Skip to content

Commit

Permalink
network scan : add network scan
Browse files Browse the repository at this point in the history
Now that we are getting all the DNS SD possible iiod hosts, return them
as part of the scan context. This enables 'iio_info -s' to return IP and
USB contexts.

Signed-off-by: Robin Getz <robin.getz@analog.com>
  • Loading branch information
rgetz committed Mar 30, 2020
1 parent 30209db commit 7be55fb
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
123 changes: 123 additions & 0 deletions dns_sd.c
Expand Up @@ -59,6 +59,93 @@ static void dnssd_remove_node(struct dns_sd_discovery_data **ddata, int n)
*ddata = d;
}

/* The only way to support scan context from the network is when
* DNS Service Discovery is turned on
*/

struct iio_scan_backend_context {
struct addrinfo *res;
};

static int dnssd_fill_context_info(struct iio_context_info *info,
char *hostname, char *addr_str, int port)
{
struct iio_context *ctx;
char uri[MAXHOSTNAMELEN + 3];
char description[255], *p;
const char *hw_model, *serial;
int i;

ctx = network_create_context(addr_str);
if (!ctx) {
ERROR("No context at %s\n", addr_str);
return -ENOMEM;
}

if (port == IIOD_PORT)
sprintf(uri, "ip:%s", hostname);
else
sprintf(uri, "ip:%s:%d", hostname, port);

hw_model = iio_context_get_attr_value(ctx, "hw_model");
serial = iio_context_get_attr_value(ctx, "hw_serial");

if (hw_model && serial) {
snprintf(description, sizeof(description), "%s (%s), serial=%s",
addr_str, hw_model, serial);
} else if (hw_model) {
snprintf(description, sizeof(description), "%s %s", addr_str, hw_model);
} else if (serial) {
snprintf(description, sizeof(description), "%s %s", addr_str, serial);
} else if (ctx->nb_devices == 0) {
snprintf(description, sizeof(description), "%s", ctx->description);
} else {
snprintf(description, sizeof(description), "%s (", addr_str);
p = description + strlen(description);
for (i = 0; i < ctx->nb_devices - 1; i++) {
if (ctx->devices[i]->name) {
snprintf(p, sizeof(description) - strlen(description) -1,
"%s,", ctx->devices[i]->name);
p += strlen(p);
}
}
p--;
*p = ')';
}

iio_context_destroy(ctx);

info->uri = iio_strdup(uri);
if (!info->uri)
return -ENOMEM;

info->description = iio_strdup(description);
if (!info->description) {
free(info->uri);
return -ENOMEM;
}

return 0;
}

struct iio_scan_backend_context * dnssd_context_scan_init(void)
{
struct iio_scan_backend_context *ctx;

ctx = malloc(sizeof(*ctx));
if (!ctx) {
errno = ENOMEM;
return NULL;
}

return ctx;
}

void dnssd_context_scan_free(struct iio_scan_backend_context *ctx)
{
free(ctx);
}

/*
* remove the ones in the list that you can't connect to
* This is sort of silly, but we have seen non-iio devices advertised
Expand Down Expand Up @@ -147,6 +234,42 @@ void remove_dup_discovery_data(struct dns_sd_discovery_data **ddata)
*ddata = d;
}

int dnssd_context_scan(struct iio_scan_backend_context *ctx,
struct iio_scan_result *scan_result)
{
struct iio_context_info **info;
struct dns_sd_discovery_data *ddata, *ndata;
int ret = 0;

ret = dnssd_find_hosts(&ddata);

/* if we return an error when no devices are found, then other scans will fail */
if (ret == -ENXIO)
return 0;

if (ret < 0)
return ret;

for (ndata = ddata; ndata->next != NULL; ndata = ndata->next) {
info = iio_scan_result_add(scan_result, 1);
if (!info) {
ERROR("Out of memory when adding new scan result\n");
ret = -ENOMEM;
break;
}

ret = dnssd_fill_context_info(*info,
ndata->hostname, ndata->addr_str,ndata->port);
if (ret < 0) {
DEBUG("Failed to add %s (%s) err: %d\n", ndata->hostname, ndata->addr_str, ret);
break;
}
}

dnssd_free_all_discovery_data(ddata);
return ret;
}

int dnssd_discover_host(char *addr_str, size_t addr_len, uint16_t *port)
{
struct dns_sd_discovery_data *ddata;
Expand Down
6 changes: 6 additions & 0 deletions iio-private.h
Expand Up @@ -275,6 +275,12 @@ void usb_context_scan_free(struct iio_scan_backend_context *ctx);
int usb_context_scan(struct iio_scan_backend_context *ctx,
struct iio_scan_result *scan_result);

struct iio_scan_backend_context * dnssd_context_scan_init(void);
void dnssd_context_scan_free(struct iio_scan_backend_context *ctx);

int dnssd_context_scan(struct iio_scan_backend_context *ctx,
struct iio_scan_result *scan_result);

/* This function is not part of the API, but is used by the IIO daemon */
__api ssize_t iio_device_get_sample_size_mask(const struct iio_device *dev,
const uint32_t *mask, size_t words);
Expand Down
22 changes: 22 additions & 0 deletions scan.c
Expand Up @@ -25,6 +25,9 @@
struct iio_scan_context {
#ifdef WITH_USB_BACKEND
struct iio_scan_backend_context *usb_ctx;
#endif
#ifdef HAVE_DNS_SD
struct iio_scan_backend_context *dnssd_ctx;
#endif
bool scan_local;
};
Expand Down Expand Up @@ -68,6 +71,17 @@ ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx,
}
#endif

#ifdef HAVE_DNS_SD
if (ctx->dnssd_ctx) {
int ret = dnssd_context_scan(ctx->dnssd_ctx, &scan_result);
if (ret < 0) {
if (scan_result.info)
iio_context_info_list_free(scan_result.info);
return ret;
}
}
#endif

*info = scan_result.info;

return (ssize_t) scan_result.size;
Expand Down Expand Up @@ -146,6 +160,10 @@ struct iio_scan_context * iio_create_scan_context(
if (!backend || !strcmp(backend, "usb"))
ctx->usb_ctx = usb_context_scan_init();
#endif
#ifdef HAVE_DNS_SD
if (!backend || !strcmp(backend, "ip"))
ctx->dnssd_ctx = dnssd_context_scan_init();
#endif

return ctx;
}
Expand All @@ -155,6 +173,10 @@ void iio_scan_context_destroy(struct iio_scan_context *ctx)
#ifdef WITH_USB_BACKEND
if (ctx->usb_ctx)
usb_context_scan_free(ctx->usb_ctx);
#endif
#ifdef HAVE_DNS_SD
if (ctx->dnssd_ctx)
dnssd_context_scan_free(ctx->dnssd_ctx);
#endif
free(ctx);
}
Expand Down

0 comments on commit 7be55fb

Please sign in to comment.