blob: dc1be04f6644d3e530c76549c7caafe8ca165393 [file] [log] [blame]
Enrico Granata19d88802019-04-29 16:28:35 -07001/*
2 * libiio - Library for interfacing industrial I/O (IIO) devices
3 *
4 * Copyright (C) 2016 Analog Devices, Inc.
5 * Author: Paul Cercueil <paul.cercueil@analog.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 */
17
18#include "iio-config.h"
19#include "iio-private.h"
20
21#include <errno.h>
22#include <stdbool.h>
23#include <string.h>
24
25struct iio_scan_context {
26#ifdef WITH_USB_BACKEND
27 struct iio_scan_backend_context *usb_ctx;
28#endif
29 bool scan_local;
30};
31
32const char * iio_context_info_get_description(
33 const struct iio_context_info *info)
34{
35 return info->description;
36}
37
38const char * iio_context_info_get_uri(
39 const struct iio_context_info *info)
40{
41 return info->uri;
42}
43
44ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx,
45 struct iio_context_info ***info)
46{
47 struct iio_scan_result scan_result = { 0, NULL };
48
49#ifdef WITH_LOCAL_BACKEND
50 if (ctx->scan_local) {
51 int ret = local_context_scan(&scan_result);
52 if (ret < 0) {
53 if (scan_result.info)
54 iio_context_info_list_free(scan_result.info);
55 return ret;
56 }
57 }
58#endif
59
60#ifdef WITH_USB_BACKEND
61 if (ctx->usb_ctx) {
62 int ret = usb_context_scan(ctx->usb_ctx, &scan_result);
63 if (ret < 0) {
64 if (scan_result.info)
65 iio_context_info_list_free(scan_result.info);
66 return ret;
67 }
68 }
69#endif
70
71 *info = scan_result.info;
72
73 return (ssize_t) scan_result.size;
74}
75
76void iio_context_info_list_free(struct iio_context_info **list)
77{
78 struct iio_context_info **it;
79
80 if (!list)
81 return;
82
83 for (it = list; *it; it++) {
84 struct iio_context_info *info = *it;
85
86 if (info->description)
87 free(info->description);
88 if (info->uri)
89 free(info->uri);
90 free(info);
91 }
92
93 free(list);
94}
95
96struct iio_context_info ** iio_scan_result_add(
97 struct iio_scan_result *scan_result, size_t num)
98{
99 struct iio_context_info **info;
100 size_t old_size, new_size;
101 size_t i;
102
103 old_size = scan_result->size;
104 new_size = old_size + num;
105
106 info = realloc(scan_result->info, (new_size + 1) * sizeof(*info));
107 if (!info)
108 return NULL;
109
110 scan_result->info = info;
111 scan_result->size = new_size;
112
113 for (i = old_size; i < new_size; i++) {
114 /* Make sure iio_context_info_list_free won't overflow */
115 info[i + 1] = NULL;
116
117 info[i] = zalloc(sizeof(**info));
118 if (!info[i])
119 return NULL;
120 }
121
122 return &info[old_size];
123}
124
125struct iio_scan_context * iio_create_scan_context(
126 const char *backend, unsigned int flags)
127{
128 struct iio_scan_context *ctx;
129
130 /* "flags" must be zero for now */
131 if (flags != 0) {
132 errno = EINVAL;
133 return NULL;
134 }
135
136 ctx = calloc(1, sizeof(*ctx));
137 if (!ctx) {
138 errno = ENOMEM;
139 return NULL;
140 }
141
142 if (!backend || !strcmp(backend, "local"))
143 ctx->scan_local = true;
144
145#ifdef WITH_USB_BACKEND
146 if (!backend || !strcmp(backend, "usb"))
147 ctx->usb_ctx = usb_context_scan_init();
148#endif
149
150 return ctx;
151}
152
153void iio_scan_context_destroy(struct iio_scan_context *ctx)
154{
155#ifdef WITH_USB_BACKEND
156 if (ctx->usb_ctx)
157 usb_context_scan_free(ctx->usb_ctx);
158#endif
159 free(ctx);
160}
161
162#ifdef WITH_MATLAB_BINDINGS_API
163
164struct iio_scan_block {
165 struct iio_scan_context *ctx;
166 struct iio_context_info **info;
167 ssize_t ctx_cnt;
168};
169
170ssize_t iio_scan_block_scan(struct iio_scan_block *blk)
171{
172 iio_context_info_list_free(blk->info);
173 blk->info = NULL;
174 blk->ctx_cnt = iio_scan_context_get_info_list(blk->ctx, &blk->info);
175 return blk->ctx_cnt;
176}
177
178struct iio_context_info *iio_scan_block_get_info(
179 struct iio_scan_block *blk, unsigned int index)
180{
181 if (!blk->info || (ssize_t)index >= blk->ctx_cnt) {
182 errno = EINVAL;
183 return NULL;
184 }
185 return blk->info[index];
186}
187
188struct iio_scan_block *iio_create_scan_block(
189 const char *backend, unsigned int flags)
190{
191 struct iio_scan_block *blk;
192
193 blk = calloc(1, sizeof(*blk));
194 if (!blk) {
195 errno = ENOMEM;
196 return NULL;
197 }
198
199 blk->ctx = iio_create_scan_context(backend, flags);
200 if (!blk->ctx) {
201 free(blk);
202 return NULL;
203 }
204
205 return blk;
206}
207
208void iio_scan_block_destroy(struct iio_scan_block *blk)
209{
210 iio_context_info_list_free(blk->info);
211 iio_scan_context_destroy(blk->ctx);
212 free(blk);
213}
214#endif