Files
video-setup/dev/cli/discovery_cli.c

110 lines
3.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "discovery.h"
#include "error.h"
static void flags_str(uint16_t flags, char *buf, size_t len) {
buf[0] = '\0';
if (flags & DISCOVERY_FLAG_SOURCE) { strncat(buf, "source ", len - strlen(buf) - 1); }
if (flags & DISCOVERY_FLAG_RELAY) { strncat(buf, "relay ", len - strlen(buf) - 1); }
if (flags & DISCOVERY_FLAG_SINK) { strncat(buf, "sink ", len - strlen(buf) - 1); }
if (flags & DISCOVERY_FLAG_CONTROLLER) { strncat(buf, "controller ", len - strlen(buf) - 1); }
/* trim trailing space */
size_t l = strlen(buf);
if (l > 0 && buf[l - 1] == ' ') { buf[l - 1] = '\0'; }
}
static void on_peer_found(const struct Discovery_Peer *peer, void *userdata) {
(void)userdata;
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &peer->addr, addr, sizeof(addr));
char flags[64];
flags_str(peer->function_flags, flags, sizeof(flags));
printf("found %-30s %s:%u site=%u [%s]\n",
peer->name, addr, peer->tcp_port, peer->site_id, flags);
}
static void on_peer_lost(const struct Discovery_Peer *peer, void *userdata) {
(void)userdata;
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &peer->addr, addr, sizeof(addr));
printf("lost %-30s %s:%u\n", peer->name, addr, peer->tcp_port);
}
static void usage(void) {
fprintf(stderr,
"usage: discovery_cli <name> <tcp_port> [flags]\n"
"\n"
" name node name in namespace:instance form, e.g. v4l2:microscope\n"
" tcp_port port this node listens on for transport connections\n"
" flags comma-separated roles: source,relay,sink,controller\n"
" default: source\n"
"\n"
"Announces this node on the multicast group and prints peers as they\n"
"appear and disappear. Press Ctrl-C to exit.\n");
}
static uint16_t parse_flags(const char *s) {
uint16_t f = 0;
if (strstr(s, "source")) { f |= DISCOVERY_FLAG_SOURCE; }
if (strstr(s, "relay")) { f |= DISCOVERY_FLAG_RELAY; }
if (strstr(s, "sink")) { f |= DISCOVERY_FLAG_SINK; }
if (strstr(s, "controller")) { f |= DISCOVERY_FLAG_CONTROLLER; }
return f;
}
int main(int argc, char **argv) {
if (argc < 3) {
usage();
return 1;
}
const char *name = argv[1];
uint16_t tcp_port = (uint16_t)atoi(argv[2]);
uint16_t flags = argc >= 4 ? parse_flags(argv[3]) : DISCOVERY_FLAG_SOURCE;
if (strlen(name) == 0 || strlen(name) > DISCOVERY_MAX_NAME_LEN) {
fprintf(stderr, "name must be 1%d characters\n", DISCOVERY_MAX_NAME_LEN);
return 1;
}
struct Discovery_Config config = {
.site_id = 0,
.tcp_port = tcp_port,
.function_flags = flags,
.name = name,
.interval_ms = 0, /* use default */
.timeout_intervals = 0, /* use default */
.on_peer_found = on_peer_found,
.on_peer_lost = on_peer_lost,
.userdata = NULL,
};
struct Discovery *d;
struct App_Error err = discovery_create(&d, &config);
if (!APP_IS_OK(err)) {
fprintf(stderr, "discovery_create: errno %d\n", err.detail.syscall.err_no);
return 1;
}
err = discovery_start(d);
if (!APP_IS_OK(err)) {
fprintf(stderr, "discovery_start: errno %d\n", err.detail.syscall.err_no);
return 1;
}
char flags_buf[64];
flags_str(flags, flags_buf, sizeof(flags_buf));
printf("announcing %-30s port=%u [%s]\n", name, tcp_port, flags_buf);
printf("listening on %s:%d\n\n", DISCOVERY_MULTICAST_GROUP, DISCOVERY_PORT);
pause();
discovery_destroy(d);
return 0;
}