diff --git a/context.c b/context.c index 36d321563..fc91d494e 100644 --- a/context.c +++ b/context.c @@ -366,6 +366,9 @@ int iio_context_get_version(const struct iio_context *ctx, return 0; } + if (ctx->ops->get_version) + return ctx->ops->get_version(ctx, major, minor, git_tag); + iio_library_get_version(major, minor, git_tag); return 0; } diff --git a/iio-backend.h b/iio-backend.h index 6bff4d6aa..582132456 100644 --- a/iio-backend.h +++ b/iio-backend.h @@ -62,6 +62,9 @@ struct iio_backend_ops { char * (*get_description)(const struct iio_context *ctx); + int (*get_version)(const struct iio_context *ctx, unsigned int *major, + unsigned int *minor, char git_tag[8]); + int (*set_timeout)(struct iio_context *ctx, unsigned int timeout); }; diff --git a/iiod-client.c b/iiod-client.c index 9b938aa76..e14ec079c 100644 --- a/iiod-client.c +++ b/iiod-client.c @@ -177,6 +177,58 @@ void iiod_client_destroy(struct iiod_client *client) free(client); } +int iiod_client_get_version(struct iiod_client *client, + struct iiod_client_pdata *desc, + unsigned int *major, unsigned int *minor, + char *git_tag) +{ + struct iio_context_pdata *pdata = client->pdata; + const struct iiod_client_ops *ops = client->ops; + char buf[256], *ptr = buf, *end; + long maj, min; + int ret; + + iio_mutex_lock(client->lock); + + ret = (int) ops->write(pdata, desc, "VERSION\r\n", sizeof("VERSION\r\n") - 1); + if (ret < 0) { + iio_mutex_unlock(client->lock); + return ret; + } + + ret = (int) ops->read_line(pdata, desc, buf, sizeof(buf)); + iio_mutex_unlock(client->lock); + + if (ret < 0) + return ret; + + errno = 0; + maj = strtol(ptr, &end, 10); + if (ptr == end || errno == ERANGE) + return -EIO; + + ptr = end + 1; + errno = 0; + min = strtol(ptr, &end, 10); + if (ptr == end || errno == ERANGE) + return -EIO; + + ptr = end + 1; + if (buf + ret < ptr + 8) + return -EIO; + + /* Strip the \n */ + ptr[buf + ret - ptr - 1] = '\0'; + + if (major) + *major = (unsigned int) maj; + if (minor) + *minor = (unsigned int) min; + if (git_tag) + iio_strlcpy(git_tag, ptr, 8); + return 0; +} + int iiod_client_get_trigger(struct iiod_client *client, struct iiod_client_pdata *desc, const struct iio_device *dev, diff --git a/iiod-client.h b/iiod-client.h index 1183602a8..be29abe15 100644 --- a/iiod-client.h +++ b/iiod-client.h @@ -35,6 +35,11 @@ struct iiod_client * iiod_client_new(struct iio_context_pdata *pdata, const struct iiod_client_ops *ops); void iiod_client_destroy(struct iiod_client *client); +int iiod_client_get_version(struct iiod_client *client, + struct iiod_client_pdata *desc, + unsigned int *major, unsigned int *minor, + char *git_tag); + int iiod_client_get_trigger(struct iiod_client *client, struct iiod_client_pdata *desc, const struct iio_device *dev, diff --git a/network.c b/network.c index 32ba08da1..3b39c89ec 100644 --- a/network.c +++ b/network.c @@ -856,6 +856,15 @@ static void network_shutdown(struct iio_context *ctx) freeaddrinfo(pdata->addrinfo); } +static int network_get_version(const struct iio_context *ctx, + unsigned int *major, unsigned int *minor, char git_tag[8]) +{ + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return iiod_client_get_version(pdata->iiod_client, + &pdata->io_ctx, major, minor, git_tag); +} + static unsigned int calculate_remote_timeout(unsigned int timeout) { /* XXX(pcercuei): We currently hardcode timeout / 2 for the backend used @@ -918,6 +927,7 @@ static const struct iio_backend_ops network_ops = { .set_trigger = network_set_trigger, .shutdown = network_shutdown, .get_description = network_get_description, + .get_version = network_get_version, .set_timeout = network_set_timeout, .set_kernel_buffers_count = network_set_kernel_buffers_count, diff --git a/serial.c b/serial.c index 34a2a3a46..451b03f03 100644 --- a/serial.c +++ b/serial.c @@ -96,6 +96,15 @@ static inline int libserialport_to_errno(enum sp_return ret) } } +static int serial_get_version(const struct iio_context *ctx, + unsigned int *major, unsigned int *minor, char git_tag[8]) +{ + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return iiod_client_get_version(pdata->iiod_client, NULL, + major, minor, git_tag); +} + static char * __serial_get_description(struct sp_port *port) { char *description, *name, *desc; @@ -347,6 +356,7 @@ static int serial_set_timeout(struct iio_context *ctx, unsigned int timeout) } static const struct iio_backend_ops serial_ops = { + .get_version = serial_get_version, .open = serial_open, .close = serial_close, .read = serial_read, diff --git a/usb.c b/usb.c index cd6521f59..b2042e9c4 100644 --- a/usb.c +++ b/usb.c @@ -119,6 +119,15 @@ static void usb_io_context_exit(struct iiod_client_pdata *io_ctx) } } +static int usb_get_version(const struct iio_context *ctx, + unsigned int *major, unsigned int *minor, char git_tag[8]) +{ + struct iio_context_pdata *pdata = iio_context_get_pdata(ctx); + + return iiod_client_get_version(pdata->iiod_client, + &pdata->io_ctx, major, minor, git_tag); +} + static unsigned int usb_calculate_remote_timeout(unsigned int timeout) { /* XXX(pcercuei): We currently hardcode timeout / 2 for the backend used @@ -530,6 +539,7 @@ static void usb_cancel(const struct iio_device *dev) } static const struct iio_backend_ops usb_ops = { + .get_version = usb_get_version, .open = usb_open, .close = usb_close, .read = usb_read,