Tiny IIO Daemon Library

Dependents:  

Committer:
mahphalke
Date:
Wed Oct 07 15:36:37 2020 +0530
Revision:
2:2119a523fbbc
Parent:
1:6cb62c8c58d6
Added dual license support (LGPL and ADI-BSD)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mahphalke 1:6cb62c8c58d6 1 /***************************************************************************//**
mahphalke 1:6cb62c8c58d6 2 * @file tinyiiod.c
mahphalke 1:6cb62c8c58d6 3 * @brief libtinyiiod - Tiny IIO Daemon Library
mahphalke 1:6cb62c8c58d6 4 * @author Paul Cercueil <paul.cercueil@analog.com>
mahphalke 1:6cb62c8c58d6 5 ********************************************************************************
mahphalke 1:6cb62c8c58d6 6 * Copyright (c) 2016, 2020 Analog Devices, Inc.
mahphalke 1:6cb62c8c58d6 7 *
mahphalke 1:6cb62c8c58d6 8 * All rights reserved.
mahphalke 1:6cb62c8c58d6 9 *
mahphalke 1:6cb62c8c58d6 10 * This software is proprietary to Analog Devices, Inc. and its licensors.
mahphalke 1:6cb62c8c58d6 11 * By using this software you agree to the terms of the associated
mahphalke 1:6cb62c8c58d6 12 * Analog Devices Software License Agreement.
mahphalke 1:6cb62c8c58d6 13 *******************************************************************************/
mahphalke 1:6cb62c8c58d6 14
mahphalke 1:6cb62c8c58d6 15 #include "tinyiiod-private.h"
mahphalke 1:6cb62c8c58d6 16
mahphalke 1:6cb62c8c58d6 17 #include "compat.h"
mahphalke 1:6cb62c8c58d6 18
mahphalke 1:6cb62c8c58d6 19 struct tinyiiod {
mahphalke 1:6cb62c8c58d6 20 struct tinyiiod_ops *ops;
mahphalke 1:6cb62c8c58d6 21 char *buf;
mahphalke 1:6cb62c8c58d6 22 };
mahphalke 1:6cb62c8c58d6 23
mahphalke 1:6cb62c8c58d6 24 struct tinyiiod * tinyiiod_create(struct tinyiiod_ops *ops)
mahphalke 1:6cb62c8c58d6 25 {
mahphalke 1:6cb62c8c58d6 26 struct tinyiiod *iiod = malloc(sizeof(*iiod));
mahphalke 1:6cb62c8c58d6 27
mahphalke 1:6cb62c8c58d6 28 if (!iiod)
mahphalke 1:6cb62c8c58d6 29 return NULL;
mahphalke 1:6cb62c8c58d6 30
mahphalke 1:6cb62c8c58d6 31 iiod->buf = malloc(IIOD_BUFFER_SIZE);
mahphalke 1:6cb62c8c58d6 32 iiod->ops = ops;
mahphalke 1:6cb62c8c58d6 33
mahphalke 1:6cb62c8c58d6 34 return iiod;
mahphalke 1:6cb62c8c58d6 35 }
mahphalke 1:6cb62c8c58d6 36
mahphalke 1:6cb62c8c58d6 37 void tinyiiod_destroy(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 38 {
mahphalke 1:6cb62c8c58d6 39 free(iiod->ops);
mahphalke 1:6cb62c8c58d6 40 free(iiod->buf);
mahphalke 1:6cb62c8c58d6 41 free(iiod);
mahphalke 1:6cb62c8c58d6 42 }
mahphalke 1:6cb62c8c58d6 43
mahphalke 1:6cb62c8c58d6 44 int32_t tinyiiod_read_command(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 45 {
mahphalke 1:6cb62c8c58d6 46 char buf[128];
mahphalke 1:6cb62c8c58d6 47 int32_t ret;
mahphalke 1:6cb62c8c58d6 48
mahphalke 1:6cb62c8c58d6 49 ret = tinyiiod_read_line(iiod, buf, sizeof(buf));
mahphalke 1:6cb62c8c58d6 50 if (ret < 0)
mahphalke 1:6cb62c8c58d6 51 return ret;
mahphalke 1:6cb62c8c58d6 52
mahphalke 1:6cb62c8c58d6 53 ret = tinyiiod_parse_string(iiod, buf);
mahphalke 1:6cb62c8c58d6 54 if (ret < 0)
mahphalke 1:6cb62c8c58d6 55 tinyiiod_write_value(iiod, ret);
mahphalke 1:6cb62c8c58d6 56
mahphalke 1:6cb62c8c58d6 57 return ret;
mahphalke 1:6cb62c8c58d6 58 }
mahphalke 1:6cb62c8c58d6 59
mahphalke 1:6cb62c8c58d6 60 char tinyiiod_read_char(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 61 {
mahphalke 1:6cb62c8c58d6 62 char c;
mahphalke 1:6cb62c8c58d6 63
mahphalke 1:6cb62c8c58d6 64 iiod->ops->read(&c, 1);
mahphalke 1:6cb62c8c58d6 65 return c;
mahphalke 1:6cb62c8c58d6 66 }
mahphalke 1:6cb62c8c58d6 67
mahphalke 1:6cb62c8c58d6 68 ssize_t tinyiiod_read(struct tinyiiod *iiod, char *buf, size_t len)
mahphalke 1:6cb62c8c58d6 69 {
mahphalke 1:6cb62c8c58d6 70 return iiod->ops->read(buf, len);
mahphalke 1:6cb62c8c58d6 71 }
mahphalke 1:6cb62c8c58d6 72
mahphalke 1:6cb62c8c58d6 73 ssize_t tinyiiod_read_line(struct tinyiiod *iiod, char *buf, size_t len)
mahphalke 1:6cb62c8c58d6 74 {
mahphalke 1:6cb62c8c58d6 75 uint32_t i;
mahphalke 1:6cb62c8c58d6 76 bool found = false;
mahphalke 1:6cb62c8c58d6 77
mahphalke 1:6cb62c8c58d6 78 if (iiod->ops->read_line)
mahphalke 1:6cb62c8c58d6 79 return iiod->ops->read_line(buf, len);
mahphalke 1:6cb62c8c58d6 80
mahphalke 1:6cb62c8c58d6 81 for (i = 0; i < len - 1; i++) {
mahphalke 1:6cb62c8c58d6 82 buf[i] = tinyiiod_read_char(iiod);
mahphalke 1:6cb62c8c58d6 83
mahphalke 1:6cb62c8c58d6 84 if (buf[i] != '\n')
mahphalke 1:6cb62c8c58d6 85 found = true;
mahphalke 1:6cb62c8c58d6 86 else if (found)
mahphalke 1:6cb62c8c58d6 87 break;
mahphalke 1:6cb62c8c58d6 88 }
mahphalke 1:6cb62c8c58d6 89
mahphalke 1:6cb62c8c58d6 90 if (!found || i == len - 1) {
mahphalke 1:6cb62c8c58d6 91 /* No \n found -> garbage data */
mahphalke 1:6cb62c8c58d6 92 return -EIO;
mahphalke 1:6cb62c8c58d6 93 }
mahphalke 1:6cb62c8c58d6 94
mahphalke 1:6cb62c8c58d6 95 buf[i - 1] = '\0';
mahphalke 1:6cb62c8c58d6 96
mahphalke 1:6cb62c8c58d6 97 return i;
mahphalke 1:6cb62c8c58d6 98 }
mahphalke 1:6cb62c8c58d6 99
mahphalke 1:6cb62c8c58d6 100 ssize_t tinyiiod_write_char(struct tinyiiod *iiod, char c)
mahphalke 1:6cb62c8c58d6 101 {
mahphalke 1:6cb62c8c58d6 102 return iiod->ops->write(&c, 1);
mahphalke 1:6cb62c8c58d6 103 }
mahphalke 1:6cb62c8c58d6 104
mahphalke 1:6cb62c8c58d6 105 ssize_t tinyiiod_write(struct tinyiiod *iiod, const char *data, size_t len)
mahphalke 1:6cb62c8c58d6 106 {
mahphalke 1:6cb62c8c58d6 107 return iiod->ops->write(data, len);
mahphalke 1:6cb62c8c58d6 108 }
mahphalke 1:6cb62c8c58d6 109
mahphalke 1:6cb62c8c58d6 110 ssize_t tinyiiod_write_string(struct tinyiiod *iiod, const char *str)
mahphalke 1:6cb62c8c58d6 111 {
mahphalke 1:6cb62c8c58d6 112 return tinyiiod_write(iiod, str, strlen(str));
mahphalke 1:6cb62c8c58d6 113 }
mahphalke 1:6cb62c8c58d6 114
mahphalke 1:6cb62c8c58d6 115 ssize_t tinyiiod_write_value(struct tinyiiod *iiod, int32_t value)
mahphalke 1:6cb62c8c58d6 116 {
mahphalke 1:6cb62c8c58d6 117 char buf[16];
mahphalke 1:6cb62c8c58d6 118
mahphalke 1:6cb62c8c58d6 119 snprintf(buf, sizeof(buf), "%"PRIi32"\n", value);
mahphalke 1:6cb62c8c58d6 120 return tinyiiod_write_string(iiod, buf);
mahphalke 1:6cb62c8c58d6 121 }
mahphalke 1:6cb62c8c58d6 122
mahphalke 1:6cb62c8c58d6 123 void tinyiiod_write_xml(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 124 {
mahphalke 1:6cb62c8c58d6 125 char *xml;
mahphalke 1:6cb62c8c58d6 126 iiod->ops->get_xml(&xml);
mahphalke 1:6cb62c8c58d6 127 size_t len = strlen(xml);
mahphalke 1:6cb62c8c58d6 128
mahphalke 1:6cb62c8c58d6 129 tinyiiod_write_value(iiod, len);
mahphalke 1:6cb62c8c58d6 130 tinyiiod_write(iiod, xml, len);
mahphalke 1:6cb62c8c58d6 131 tinyiiod_write_char(iiod, '\n');
mahphalke 1:6cb62c8c58d6 132 free(xml);
mahphalke 1:6cb62c8c58d6 133 }
mahphalke 1:6cb62c8c58d6 134
mahphalke 1:6cb62c8c58d6 135 void tinyiiod_do_read_attr(struct tinyiiod *iiod, const char *device,
mahphalke 1:6cb62c8c58d6 136 const char *channel, bool ch_out, const char *attr, bool debug)
mahphalke 1:6cb62c8c58d6 137 {
mahphalke 1:6cb62c8c58d6 138 ssize_t ret;
mahphalke 1:6cb62c8c58d6 139
mahphalke 1:6cb62c8c58d6 140 if (channel)
mahphalke 1:6cb62c8c58d6 141 ret = iiod->ops->ch_read_attr(device, channel,
mahphalke 1:6cb62c8c58d6 142 ch_out, attr, iiod->buf, IIOD_BUFFER_SIZE);
mahphalke 1:6cb62c8c58d6 143 else
mahphalke 1:6cb62c8c58d6 144 ret = iiod->ops->read_attr(device, attr,
mahphalke 1:6cb62c8c58d6 145 iiod->buf, IIOD_BUFFER_SIZE, debug);
mahphalke 1:6cb62c8c58d6 146
mahphalke 1:6cb62c8c58d6 147 tinyiiod_write_value(iiod, (int32_t) ret);
mahphalke 1:6cb62c8c58d6 148 if (ret > 0) {
mahphalke 1:6cb62c8c58d6 149 iiod->buf[ret] = '\n';
mahphalke 1:6cb62c8c58d6 150 tinyiiod_write(iiod, iiod->buf, (size_t) ret + 1);
mahphalke 1:6cb62c8c58d6 151 }
mahphalke 1:6cb62c8c58d6 152 }
mahphalke 1:6cb62c8c58d6 153
mahphalke 1:6cb62c8c58d6 154 void tinyiiod_do_write_attr(struct tinyiiod *iiod, const char *device,
mahphalke 1:6cb62c8c58d6 155 const char *channel, bool ch_out, const char *attr,
mahphalke 1:6cb62c8c58d6 156 size_t bytes, bool debug)
mahphalke 1:6cb62c8c58d6 157 {
mahphalke 1:6cb62c8c58d6 158 ssize_t ret;
mahphalke 1:6cb62c8c58d6 159
mahphalke 1:6cb62c8c58d6 160 if (bytes > IIOD_BUFFER_SIZE - 1)
mahphalke 1:6cb62c8c58d6 161 bytes = IIOD_BUFFER_SIZE - 1;
mahphalke 1:6cb62c8c58d6 162
mahphalke 1:6cb62c8c58d6 163 tinyiiod_read(iiod, iiod->buf, bytes);
mahphalke 1:6cb62c8c58d6 164 iiod->buf[bytes] = '\0';
mahphalke 1:6cb62c8c58d6 165
mahphalke 1:6cb62c8c58d6 166 if (channel)
mahphalke 1:6cb62c8c58d6 167 ret = iiod->ops->ch_write_attr(device, channel, ch_out,
mahphalke 1:6cb62c8c58d6 168 attr, iiod->buf, bytes);
mahphalke 1:6cb62c8c58d6 169 else
mahphalke 1:6cb62c8c58d6 170 ret = iiod->ops->write_attr(device, attr, iiod->buf, bytes, debug);
mahphalke 1:6cb62c8c58d6 171
mahphalke 1:6cb62c8c58d6 172 tinyiiod_write_value(iiod, (int32_t) ret);
mahphalke 1:6cb62c8c58d6 173 }
mahphalke 1:6cb62c8c58d6 174
mahphalke 1:6cb62c8c58d6 175 void tinyiiod_do_open(struct tinyiiod *iiod, const char *device,
mahphalke 1:6cb62c8c58d6 176 size_t sample_size, uint32_t mask)
mahphalke 1:6cb62c8c58d6 177 {
mahphalke 1:6cb62c8c58d6 178 int32_t ret = iiod->ops->open(device, sample_size, mask);
mahphalke 1:6cb62c8c58d6 179 tinyiiod_write_value(iiod, ret);
mahphalke 1:6cb62c8c58d6 180 }
mahphalke 1:6cb62c8c58d6 181
mahphalke 1:6cb62c8c58d6 182 void tinyiiod_do_close(struct tinyiiod *iiod, const char *device)
mahphalke 1:6cb62c8c58d6 183 {
mahphalke 1:6cb62c8c58d6 184 int32_t ret = iiod->ops->close(device);
mahphalke 1:6cb62c8c58d6 185 tinyiiod_write_value(iiod, ret);
mahphalke 1:6cb62c8c58d6 186 }
mahphalke 1:6cb62c8c58d6 187
mahphalke 1:6cb62c8c58d6 188 int32_t tinyiiod_do_open_instance(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 189 {
mahphalke 1:6cb62c8c58d6 190 return iiod->ops->open_instance();
mahphalke 1:6cb62c8c58d6 191 }
mahphalke 1:6cb62c8c58d6 192
mahphalke 1:6cb62c8c58d6 193 int32_t tinyiiod_do_close_instance(struct tinyiiod *iiod)
mahphalke 1:6cb62c8c58d6 194 {
mahphalke 1:6cb62c8c58d6 195 return iiod->ops->close_instance();
mahphalke 1:6cb62c8c58d6 196 }
mahphalke 1:6cb62c8c58d6 197
mahphalke 1:6cb62c8c58d6 198 int32_t tinyiiod_do_writebuf(struct tinyiiod *iiod,
mahphalke 1:6cb62c8c58d6 199 const char *device, size_t bytes_count)
mahphalke 1:6cb62c8c58d6 200 {
mahphalke 1:6cb62c8c58d6 201 size_t bytes, offset = 0, total_bytes = bytes_count;
mahphalke 1:6cb62c8c58d6 202 char buf[256];
mahphalke 1:6cb62c8c58d6 203 int32_t ret = 0;
mahphalke 1:6cb62c8c58d6 204
mahphalke 1:6cb62c8c58d6 205 tinyiiod_write_value(iiod, bytes_count);
mahphalke 1:6cb62c8c58d6 206 while (bytes_count) {
mahphalke 1:6cb62c8c58d6 207 bytes = bytes_count > sizeof(buf) ? sizeof(buf) : bytes_count;
mahphalke 1:6cb62c8c58d6 208 ret = tinyiiod_read(iiod, buf, bytes);
mahphalke 1:6cb62c8c58d6 209 if (ret > 0) {
mahphalke 1:6cb62c8c58d6 210 ret = iiod->ops->write_data(device, buf, offset, ret);
mahphalke 1:6cb62c8c58d6 211 offset += ret;
mahphalke 1:6cb62c8c58d6 212 if (ret < 0)
mahphalke 1:6cb62c8c58d6 213 return ret;
mahphalke 1:6cb62c8c58d6 214 bytes_count -= ret;
mahphalke 1:6cb62c8c58d6 215 } else
mahphalke 1:6cb62c8c58d6 216 return ret;
mahphalke 1:6cb62c8c58d6 217 }
mahphalke 1:6cb62c8c58d6 218 if (iiod->ops->transfer_mem_to_dev)
mahphalke 1:6cb62c8c58d6 219 ret = iiod->ops->transfer_mem_to_dev(device, total_bytes);
mahphalke 1:6cb62c8c58d6 220 tinyiiod_write_value(iiod, (int) total_bytes);
mahphalke 1:6cb62c8c58d6 221
mahphalke 1:6cb62c8c58d6 222 return ret;
mahphalke 1:6cb62c8c58d6 223 }
mahphalke 1:6cb62c8c58d6 224
mahphalke 1:6cb62c8c58d6 225 int32_t tinyiiod_do_readbuf(struct tinyiiod *iiod,
mahphalke 1:6cb62c8c58d6 226 const char *device, size_t bytes_count)
mahphalke 1:6cb62c8c58d6 227 {
mahphalke 1:6cb62c8c58d6 228 int32_t ret;
mahphalke 1:6cb62c8c58d6 229 char buf[256];
mahphalke 1:6cb62c8c58d6 230 uint32_t mask;
mahphalke 1:6cb62c8c58d6 231 bool print_mask = true;
mahphalke 1:6cb62c8c58d6 232 size_t offset = 0;
mahphalke 1:6cb62c8c58d6 233
mahphalke 1:6cb62c8c58d6 234 ret = iiod->ops->get_mask(device, &mask);
mahphalke 1:6cb62c8c58d6 235 if (ret < 0) {
mahphalke 1:6cb62c8c58d6 236 return ret;
mahphalke 1:6cb62c8c58d6 237 }
mahphalke 1:6cb62c8c58d6 238 if (iiod->ops->transfer_dev_to_mem)
mahphalke 1:6cb62c8c58d6 239 ret = iiod->ops->transfer_dev_to_mem(device, bytes_count);
mahphalke 1:6cb62c8c58d6 240 while (bytes_count) {
mahphalke 1:6cb62c8c58d6 241 size_t bytes = bytes_count > sizeof(buf) ? sizeof(buf) : bytes_count;
mahphalke 1:6cb62c8c58d6 242
mahphalke 1:6cb62c8c58d6 243 ret = (int) iiod->ops->read_data(device, buf, offset, bytes);
mahphalke 1:6cb62c8c58d6 244 offset += bytes;
mahphalke 1:6cb62c8c58d6 245 tinyiiod_write_value(iiod, ret);
mahphalke 1:6cb62c8c58d6 246 if (ret < 0)
mahphalke 1:6cb62c8c58d6 247 return ret;
mahphalke 1:6cb62c8c58d6 248
mahphalke 1:6cb62c8c58d6 249 if (print_mask) {
mahphalke 1:6cb62c8c58d6 250 char buf_mask[10];
mahphalke 1:6cb62c8c58d6 251
mahphalke 1:6cb62c8c58d6 252 snprintf(buf_mask, sizeof(buf_mask), "%08"PRIx32"\n", mask);
mahphalke 1:6cb62c8c58d6 253 tinyiiod_write_string(iiod, buf_mask);
mahphalke 1:6cb62c8c58d6 254 print_mask = false;
mahphalke 1:6cb62c8c58d6 255 }
mahphalke 1:6cb62c8c58d6 256
mahphalke 1:6cb62c8c58d6 257 tinyiiod_write(iiod, buf, (size_t) ret);
mahphalke 1:6cb62c8c58d6 258 bytes_count -= (size_t) ret;
mahphalke 1:6cb62c8c58d6 259 }
mahphalke 1:6cb62c8c58d6 260
mahphalke 1:6cb62c8c58d6 261 return ret;
mahphalke 1:6cb62c8c58d6 262 }
mahphalke 1:6cb62c8c58d6 263
mahphalke 1:6cb62c8c58d6 264 int32_t tinyiiod_set_timeout(struct tinyiiod *iiod, uint32_t timeout)
mahphalke 1:6cb62c8c58d6 265 {
mahphalke 1:6cb62c8c58d6 266 int32_t ret = 0;
mahphalke 1:6cb62c8c58d6 267
mahphalke 1:6cb62c8c58d6 268 if (iiod->ops->set_timeout)
mahphalke 1:6cb62c8c58d6 269 ret = iiod->ops->set_timeout(timeout);
mahphalke 1:6cb62c8c58d6 270 tinyiiod_write_value(iiod, ret);
mahphalke 1:6cb62c8c58d6 271
mahphalke 1:6cb62c8c58d6 272 return ret;
mahphalke 1:6cb62c8c58d6 273 }