blob: 9809c94c90e69143c3f24b0357add92dbcc9bf48 [file] [log] [blame]
Paul Cercueilc7bad0f2014-03-03 17:06:48 +01001/*
2 * libiio - Library for interfacing industrial I/O (IIO) devices
3 *
4 * Copyright (C) 2014 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
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010019#include "iio-private.h"
20
21#include <errno.h>
Paul Cercueile60c3ed2014-03-04 11:23:56 +010022#include <stdbool.h>
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010023#include <string.h>
24#include <sys/types.h>
Paul Cercueil1fef1a52014-04-07 16:31:15 +020025
26#ifdef _WIN32
27#include <winsock2.h>
28#include <ws2tcpip.h>
29#define close(s) closesocket(s)
30
31/* winsock2.h defines ERROR, we don't want that */
32#undef ERROR
33
34#else /* _WIN32 */
35#include <netdb.h>
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010036#include <sys/socket.h>
37#include <unistd.h>
Paul Cercueil1fef1a52014-04-07 16:31:15 +020038#endif /* _WIN32 */
39
40#include "debug.h"
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010041
Paul Cercueil2e38bbe2014-03-19 15:27:15 +010042#define _STRINGIFY(x) #x
43#define STRINGIFY(x) _STRINGIFY(x)
44
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010045#define IIOD_PORT 30431
Paul Cercueil2e38bbe2014-03-19 15:27:15 +010046#define IIOD_PORT_STR STRINGIFY(IIOD_PORT)
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010047
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +010048struct iio_context_pdata {
49 int fd;
50};
51
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010052static ssize_t write_all(const void *src, size_t len, int fd)
53{
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020054 uintptr_t ptr = (uintptr_t) src;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010055 while (len) {
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020056 ssize_t ret = send(fd, (const void *) ptr, len, 0);
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010057 if (ret < 0)
58 return -errno;
59 ptr += ret;
60 len -= ret;
61 }
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020062 return ptr - (uintptr_t) src;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010063}
64
65static ssize_t read_all(void *dst, size_t len, int fd)
66{
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020067 uintptr_t ptr = (uintptr_t) dst;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010068 while (len) {
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020069 ssize_t ret = recv(fd, (void *) ptr, len, 0);
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010070 if (ret < 0)
71 return -errno;
72 ptr += ret;
73 len -= ret;
74 }
Paul Cercueil6e7f79e2014-04-04 12:27:24 +020075 return ptr - (uintptr_t) dst;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +010076}
77
Paul Cercueile60c3ed2014-03-04 11:23:56 +010078static int read_integer(int fd, long *val)
79{
80 unsigned int i;
81 char buf[1024], *ptr;
82 ssize_t ret;
83 bool found = false;
84
85 for (i = 0; i < sizeof(buf) - 1; i++) {
86 ret = read_all(buf + i, 1, fd);
87 if (ret < 0)
88 return (int) ret;
89
90 /* Skip the eventual first few carriage returns */
91 if (buf[i] != '\n')
92 found = true;
93 else if (found)
94 break;
95 }
96
97 buf[i] = '\0';
98 ret = (ssize_t) strtol(buf, &ptr, 10);
99 if (ptr == buf)
100 return -EINVAL;
101 *val = (long) ret;
102 return 0;
103}
104
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100105static ssize_t write_command(const char *cmd, int fd)
106{
107 ssize_t ret;
108
109 DEBUG("Writing command: %s\n", cmd);
110 ret = write_all(cmd, strlen(cmd), fd);
111 if (ret < 0) {
112 char buf[1024];
113 strerror_r(-ret, buf, sizeof(buf));
114 ERROR("Unable to send command: %s\n", buf);
115 }
116 return ret;
117}
118
119static long exec_command(const char *cmd, int fd)
120{
121 long resp;
122 ssize_t ret = write_command(cmd, fd);
123 if (ret < 0)
124 return (long) ret;
125
126 DEBUG("Reading response\n");
127 ret = read_integer(fd, &resp);
128 if (ret < 0) {
129 char buf[1024];
130 strerror_r(-ret, buf, sizeof(buf));
131 ERROR("Unable to read response: %s\n", buf);
132 return (long) ret;
133 }
134
Paul Cercueilc7fe2ea2014-03-28 11:38:45 +0100135#if LOG_LEVEL >= DEBUG_L
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100136 if (resp < 0) {
137 char buf[1024];
138 strerror_r(-resp, buf, sizeof(buf));
Paul Cercueilc7fe2ea2014-03-28 11:38:45 +0100139 DEBUG("Server returned an error: %s\n", buf);
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100140 }
Paul Cercueilc7fe2ea2014-03-28 11:38:45 +0100141#endif
142
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100143 return resp;
144}
145
Paul Cercueil3c407f82014-04-02 14:11:59 +0200146static int network_open(const struct iio_device *dev,
147 size_t samples_count, uint32_t *mask, size_t nb)
Paul Cercueilba059762014-03-14 11:02:02 +0100148{
149 char buf[1024], *ptr;
150 unsigned int i;
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100151 int ret;
Paul Cercueilba059762014-03-14 11:02:02 +0100152
Paul Cercueilff778232014-03-24 14:23:08 +0100153 if (nb != dev->words)
Paul Cercueilba059762014-03-14 11:02:02 +0100154 return -EINVAL;
155
Paul Cercueil3c407f82014-04-02 14:11:59 +0200156 snprintf(buf, sizeof(buf), "OPEN %s %lu ",
157 dev->id, (unsigned long) samples_count);
Paul Cercueilba059762014-03-14 11:02:02 +0100158 ptr = buf + strlen(buf);
159
160 for (i = nb; i > 0; i--) {
Paul Cercueil8c29e412014-04-07 09:46:45 +0200161 snprintf(ptr, (ptr - buf) + i * 8, "%08x", mask[i - 1]);
Paul Cercueilba059762014-03-14 11:02:02 +0100162 ptr += 8;
163 }
164 strcpy(ptr, "\r\n");
165
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100166 ret = (int) exec_command(buf, dev->ctx->pdata->fd);
167 if (ret < 0) {
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100168 return ret;
169 } else {
Paul Cercueilff778232014-03-24 14:23:08 +0100170 memcpy(dev->mask, mask, nb * sizeof(*mask));
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100171 return 0;
172 }
Paul Cercueilba059762014-03-14 11:02:02 +0100173}
174
175static int network_close(const struct iio_device *dev)
176{
177 char buf[1024];
178 snprintf(buf, sizeof(buf), "CLOSE %s\r\n", dev->id);
Paul Cercueilff778232014-03-24 14:23:08 +0100179 return (int) exec_command(buf, dev->ctx->pdata->fd);
Paul Cercueilba059762014-03-14 11:02:02 +0100180}
181
Paul Cercueil45c575d2014-03-20 15:14:01 +0100182static ssize_t network_read(const struct iio_device *dev, void *dst, size_t len,
183 uint32_t *mask, size_t words)
Paul Cercueilf9286452014-03-18 14:32:17 +0100184{
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200185 uintptr_t ptr = (uintptr_t) dst;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100186 int fd = dev->ctx->pdata->fd;
Paul Cercueil45c575d2014-03-20 15:14:01 +0100187 ssize_t ret, read = 0;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100188 char buf[1024];
Paul Cercueil45c575d2014-03-20 15:14:01 +0100189 bool read_mask = true;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100190
Paul Cercueil45c575d2014-03-20 15:14:01 +0100191 if (!len || words != (dev->nb_channels + 31) / 32)
Paul Cercueil9945bc82014-03-05 14:07:29 +0100192 return -EINVAL;
193
Paul Cercueila78b6eb2014-03-17 17:28:07 +0100194 snprintf(buf, sizeof(buf), "READBUF %s %lu\r\n",
195 dev->id, (unsigned long) len);
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100196 ret = write_command(buf, fd);
Paul Cercueil45c575d2014-03-20 15:14:01 +0100197 if (ret < 0)
Paul Cercueil9945bc82014-03-05 14:07:29 +0100198 return ret;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100199
200 do {
Paul Cercueil5cab3ae2014-03-14 11:23:56 +0100201 unsigned int i;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100202 long read_len;
203
204 DEBUG("Reading READ response\n");
205 ret = read_integer(fd, &read_len);
206 if (ret < 0) {
207 strerror_r(-ret, buf, sizeof(buf));
208 ERROR("Unable to read response to READ: %s\n", buf);
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200209 return read ? read : ret;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100210 }
211
212 if (read_len < 0) {
213 strerror_r(-read_len, buf, sizeof(buf));
214 ERROR("Server returned an error: %s\n", buf);
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200215 return read ? read : read_len;
Paul Cercueila78b6eb2014-03-17 17:28:07 +0100216 } else if (read_len == 0) {
217 break;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100218 }
219
220 DEBUG("Bytes to read: %li\n", read_len);
221
Paul Cercueil43c1e6c2014-03-20 14:26:20 +0100222 if (read_mask) {
223 DEBUG("Reading mask\n");
224 buf[8] = '\0';
Paul Cercueil45c575d2014-03-20 15:14:01 +0100225 for (i = words; i > 0; i--) {
Paul Cercueil43c1e6c2014-03-20 14:26:20 +0100226 ret = read_all(buf, 8, fd);
227 if (ret < 0)
228 break;
229 sscanf(buf, "%08x", &mask[i - 1]);
230 DEBUG("mask[%i] = 0x%x\n", i - 1, mask[i - 1]);
Paul Cercueil43c1e6c2014-03-20 14:26:20 +0100231 }
232 read_mask = false;
Paul Cercueil5cab3ae2014-03-14 11:23:56 +0100233 }
234
235 if (ret > 0) {
236 char c;
237 ret = recv(fd, &c, 1, 0);
238 if (ret > 0 && c != '\n')
239 ret = -EIO;
240 }
241
242 if (ret < 0) {
243 strerror_r(-ret, buf, sizeof(buf));
244 ERROR("Unable to read mask: %s\n", buf);
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200245 return read ? read : ret;
Paul Cercueil5cab3ae2014-03-14 11:23:56 +0100246 }
247
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200248 ret = read_all((void *) ptr, read_len, fd);
Paul Cercueil9945bc82014-03-05 14:07:29 +0100249 if (ret < 0) {
250 strerror_r(-ret, buf, sizeof(buf));
251 ERROR("Unable to read response to READ: %s\n", buf);
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200252 return read ? read : ret;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100253 }
254
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200255 ptr += ret;
Paul Cercueilf9286452014-03-18 14:32:17 +0100256 read += ret;
Paul Cercueil9945bc82014-03-05 14:07:29 +0100257 len -= read_len;
258 } while (len);
259
260 return read;
261}
262
Paul Cercueil99cf3d42014-03-06 12:35:26 +0100263static ssize_t network_read_attr_helper(int fd, const char *id,
264 const char *chn, const char *attr, char *dst, size_t len)
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100265{
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100266 long read_len;
267 ssize_t ret;
268 char buf[1024];
269
Paul Cercueil99cf3d42014-03-06 12:35:26 +0100270 if (chn)
271 snprintf(buf, sizeof(buf), "READ %s %s %s\r\n", id, chn, attr);
272 else
273 snprintf(buf, sizeof(buf), "READ %s %s\r\n", id, attr);
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100274 read_len = exec_command(buf, fd);
275 if (read_len < 0)
276 return (ssize_t) read_len;
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100277
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200278 if ((unsigned long) read_len > len) {
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100279 ERROR("Value returned by server is too large\n");
280 return -EIO;
281 }
282
283 ret = read_all(dst, read_len, fd);
284 if (ret < 0) {
285 strerror_r(-ret, buf, sizeof(buf));
286 ERROR("Unable to read response to READ: %s\n", buf);
287 return ret;
288 }
289
290 dst[read_len] = '\0';
291 return read_len + 1;
292}
293
Paul Cercueil07897d32014-03-06 12:46:08 +0100294static ssize_t network_write_attr_helper(int fd, const char *id,
295 const char *chn, const char *attr, const char *src)
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100296{
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100297 char buf[1024];
298
Paul Cercueil07897d32014-03-06 12:46:08 +0100299 if (chn)
300 snprintf(buf, sizeof(buf), "WRITE %s %s %s %s\r\n",
301 id, chn, attr, src);
302 else
303 snprintf(buf, sizeof(buf), "WRITE %s %s %s\r\n", id, attr, src);
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100304 return (ssize_t) exec_command(buf, fd);
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100305}
306
Paul Cercueil99cf3d42014-03-06 12:35:26 +0100307static ssize_t network_read_dev_attr(const struct iio_device *dev,
308 const char *attr, char *dst, size_t len)
309{
310 return network_read_attr_helper(dev->ctx->pdata->fd, dev->id,
311 NULL, attr, dst, len);
312}
313
Paul Cercueil07897d32014-03-06 12:46:08 +0100314static ssize_t network_write_dev_attr(const struct iio_device *dev,
315 const char *attr, const char *src)
316{
317 return network_write_attr_helper(dev->ctx->pdata->fd, dev->id,
318 NULL, attr, src);
319}
320
Paul Cercueil99cf3d42014-03-06 12:35:26 +0100321static ssize_t network_read_chn_attr(const struct iio_channel *chn,
322 const char *attr, char *dst, size_t len)
323{
324 return network_read_attr_helper(chn->dev->ctx->pdata->fd, chn->dev->id,
325 chn->id, attr, dst, len);
326}
327
Paul Cercueil07897d32014-03-06 12:46:08 +0100328static ssize_t network_write_chn_attr(const struct iio_channel *chn,
329 const char *attr, const char *src)
330{
331 return network_write_attr_helper(chn->dev->ctx->pdata->fd, chn->dev->id,
332 chn->id, attr, src);
333}
334
Paul Cercueildcab40c2014-03-11 10:59:14 +0100335static int network_get_trigger(const struct iio_device *dev,
336 const struct iio_device **trigger)
337{
338 struct iio_context_pdata *pdata = dev->ctx->pdata;
339 unsigned int i;
340 char buf[1024];
341 ssize_t ret;
342 long resp;
343
344 snprintf(buf, sizeof(buf), "GETTRIG %s\r\n", dev->id);
345 resp = exec_command(buf, pdata->fd);
346 if (resp < 0) {
347 return (int) resp;
348 } else if (resp == 0) {
349 *trigger = NULL;
350 return 0;
Paul Cercueil6e7f79e2014-04-04 12:27:24 +0200351 } else if ((unsigned long) resp > sizeof(buf)) {
Paul Cercueildcab40c2014-03-11 10:59:14 +0100352 ERROR("Value returned by server is too large\n");
353 return -EIO;
354 }
355
356 ret = read_all(buf, resp, pdata->fd);
357 if (ret < 0) {
358 strerror_r(-ret, buf, sizeof(buf));
359 ERROR("Unable to read response to GETTRIG: %s\n", buf);
360 return ret;
361 }
362
363 for (i = 0; i < dev->ctx->nb_devices; i++) {
364 struct iio_device *cur = dev->ctx->devices[i];
365 if (iio_device_is_trigger(cur) &&
366 !strncmp(cur->name, buf, resp)) {
367 *trigger = cur;
368 return 0;
369 }
370 }
371
372 return -ENXIO;
373}
374
375static int network_set_trigger(const struct iio_device *dev,
376 const struct iio_device *trigger)
377{
378 char buf[1024];
379 if (trigger)
380 snprintf(buf, sizeof(buf), "SETTRIG %s %s\r\n",
381 dev->id, trigger->id);
382 else
383 snprintf(buf, sizeof(buf), "SETTRIG %s\r\n", dev->id);
384 return (int) exec_command(buf, dev->ctx->pdata->fd);
385}
386
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100387static void network_shutdown(struct iio_context *ctx)
388{
389 struct iio_context_pdata *pdata = ctx->pdata;
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100390 unsigned int i;
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100391
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100392 write_command("\r\nEXIT\r\n", pdata->fd);
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100393 close(pdata->fd);
394 free(pdata);
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100395
396 for (i = 0; i < ctx->nb_devices; i++) {
397 struct iio_device *dev = ctx->devices[i];
398 if (dev->pdata)
399 free(dev->pdata);
400 }
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100401}
402
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100403static struct iio_backend_ops network_ops = {
Paul Cercueilba059762014-03-14 11:02:02 +0100404 .open = network_open,
405 .close = network_close,
Paul Cercueil9945bc82014-03-05 14:07:29 +0100406 .read = network_read,
Paul Cercueil3e94a5b2014-03-04 13:00:41 +0100407 .read_device_attr = network_read_dev_attr,
408 .write_device_attr = network_write_dev_attr,
Paul Cercueil99cf3d42014-03-06 12:35:26 +0100409 .read_channel_attr = network_read_chn_attr,
Paul Cercueil07897d32014-03-06 12:46:08 +0100410 .write_channel_attr = network_write_chn_attr,
Paul Cercueildcab40c2014-03-11 10:59:14 +0100411 .get_trigger = network_get_trigger,
412 .set_trigger = network_set_trigger,
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100413 .shutdown = network_shutdown,
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100414};
415
416static struct iio_context * get_context(int fd)
417{
418 struct iio_context *ctx;
Paul Cercueile60c3ed2014-03-04 11:23:56 +0100419 char *xml;
Paul Cercueilbb76bf92014-03-11 10:20:18 +0100420 long xml_len = exec_command("PRINT\r\n", fd);
421 if (xml_len < 0)
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100422 return NULL;
Paul Cercueile60c3ed2014-03-04 11:23:56 +0100423
424 DEBUG("Server returned a XML string of length %li\n", xml_len);
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100425 xml = malloc(xml_len);
426 if (!xml) {
427 ERROR("Unable to allocate data\n");
428 return NULL;
429 }
430
431 DEBUG("Reading XML string...\n");
432 read_all(xml, xml_len, fd);
433
434 DEBUG("Creating context from XML...\n");
435 ctx = iio_create_xml_context_mem(xml, xml_len);
436 free(xml);
437 return ctx;
438}
439
440struct iio_context * iio_create_network_context(const char *host)
441{
Paul Cercueil2e38bbe2014-03-19 15:27:15 +0100442 struct addrinfo hints, *res;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100443 struct iio_context *ctx;
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100444 struct iio_context_pdata *pdata;
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100445 unsigned int i;
Paul Cercueil2e38bbe2014-03-19 15:27:15 +0100446 int fd, ret;
Paul Cercueil1fef1a52014-04-07 16:31:15 +0200447#ifdef _WIN32
448 WSADATA wsaData;
449
450 ret = WSAStartup(MAKEWORD(2, 0), &wsaData);
451 if (ret < 0) {
452 ERROR("WSAStartup failed with error %i\n", ret);
453 return NULL;
454 }
455#endif
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100456
Paul Cercueil2e38bbe2014-03-19 15:27:15 +0100457 memset(&hints, 0, sizeof(hints));
458 hints.ai_family = AF_UNSPEC;
459 hints.ai_socktype = SOCK_STREAM;
460 ret = getaddrinfo(host, IIOD_PORT_STR, &hints, &res);
461 if (ret) {
462 ERROR("Unable to find IP address for host %s: %s\n",
463 host, gai_strerror(ret));
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100464 return NULL;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100465 }
466
Paul Cercueil2e38bbe2014-03-19 15:27:15 +0100467 fd = socket(res->ai_family, res->ai_socktype, 0);
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100468 if (fd < 0) {
469 ERROR("Unable to open socket\n");
470 return NULL;
471 }
472
Paul Cercueil2e38bbe2014-03-19 15:27:15 +0100473 if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100474 ERROR("Unable to connect\n");
475 goto err_close_socket;
476 }
477
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100478 pdata = calloc(1, sizeof(*pdata));
479 if (!pdata) {
480 ERROR("Unable to allocate memory\n");
481 goto err_close_socket;
482 }
483
484 pdata->fd = fd;
485
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100486 DEBUG("Creating context...\n");
487 ctx = get_context(fd);
488 if (!ctx)
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100489 goto err_free_pdata;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100490
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100491 for (i = 0; i < ctx->nb_devices; i++) {
492 struct iio_device *dev = ctx->devices[i];
Paul Cercueilff778232014-03-24 14:23:08 +0100493 uint32_t *mask = NULL;
494
495 dev->words = (dev->nb_channels + 31) / 32;
496 if (dev->words) {
497 mask = calloc(dev->words, sizeof(*mask));
498 if (!mask)
499 goto err_network_shutdown;
500 }
501
502 dev->mask = mask;
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100503 }
504
Paul Cercueilff778232014-03-24 14:23:08 +0100505
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100506 /* Override the name and low-level functions of the XML context
507 * with those corresponding to the network context */
508 ctx->name = "network";
509 ctx->ops = &network_ops;
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100510 ctx->pdata = pdata;
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100511
Paul Cercueil4c6729d2014-04-04 17:24:41 +0200512 ret = iio_context_init(ctx);
513 if (ret < 0) {
514 char buf[1024];
515 strerror_r(-ret, buf, sizeof(buf));
516 ERROR("Unable to initialize context: %s\n", buf);
Paul Cercueildfcd6b12014-04-08 14:45:36 +0200517 goto err_network_shutdown;
Paul Cercueil4c6729d2014-04-04 17:24:41 +0200518 }
519
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100520 return ctx;
521
Paul Cercueil44ae11c2014-03-17 09:56:29 +0100522err_network_shutdown:
523 network_shutdown(ctx);
524 iio_context_destroy(ctx);
Paul Cercueil8fd9c8f2014-03-03 17:21:31 +0100525err_free_pdata:
526 free(pdata);
Paul Cercueilc7bad0f2014-03-03 17:06:48 +0100527err_close_socket:
528 close(fd);
529 return NULL;
530}