Skip to content

Commit

Permalink
iio: create iio_context_create_from_backend() helper and use it for l…
Browse files Browse the repository at this point in the history
…ocal & xml

The creation of a context can be tied to an iio_backend object that acts as
a template for some context parameters.
Using an iio_backend object for IIO context creation allows us to hide the
assignments of the name, iio_backend_ops, description, private data and
possibly other parameters in the future.

For now, this ties it to the local & xml backends. The other backends seem
to be iiod client-type backends. Using the iio_backend object there
requires a bit more rework.

At a later point in time, the iio_context_create_from_backend() helper
should also do more validation for the backend object.

Signed-off-by: Alexandru Ardelean <[email protected]>
  • Loading branch information
commodo committed Oct 14, 2020
1 parent 0fcd01c commit 4a72ef0
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 29 deletions.
45 changes: 45 additions & 0 deletions context.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,51 @@ char * iio_context_create_xml(const struct iio_context *ctx)
return NULL;
}

struct iio_context * iio_context_create_from_backend(
const struct iio_backend *backend,
const char *description)
{
struct iio_context *ctx;
int ret;

if (!backend) {
errno = EINVAL;
return NULL;
}

ctx = zalloc(sizeof(*ctx));
if (!ctx) {
errno = ENOMEM;
return NULL;
}

ret = -ENOMEM;
if (backend->sizeof_context_pdata) {
ctx->pdata = zalloc(backend->sizeof_context_pdata);
if (!ctx->pdata)
goto err_free_ctx;
}

if (description) {
ctx->description = iio_strdup(description);
if (!ctx->description)
goto err_free_pdata;
}

ctx->name = backend->name;
ctx->ops = backend->ops;

return ctx;

err_free_pdata:
if (ctx->pdata)
free(ctx->pdata);
err_free_ctx:
free(ctx);
errno = -ret;
return NULL;
}

const char * iio_context_get_xml(const struct iio_context *ctx)
{
return ctx->xml;
Expand Down
24 changes: 24 additions & 0 deletions iio-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
struct iio_device;
struct iio_context;

enum iio_backend_api_ver {
IIO_BACKEND_API_V1 = 1,
};

enum iio_attr_type {
IIO_ATTR_TYPE_DEVICE = 0,
IIO_ATTR_TYPE_DEBUG,
Expand Down Expand Up @@ -72,4 +76,24 @@ struct iio_backend_ops {
int (*set_timeout)(struct iio_context *ctx, unsigned int timeout);
};

/**
* struct iio_backend - IIO backend object (API version 1)
* @api_version API version for interfacing with libiio core library
* @name Name of this backend
* @uri_prefix URI prefix for this backend
* @ops Reference to backend ops
* @sizeof_context_pdata Size of private data for the IIO contexts generated by this backend
*/
struct iio_backend {
unsigned int api_version;
const char *name;
const char *uri_prefix;
const struct iio_backend_ops *ops;
unsigned int sizeof_context_pdata;
};

__api struct iio_context * iio_context_create_from_backend(
const struct iio_backend *backend,
const char *description);

#endif /* __IIO_BACKEND_H__ */
40 changes: 20 additions & 20 deletions local.c
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,14 @@ static const struct iio_backend_ops local_ops = {
.cancel = local_cancel,
};

static const struct iio_backend local_backend = {
.api_version = IIO_BACKEND_API_V1,
.name = "local",
.uri_prefix = "local:",
.ops = &local_ops,
.sizeof_context_pdata = sizeof(struct iio_context_pdata),
};

static void init_data_scale(struct iio_channel *chn)
{
char *end, buf[1024];
Expand Down Expand Up @@ -2038,37 +2046,29 @@ static int populate_context_attrs(struct iio_context *ctx, const char *file)

struct iio_context * local_create_context(void)
{
struct iio_context *ctx;
char *description;
int ret = -ENOMEM;
unsigned int len;
struct utsname uts;
struct iio_context *ctx = zalloc(sizeof(*ctx));
if (!ctx)
goto err_set_errno;

ctx->ops = &local_ops;
ctx->name = "local";

ctx->pdata = zalloc(sizeof(*ctx->pdata));
if (!ctx->pdata) {
free(ctx);
goto err_set_errno;
}

local_set_timeout(ctx, DEFAULT_TIMEOUT_MS);

uname(&uts);
len = strlen(uts.sysname) + strlen(uts.nodename) + strlen(uts.release)
+ strlen(uts.version) + strlen(uts.machine);
ctx->description = malloc(len + 5); /* 4 spaces + EOF */
if (!ctx->description) {
free(ctx->pdata);
free(ctx);
description = malloc(len + 5); /* 4 spaces + EOF */
if (!description)
goto err_set_errno;
}

iio_snprintf(ctx->description, len + 5, "%s %s %s %s %s", uts.sysname,
iio_snprintf(description, len + 5, "%s %s %s %s %s", uts.sysname,
uts.nodename, uts.release, uts.version, uts.machine);

ctx = iio_context_create_from_backend(&local_backend, description);
free(description);
if (!ctx)
goto err_set_errno;

local_set_timeout(ctx, DEFAULT_TIMEOUT_MS);

ret = foreach_in_dir(ctx, "/sys/bus/iio/devices", true, create_device);
if (ret < 0)
goto err_context_destroy;
Expand Down
24 changes: 15 additions & 9 deletions xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,13 @@ static const struct iio_backend_ops xml_ops = {
.clone = xml_clone,
};

static const struct iio_backend xml_backend = {
.api_version = IIO_BACKEND_API_V1,
.name = "xml",
.uri_prefix = "xml:",
.ops = &xml_ops,
};

static int parse_context_attr(struct iio_context *ctx, xmlNode *n)
{
xmlAttr *attr;
Expand All @@ -376,29 +383,28 @@ static struct iio_context * iio_create_xml_context_helper(xmlDoc *doc)
xmlNode *root, *n;
xmlAttr *attr;
int err = -ENOMEM;
struct iio_context *ctx = zalloc(sizeof(*ctx));
if (!ctx)
goto err_set_errno;

ctx->name = "xml";
ctx->ops = &xml_ops;
struct iio_context *ctx;
const char *description = NULL;

root = xmlDocGetRootElement(doc);
if (strcmp((char *) root->name, "context")) {
IIO_ERROR("Unrecognized XML file\n");
err = -EINVAL;
goto err_context_destroy;
goto err_set_errno;
}

for (attr = root->properties; attr; attr = attr->next) {
if (!strcmp((char *) attr->name, "description"))
ctx->description = iio_strdup(
(char *) attr->children->content);
description = (const char *)attr->children->content;
else if (strcmp((char *) attr->name, "name"))
IIO_WARNING("Unknown parameter \'%s\' in <context>\n",
(char *) attr->children->content);
}

ctx = iio_context_create_from_backend(&xml_backend, description);
if (!ctx)
goto err_set_errno;

for (n = root->children; n; n = n->next) {
struct iio_device *dev;

Expand Down

0 comments on commit 4a72ef0

Please sign in to comment.