215 lines
4.4 KiB
C
215 lines
4.4 KiB
C
/*
|
|
* libiio - Library for interfacing industrial I/O (IIO) devices
|
|
*
|
|
* Copyright (C) 2016 Analog Devices, Inc.
|
|
* Author: Paul Cercueil <paul.cercueil@analog.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*/
|
|
|
|
#include "iio-config.h"
|
|
#include "iio-private.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
struct iio_scan_context {
|
|
#ifdef WITH_USB_BACKEND
|
|
struct iio_scan_backend_context *usb_ctx;
|
|
#endif
|
|
bool scan_local;
|
|
};
|
|
|
|
const char * iio_context_info_get_description(
|
|
const struct iio_context_info *info)
|
|
{
|
|
return info->description;
|
|
}
|
|
|
|
const char * iio_context_info_get_uri(
|
|
const struct iio_context_info *info)
|
|
{
|
|
return info->uri;
|
|
}
|
|
|
|
ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx,
|
|
struct iio_context_info ***info)
|
|
{
|
|
struct iio_scan_result scan_result = { 0, NULL };
|
|
|
|
#ifdef WITH_LOCAL_BACKEND
|
|
if (ctx->scan_local) {
|
|
int ret = local_context_scan(&scan_result);
|
|
if (ret < 0) {
|
|
if (scan_result.info)
|
|
iio_context_info_list_free(scan_result.info);
|
|
return ret;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef WITH_USB_BACKEND
|
|
if (ctx->usb_ctx) {
|
|
int ret = usb_context_scan(ctx->usb_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;
|
|
}
|
|
|
|
void iio_context_info_list_free(struct iio_context_info **list)
|
|
{
|
|
struct iio_context_info **it;
|
|
|
|
if (!list)
|
|
return;
|
|
|
|
for (it = list; *it; it++) {
|
|
struct iio_context_info *info = *it;
|
|
|
|
if (info->description)
|
|
free(info->description);
|
|
if (info->uri)
|
|
free(info->uri);
|
|
free(info);
|
|
}
|
|
|
|
free(list);
|
|
}
|
|
|
|
struct iio_context_info ** iio_scan_result_add(
|
|
struct iio_scan_result *scan_result, size_t num)
|
|
{
|
|
struct iio_context_info **info;
|
|
size_t old_size, new_size;
|
|
size_t i;
|
|
|
|
old_size = scan_result->size;
|
|
new_size = old_size + num;
|
|
|
|
info = realloc(scan_result->info, (new_size + 1) * sizeof(*info));
|
|
if (!info)
|
|
return NULL;
|
|
|
|
scan_result->info = info;
|
|
scan_result->size = new_size;
|
|
|
|
for (i = old_size; i < new_size; i++) {
|
|
/* Make sure iio_context_info_list_free won't overflow */
|
|
info[i + 1] = NULL;
|
|
|
|
info[i] = zalloc(sizeof(**info));
|
|
if (!info[i])
|
|
return NULL;
|
|
}
|
|
|
|
return &info[old_size];
|
|
}
|
|
|
|
struct iio_scan_context * iio_create_scan_context(
|
|
const char *backend, unsigned int flags)
|
|
{
|
|
struct iio_scan_context *ctx;
|
|
|
|
/* "flags" must be zero for now */
|
|
if (flags != 0) {
|
|
errno = EINVAL;
|
|
return NULL;
|
|
}
|
|
|
|
ctx = calloc(1, sizeof(*ctx));
|
|
if (!ctx) {
|
|
errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
|
|
if (!backend || !strcmp(backend, "local"))
|
|
ctx->scan_local = true;
|
|
|
|
#ifdef WITH_USB_BACKEND
|
|
if (!backend || !strcmp(backend, "usb"))
|
|
ctx->usb_ctx = usb_context_scan_init();
|
|
#endif
|
|
|
|
return ctx;
|
|
}
|
|
|
|
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
|
|
free(ctx);
|
|
}
|
|
|
|
#ifdef WITH_MATLAB_BINDINGS_API
|
|
|
|
struct iio_scan_block {
|
|
struct iio_scan_context *ctx;
|
|
struct iio_context_info **info;
|
|
ssize_t ctx_cnt;
|
|
};
|
|
|
|
ssize_t iio_scan_block_scan(struct iio_scan_block *blk)
|
|
{
|
|
iio_context_info_list_free(blk->info);
|
|
blk->info = NULL;
|
|
blk->ctx_cnt = iio_scan_context_get_info_list(blk->ctx, &blk->info);
|
|
return blk->ctx_cnt;
|
|
}
|
|
|
|
struct iio_context_info *iio_scan_block_get_info(
|
|
struct iio_scan_block *blk, unsigned int index)
|
|
{
|
|
if (!blk->info || (ssize_t)index >= blk->ctx_cnt) {
|
|
errno = EINVAL;
|
|
return NULL;
|
|
}
|
|
return blk->info[index];
|
|
}
|
|
|
|
struct iio_scan_block *iio_create_scan_block(
|
|
const char *backend, unsigned int flags)
|
|
{
|
|
struct iio_scan_block *blk;
|
|
|
|
blk = calloc(1, sizeof(*blk));
|
|
if (!blk) {
|
|
errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
|
|
blk->ctx = iio_create_scan_context(backend, flags);
|
|
if (!blk->ctx) {
|
|
free(blk);
|
|
return NULL;
|
|
}
|
|
|
|
return blk;
|
|
}
|
|
|
|
void iio_scan_block_destroy(struct iio_scan_block *blk)
|
|
{
|
|
iio_context_info_list_free(blk->info);
|
|
iio_scan_context_destroy(blk->ctx);
|
|
free(blk);
|
|
}
|
|
#endif
|