Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
tinyiiod.cpp
- Committer:
- adisuciu
- Date:
- 2019-12-13
- Revision:
- 0:bf917bb43db6
File content as of revision 0:bf917bb43db6:
/*
* libtinyiiod - Tiny IIO Daemon Library
*
* Copyright (C) 2016 Analog Devices, Inc.
* Author: Paul Cercueil <paul.cercueil@analog.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#include "tinyiiod-private.h"
#include "compat.h"
struct tinyiiod {
struct tinyiiod_ops *ops;
char *buf;
};
struct tinyiiod * tinyiiod_create(struct tinyiiod_ops *ops)
{
struct tinyiiod *iiod =(struct tinyiiod*) malloc(sizeof(*iiod));
if (!iiod)
return NULL;
iiod->buf = (char*)malloc(IIOD_BUFFER_SIZE);
iiod->ops = ops;
return iiod;
}
void tinyiiod_destroy(struct tinyiiod *iiod)
{
free(iiod->ops);
free(iiod->buf);
free(iiod);
}
int32_t tinyiiod_read_command(struct tinyiiod *iiod)
{
char buf[128];
int32_t ret;
ret = tinyiiod_read_line(iiod, buf, sizeof(buf));
if (ret < 0)
return ret;
ret = tinyiiod_parse_string(iiod, buf);
if (ret < 0)
tinyiiod_write_value(iiod, ret);
return ret;
}
char tinyiiod_read_char(struct tinyiiod *iiod)
{
char c;
iiod->ops->read(&c, 1);
return c;
}
ssize_t tinyiiod_read(struct tinyiiod *iiod, char *buf, size_t len)
{
return iiod->ops->read(buf, len);
}
ssize_t tinyiiod_read_line(struct tinyiiod *iiod, char *buf, size_t len)
{
uint32_t i;
bool found = false;
if (iiod->ops->read_line)
return iiod->ops->read_line(buf, len);
for (i = 0; i < len - 1; i++) {
buf[i] = tinyiiod_read_char(iiod);
if (buf[i] != '\n')
found = true;
else if (found)
break;
}
if (!found || i == len - 1) {
/* No \n found -> garbage data */
return -EIO;
}
buf[i - 1] = '\0';
return i;
}
ssize_t tinyiiod_write_char(struct tinyiiod *iiod, char c)
{
return iiod->ops->write(&c, 1);
}
ssize_t tinyiiod_write(struct tinyiiod *iiod, const char *data, size_t len)
{
return iiod->ops->write(data, len);
}
ssize_t tinyiiod_write_string(struct tinyiiod *iiod, const char *str)
{
return tinyiiod_write(iiod, str, strlen(str));
}
ssize_t tinyiiod_write_value(struct tinyiiod *iiod, int32_t value)
{
char buf[16];
snprintf(buf, sizeof(buf), "%"PRIi32"\n", value);
return tinyiiod_write_string(iiod, buf);
}
void tinyiiod_write_xml(struct tinyiiod *iiod)
{
char *xml;
iiod->ops->get_xml(&xml);
size_t len = strlen(xml);
tinyiiod_write_value(iiod, len);
tinyiiod_write(iiod, xml, len);
tinyiiod_write_char(iiod, '\n');
free(xml);
}
void tinyiiod_do_read_attr(struct tinyiiod *iiod, const char *device,
const char *channel, bool ch_out, const char *attr, bool debug)
{
ssize_t ret;
if (channel)
ret = iiod->ops->ch_read_attr(device, channel,
ch_out, attr, iiod->buf, IIOD_BUFFER_SIZE);
else
ret = iiod->ops->read_attr(device, attr,
iiod->buf, IIOD_BUFFER_SIZE, debug);
tinyiiod_write_value(iiod, (int32_t) ret);
if (ret > 0) {
iiod->buf[ret] = '\n';
tinyiiod_write(iiod, iiod->buf, (size_t) ret + 1);
}
}
void tinyiiod_do_write_attr(struct tinyiiod *iiod, const char *device,
const char *channel, bool ch_out, const char *attr,
size_t bytes, bool debug)
{
ssize_t ret;
if (bytes > IIOD_BUFFER_SIZE - 1)
bytes = IIOD_BUFFER_SIZE - 1;
tinyiiod_read(iiod, iiod->buf, bytes);
iiod->buf[bytes] = '\0';
if (channel)
ret = iiod->ops->ch_write_attr(device, channel, ch_out,
attr, iiod->buf, bytes);
else
ret = iiod->ops->write_attr(device, attr, iiod->buf, bytes, debug);
tinyiiod_write_value(iiod, (int32_t) ret);
}
void tinyiiod_do_open(struct tinyiiod *iiod, const char *device,
size_t sample_size, uint32_t mask)
{
int32_t ret = iiod->ops->open(device, sample_size, mask);
tinyiiod_write_value(iiod, ret);
}
void tinyiiod_do_close(struct tinyiiod *iiod, const char *device)
{
int32_t ret = iiod->ops->close(device);
tinyiiod_write_value(iiod, ret);
}
int32_t tinyiiod_do_open_instance(struct tinyiiod *iiod)
{
return iiod->ops->open_instance();
}
int32_t tinyiiod_do_close_instance(struct tinyiiod *iiod)
{
return iiod->ops->close_instance();
}
int32_t tinyiiod_do_writebuf(struct tinyiiod *iiod,
const char *device, size_t bytes_count)
{
size_t bytes, offset = 0, total_bytes = bytes_count;
char buf[256];
int32_t ret;
tinyiiod_write_value(iiod, bytes_count);
while (bytes_count) {
bytes = bytes_count > sizeof(buf) ? sizeof(buf) : bytes_count;
ret = tinyiiod_read(iiod, buf, bytes);
if (ret > 0) {
ret = iiod->ops->write_data(device, buf, offset, ret);
offset += ret;
if (ret < 0)
return ret;
bytes_count -= ret;
} else
return ret;
}
if (iiod->ops->transfer_mem_to_dev)
ret = iiod->ops->transfer_mem_to_dev(device, total_bytes);
tinyiiod_write_value(iiod, (int) total_bytes);
return ret;
}
int32_t tinyiiod_do_readbuf(struct tinyiiod *iiod,
const char *device, size_t bytes_count)
{
int32_t ret;
char buf[256];
uint32_t mask;
bool print_mask = true;
size_t offset = 0;
ret = iiod->ops->get_mask(device, &mask);
if (ret < 0) {
return ret;
}
if (iiod->ops->transfer_dev_to_mem)
ret = iiod->ops->transfer_dev_to_mem(device, bytes_count);
while (bytes_count) {
size_t bytes = bytes_count > sizeof(buf) ? sizeof(buf) : bytes_count;
ret = (int) iiod->ops->read_data(device, buf, offset, bytes);
offset += bytes;
tinyiiod_write_value(iiod, ret);
if (ret < 0)
return ret;
if (print_mask) {
char buf_mask[10];
snprintf(buf_mask, sizeof(buf_mask), "%08"PRIx32"\n", mask);
tinyiiod_write_string(iiod, buf_mask);
print_mask = false;
}
tinyiiod_write(iiod, buf, (size_t) ret);
bytes_count -= (size_t) ret;
}
return ret;
}
int32_t tinyiiod_set_timeout(struct tinyiiod *iiod, uint32_t timeout)
{
int32_t ret = 0;
if (iiod->ops->set_timeout)
ret = iiod->ops->set_timeout(timeout);
tinyiiod_write_value(iiod, ret);
return ret;
}

