X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fdevice.c;h=9ba8bfc570cb43ed9bec54a661904b45ec6f7e88;hb=f1ba6b4b2c9a8ecf90bb31efb218752aa7e49d1a;hp=38ac003cf01d7433b9c1767ccf3ace01d70329db;hpb=4bf93988023b2428129c8145ef9ea7121400f195;p=libsigrok.git diff --git a/src/device.c b/src/device.c index 38ac003c..9ba8bfc5 100644 --- a/src/device.c +++ b/src/device.c @@ -136,7 +136,9 @@ SR_API int sr_dev_channel_enable(struct sr_channel *channel, gboolean state) } /* Returns the next enabled channel, wrapping around if necessary. */ +/** @private */ SR_PRIV struct sr_channel *sr_next_enabled_channel(const struct sr_dev_inst *sdi, + struct sr_channel *cur_channel) { struct sr_channel *next_channel; @@ -409,7 +411,8 @@ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus, /** * Free struct sr_usb_dev_inst * allocated by sr_usb_dev_inst(). * - * @param usb The struct sr_usb_dev_inst * to free. Must not be NULL. + * @param usb The struct sr_usb_dev_inst * to free. If NULL, this + * function does nothing. * * @private */ @@ -457,12 +460,16 @@ SR_PRIV struct sr_serial_dev_inst *sr_serial_dev_inst_new(const char *port, /** * Free struct sr_serial_dev_inst * allocated by sr_serial_dev_inst(). * - * @param serial The struct sr_serial_dev_inst * to free. Must not be NULL. + * @param serial The struct sr_serial_dev_inst * to free. If NULL, this + * function will do nothing. * * @private */ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial) { + if (!serial) + return; + g_free(serial->port); g_free(serial->serialcomm); g_free(serial); @@ -484,6 +491,9 @@ SR_PRIV struct sr_usbtmc_dev_inst *sr_usbtmc_dev_inst_new(const char *device) /** @private */ SR_PRIV void sr_usbtmc_dev_inst_free(struct sr_usbtmc_dev_inst *usbtmc) { + if (!usbtmc) + return; + g_free(usbtmc->device); g_free(usbtmc); } @@ -535,11 +545,19 @@ SR_API int sr_dev_clear(const struct sr_dev_driver *driver) } /** - * Open the specified device. + * Open the specified device instance. + * + * If the device instance is already open (sdi->status == SR_ST_ACTIVE), + * SR_ERR will be returned and no re-opening of the device will be attempted. + * + * If opening was successful, sdi->status is set to SR_ST_ACTIVE, otherwise + * it will be left unchanged. * * @param sdi Device instance to use. Must not be NULL. * - * @return SR_OK upon success, a negative error code upon errors. + * @retval SR_OK Success. + * @retval SR_ERR_ARG Invalid arguments. + * @retval SR_ERR Device instance was already active, or other error. * * @since 0.2.0 */ @@ -548,19 +566,40 @@ SR_API int sr_dev_open(struct sr_dev_inst *sdi) int ret; if (!sdi || !sdi->driver || !sdi->driver->dev_open) + return SR_ERR_ARG; + + if (sdi->status == SR_ST_ACTIVE) { + sr_err("%s: Device instance already active, can't re-open.", + sdi->driver->name); return SR_ERR; + } + + sr_dbg("%s: Opening device instance.", sdi->driver->name); ret = sdi->driver->dev_open(sdi); + if (ret == SR_OK) + sdi->status = SR_ST_ACTIVE; + return ret; } /** - * Close the specified device. + * Close the specified device instance. + * + * If the device instance is not open (sdi->status != SR_ST_ACTIVE), + * SR_ERR_DEV_CLOSED will be returned and no closing will be attempted. + * + * Note: sdi->status will be set to SR_ST_INACTIVE, regardless of whether + * there are any errors during closing of the device instance (any errors + * will be reported via error code and log message, though). * * @param sdi Device instance to use. Must not be NULL. * - * @return SR_OK upon success, a negative error code upon errors. + * @retval SR_OK Success. + * @retval SR_ERR_ARG Invalid arguments. + * @retval SR_ERR_DEV_CLOSED Device instance was not active. + * @retval SR_ERR Other error. * * @since 0.2.0 */ @@ -569,7 +608,17 @@ SR_API int sr_dev_close(struct sr_dev_inst *sdi) int ret; if (!sdi || !sdi->driver || !sdi->driver->dev_close) - return SR_ERR; + return SR_ERR_ARG; + + if (sdi->status != SR_ST_ACTIVE) { + sr_err("%s: Device instance not active, can't close.", + sdi->driver->name); + return SR_ERR_DEV_CLOSED; + } + + sdi->status = SR_ST_INACTIVE; + + sr_dbg("%s: Closing device instance.", sdi->driver->name); ret = sdi->driver->dev_close(sdi);