Analog Devices / Mbed OS tinyiiod-example
Committer:
adisuciu
Date:
Fri Dec 13 22:21:29 2019 +0000
Revision:
0:bf917bb43db6
Initial revision

Who changed what in which revision?

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