blob: 12f50b07683b6db4dbb7695483057729986ef7b8 [file] [log] [blame]
Lars-Peter Clausen08633732016-02-22 14:35:17 +01001/*
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-private.h"
19
20#include <errno.h>
Paul Cercueil668fd032016-05-20 16:03:50 +020021#include <stdbool.h>
22#include <string.h>
Lars-Peter Clausen08633732016-02-22 14:35:17 +010023
24struct iio_scan_context {
Lars-Peter Clausen794ba032016-04-25 15:07:00 +020025#if USB_BACKEND
26 struct iio_scan_backend_context *usb_ctx;
Lars-Peter Clausen794ba032016-04-25 15:07:00 +020027#endif
Paul Cercueil668fd032016-05-20 16:03:50 +020028 bool scan_local;
Lars-Peter Clausen08633732016-02-22 14:35:17 +010029};
30
31const char * iio_context_info_get_description(
32 const struct iio_context_info *info)
33{
34 return info->description;
35}
36
37const char * iio_context_info_get_uri(
38 const struct iio_context_info *info)
39{
40 return info->uri;
41}
42
43ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx,
44 struct iio_context_info ***info)
45{
46 struct iio_scan_result scan_result = { 0, NULL };
47
Lars-Peter Clausen3db58d62016-04-25 15:00:54 +020048#if LOCAL_BACKEND
Paul Cercueil668fd032016-05-20 16:03:50 +020049 if (ctx->scan_local) {
Lars-Peter Clausen3db58d62016-04-25 15:00:54 +020050 int ret = local_context_scan(&scan_result);
51 if (ret < 0) {
52 if (scan_result.info)
53 iio_context_info_list_free(scan_result.info);
54 return ret;
55 }
56 }
57#endif
Lars-Peter Clausen08633732016-02-22 14:35:17 +010058
Lars-Peter Clausen794ba032016-04-25 15:07:00 +020059#if USB_BACKEND
60 if (ctx->usb_ctx) {
61 int ret = usb_context_scan(ctx->usb_ctx, &scan_result);
62 if (ret < 0) {
63 if (scan_result.info)
64 iio_context_info_list_free(scan_result.info);
65 return ret;
66 }
67 }
68#endif
69
Lars-Peter Clausen08633732016-02-22 14:35:17 +010070 *info = scan_result.info;
71
72 return (ssize_t) scan_result.size;
73}
74
75void iio_context_info_list_free(struct iio_context_info **list)
76{
77 struct iio_context_info **it;
78
Paul Cercueilb91538a2016-05-20 16:15:39 +020079 if (!list)
80 return;
81
Lars-Peter Clausen08633732016-02-22 14:35:17 +010082 for (it = list; *it; it++) {
83 struct iio_context_info *info = *it;
84
85 if (info->description)
86 free(info->description);
87 if (info->uri)
88 free(info->uri);
89 free(info);
90 }
91
Paul Cercueilb91538a2016-05-20 16:15:39 +020092 free(list);
Lars-Peter Clausen08633732016-02-22 14:35:17 +010093}
94
95struct iio_context_info ** iio_scan_result_add(
96 struct iio_scan_result *scan_result, size_t num)
97{
98 struct iio_context_info **info;
99 size_t old_size, new_size;
100 size_t i;
101
102 old_size = scan_result->size;
103 new_size = old_size + num;
104
105 info = realloc(scan_result->info, (new_size + 1) * sizeof(*info));
106 if (!info)
107 goto err_free_info_list;
108
109 for (i = old_size; i < new_size; i++) {
110 /* Make sure iio_context_info_list_free won't overflow */
111 info[i + 1] = NULL;
112
113 info[i] = zalloc(sizeof(**info));
114 if (!info[i])
115 goto err_free_info_list;
116 }
117
118 scan_result->info = info;
119 scan_result->size = new_size;
120
121 return &info[old_size];
122
123err_free_info_list:
124 scan_result->size = 0;
125 iio_context_info_list_free(scan_result->info);
126 return NULL;
127}
128
129struct iio_scan_context * iio_create_scan_context(
130 const char *backend, unsigned int flags)
131{
132 struct iio_scan_context *ctx;
133
134 /* "flags" must be zero for now */
135 if (flags != 0) {
136 errno = EINVAL;
137 return NULL;
138 }
139
Paul Cercueil668fd032016-05-20 16:03:50 +0200140 ctx = calloc(1, sizeof(*ctx));
Lars-Peter Clausen08633732016-02-22 14:35:17 +0100141 if (!ctx) {
142 errno = ENOMEM;
143 return NULL;
144 }
145
Paul Cercueil668fd032016-05-20 16:03:50 +0200146 if (!backend || !strcmp(backend, "local"))
147 ctx->scan_local = true;
148
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200149#if USB_BACKEND
Paul Cercueil668fd032016-05-20 16:03:50 +0200150 if (!backend || !strcmp(backend, "usb"))
151 ctx->usb_ctx = usb_context_scan_init();
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200152#endif
153
Lars-Peter Clausen08633732016-02-22 14:35:17 +0100154 return ctx;
155}
156
157void iio_scan_context_destroy(struct iio_scan_context *ctx)
158{
Lars-Peter Clausen794ba032016-04-25 15:07:00 +0200159#if USB_BACKEND
160 if (ctx->usb_ctx)
161 usb_context_scan_free(ctx->usb_ctx);
162#endif
Lars-Peter Clausen08633732016-02-22 14:35:17 +0100163 free(ctx);
164}