libsigrok  0.3.0
sigrok hardware access and backend library
device.c
Go to the documentation of this file.
00001 /*
00002  * This file is part of the libsigrok project.
00003  *
00004  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
00005  *
00006  * This program is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <stdio.h>
00021 #include <glib.h>
00022 #include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */
00023 #include "libsigrok.h"
00024 #include "libsigrok-internal.h"
00025 
00026 /** @cond PRIVATE */
00027 #define LOG_PREFIX "device"
00028 /** @endcond */
00029 
00030 /**
00031  * @file
00032  *
00033  * Device handling in libsigrok.
00034  */
00035 
00036 /**
00037  * @defgroup grp_devices Devices
00038  *
00039  * Device handling in libsigrok.
00040  *
00041  * @{
00042  */
00043 
00044 /** @private
00045  *  Allocate and initialize new struct sr_channel
00046  *  @param[in]  index @copydoc sr_channel::index
00047  *  @param[in]  type @copydoc sr_channel::type
00048  *  @param[in]  enabled @copydoc sr_channel::enabled
00049  *  @param[in]  name @copydoc sr_channel::name
00050  *
00051  *  @return NULL (failure) or new struct sr_channel*.
00052  */
00053 SR_PRIV struct sr_channel *sr_channel_new(int index, int type,
00054                 gboolean enabled, const char *name)
00055 {
00056         struct sr_channel *ch;
00057 
00058         if (!(ch = g_try_malloc0(sizeof(struct sr_channel)))) {
00059                 sr_err("Channel malloc failed.");
00060                 return NULL;
00061         }
00062 
00063         ch->index = index;
00064         ch->type = type;
00065         ch->enabled = enabled;
00066         if (name)
00067                 ch->name = g_strdup(name);
00068 
00069         return ch;
00070 }
00071 
00072 /**
00073  * Set the name of the specified channel in the specified device.
00074  *
00075  * If the channel already has a different name assigned to it, it will be
00076  * removed, and the new name will be saved instead.
00077  *
00078  * @param sdi The device instance the channel is connected to.
00079  * @param[in] channelnum The number of the channel whose name to set.
00080  *                 Note that the channel numbers start at 0.
00081  * @param[in] name The new name that the specified channel should get. A copy
00082  *             of the string is made.
00083  *
00084  * @return SR_OK on success, or SR_ERR_ARG on invalid arguments.
00085  *
00086  * @since 0.3.0
00087  */
00088 SR_API int sr_dev_channel_name_set(const struct sr_dev_inst *sdi,
00089                 int channelnum, const char *name)
00090 {
00091         GSList *l;
00092         struct sr_channel *ch;
00093         int ret;
00094 
00095         if (!sdi) {
00096                 sr_err("%s: sdi was NULL", __func__);
00097                 return SR_ERR_ARG;
00098         }
00099 
00100         ret = SR_ERR_ARG;
00101         for (l = sdi->channels; l; l = l->next) {
00102                 ch = l->data;
00103                 if (ch->index == channelnum) {
00104                         g_free(ch->name);
00105                         ch->name = g_strdup(name);
00106                         ret = SR_OK;
00107                         break;
00108                 }
00109         }
00110 
00111         return ret;
00112 }
00113 
00114 /**
00115  * Enable or disable a channel on the specified device.
00116  *
00117  * @param sdi The device instance the channel is connected to.
00118  * @param channelnum The channel number, starting from 0.
00119  * @param state TRUE to enable the channel, FALSE to disable.
00120  *
00121  * @return SR_OK on success or SR_ERR on failure.  In case of invalid
00122  *         arguments, SR_ERR_ARG is returned and the channel enabled state
00123  *         remains unchanged.
00124  *
00125  * @since 0.3.0
00126  */
00127 SR_API int sr_dev_channel_enable(const struct sr_dev_inst *sdi, int channelnum,
00128                 gboolean state)
00129 {
00130         GSList *l;
00131         struct sr_channel *ch;
00132         int ret;
00133         gboolean was_enabled;
00134 
00135         if (!sdi)
00136                 return SR_ERR_ARG;
00137 
00138         ret = SR_ERR_ARG;
00139         for (l = sdi->channels; l; l = l->next) {
00140                 ch = l->data;
00141                 if (ch->index == channelnum) {
00142                         was_enabled = ch->enabled;
00143                         ch->enabled = state;
00144                         ret = SR_OK;
00145                         if (!state != !was_enabled && sdi->driver
00146                                         && sdi->driver->config_channel_set) {
00147                                 ret = sdi->driver->config_channel_set(
00148                                         sdi, ch, SR_CHANNEL_SET_ENABLED);
00149                                 /* Roll back change if it wasn't applicable. */
00150                                 if (ret == SR_ERR_ARG)
00151                                         ch->enabled = was_enabled;
00152                         }
00153                         break;
00154                 }
00155         }
00156 
00157         return ret;
00158 }
00159 
00160 /**
00161  * Add a trigger to the specified device (and the specified channel).
00162  *
00163  * If the specified channel of this device already has a trigger, it will
00164  * be silently replaced.
00165  *
00166  * @param[in,out] sdi Pointer to the device instance; must not be NULL.
00167  * @param[in] channelnum Number of channel, starting at 0.
00168  * @param[in] trigger Trigger string, in the format used by sigrok-cli
00169  *
00170  * @return SR_OK on success or SR_ERR on failure.  In case of invalid
00171  *         arguments, SR_ERR_ARG is returned and the trigger settings
00172  *         remain unchanged.
00173  *
00174  * @since 0.2.0
00175  */
00176 SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, int channelnum,
00177                 const char *trigger)
00178 {
00179         GSList *l;
00180         struct sr_channel *ch;
00181         char *old_trigger;
00182         int ret;
00183 
00184         if (!sdi)
00185                 return SR_ERR_ARG;
00186 
00187         ret = SR_ERR_ARG;
00188         for (l = sdi->channels; l; l = l->next) {
00189                 ch = l->data;
00190                 if (ch->index == channelnum) {
00191                         old_trigger = ch->trigger;
00192                         ret = SR_OK;
00193                         if (g_strcmp0(trigger, old_trigger) == 0)
00194                                 break;
00195                         /* Set new trigger if it has changed. */
00196                         ch->trigger = g_strdup(trigger);
00197 
00198                         if (sdi->driver && sdi->driver->config_channel_set) {
00199                                 ret = sdi->driver->config_channel_set(
00200                                         sdi, ch, SR_CHANNEL_SET_TRIGGER);
00201                                 /* Roll back change if it wasn't applicable. */
00202                                 if (ret == SR_ERR_ARG) {
00203                                         g_free(ch->trigger);
00204                                         ch->trigger = old_trigger;
00205                                         break;
00206                                 }
00207                         }
00208                         g_free(old_trigger);
00209                         break;
00210                 }
00211         }
00212 
00213         return ret;
00214 }
00215 
00216 /**
00217  * Determine whether the specified device instance has the specified
00218  * capability.
00219  *
00220  * @param sdi Pointer to the device instance to be checked. Must not be NULL.
00221  *            If the device's 'driver' field is NULL (virtual device), this
00222  *            function will always return FALSE (virtual devices don't have
00223  *            a hardware capabilities list).
00224  * @param[in] key The option that should be checked for is supported by the
00225  *            specified device.
00226  *
00227  * @retval TRUE Device has the specified option
00228  * @retval FALSE Device does not have the specified option, invalid input
00229  *         parameters or other error conditions.
00230  *
00231  * @since 0.2.0
00232  */
00233 SR_API gboolean sr_dev_has_option(const struct sr_dev_inst *sdi, int key)
00234 {
00235         GVariant *gvar;
00236         const int *devopts;
00237         gsize num_opts, i;
00238         int ret;
00239 
00240         if (!sdi || !sdi->driver || !sdi->driver->config_list)
00241                 return FALSE;
00242 
00243         if (sdi->driver->config_list(SR_CONF_DEVICE_OPTIONS,
00244                                 &gvar, sdi, NULL) != SR_OK)
00245                 return FALSE;
00246 
00247         ret = FALSE;
00248         devopts = g_variant_get_fixed_array(gvar, &num_opts, sizeof(int32_t));
00249         for (i = 0; i < num_opts; i++) {
00250                 if (devopts[i] == key) {
00251                         ret = TRUE;
00252                         break;
00253                 }
00254         }
00255         g_variant_unref(gvar);
00256 
00257         return ret;
00258 }
00259 
00260 /** @private
00261  *  Allocate and init new device instance struct.
00262  *  @param[in]  index   @copydoc sr_dev_inst::index
00263  *  @param[in]  status  @copydoc sr_dev_inst::status
00264  *  @param[in]  vendor  @copydoc sr_dev_inst::vendor
00265  *  @param[in]  model   @copydoc sr_dev_inst::model
00266  *  @param[in]  version @copydoc sr_dev_inst::version
00267  *
00268  *  @retval NULL Error
00269  *  @retval struct sr_dev_inst *. Dynamically allocated, free using
00270  *              sr_dev_inst_free().
00271  */
00272 SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int index, int status,
00273                 const char *vendor, const char *model, const char *version)
00274 {
00275         struct sr_dev_inst *sdi;
00276 
00277         if (!(sdi = g_try_malloc(sizeof(struct sr_dev_inst)))) {
00278                 sr_err("Device instance malloc failed.");
00279                 return NULL;
00280         }
00281 
00282         sdi->driver = NULL;
00283         sdi->index = index;
00284         sdi->status = status;
00285         sdi->inst_type = -1;
00286         sdi->vendor = vendor ? g_strdup(vendor) : NULL;
00287         sdi->model = model ? g_strdup(model) : NULL;
00288         sdi->version = version ? g_strdup(version) : NULL;
00289         sdi->channels = NULL;
00290         sdi->channel_groups = NULL;
00291         sdi->conn = NULL;
00292         sdi->priv = NULL;
00293 
00294         return sdi;
00295 }
00296 
00297 /** @private
00298  *  Free device instance struct created by sr_dev_inst().
00299  *  @param sdi  struct* to free.
00300  */
00301 SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
00302 {
00303         struct sr_channel *ch;
00304         GSList *l;
00305 
00306         for (l = sdi->channels; l; l = l->next) {
00307                 ch = l->data;
00308                 g_free(ch->name);
00309                 g_free(ch->trigger);
00310                 g_free(ch);
00311         }
00312         g_slist_free(sdi->channels);
00313 
00314         if (sdi->channel_groups)
00315                 g_slist_free(sdi->channel_groups);
00316 
00317         g_free(sdi->vendor);
00318         g_free(sdi->model);
00319         g_free(sdi->version);
00320         g_free(sdi);
00321 }
00322 
00323 #ifdef HAVE_LIBUSB_1_0
00324 
00325 /** @private
00326  *  Allocate and init struct for USB device instance.
00327  *  @param[in]  bus @copydoc sr_usb_dev_inst::bus
00328  *  @param[in]  address @copydoc sr_usb_dev_inst::address
00329  *  @param[in]  hdl @copydoc sr_usb_dev_inst::devhdl
00330  *
00331  *  @retval NULL Error
00332  *  @retval other struct sr_usb_dev_inst * for USB device instance.
00333  */
00334 SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus,
00335                         uint8_t address, struct libusb_device_handle *hdl)
00336 {
00337         struct sr_usb_dev_inst *udi;
00338 
00339         if (!(udi = g_try_malloc(sizeof(struct sr_usb_dev_inst)))) {
00340                 sr_err("USB device instance malloc failed.");
00341                 return NULL;
00342         }
00343 
00344         udi->bus = bus;
00345         udi->address = address;
00346         udi->devhdl = hdl;
00347 
00348         return udi;
00349 }
00350 
00351 /** @private
00352  *  Free struct * allocated by sr_usb_dev_inst().
00353  *  @param usb  struct* to free. Must not be NULL.
00354  */
00355 SR_PRIV void sr_usb_dev_inst_free(struct sr_usb_dev_inst *usb)
00356 {
00357         g_free(usb);
00358 }
00359 
00360 #endif
00361 
00362 #ifdef HAVE_LIBSERIALPORT
00363 
00364 /**
00365  * @private
00366  *
00367  * Both parameters are copied to newly allocated strings, and freed
00368  * automatically by sr_serial_dev_inst_free().
00369  *
00370  * @param[in] port OS-specific serial port specification. Examples:
00371  *                 "/dev/ttyUSB0", "/dev/ttyACM1", "/dev/tty.Modem-0", "COM1".
00372  * @param[in] serialcomm A serial communication parameters string, in the form
00373  *              of <speed>/<data bits><parity><stopbits>, for example
00374  *              "9600/8n1" or "600/7o2". This is an optional parameter;
00375  *              it may be filled in later.
00376  *
00377  * @return A pointer to a newly initialized struct sr_serial_dev_inst,
00378  *         or NULL on error.
00379  */
00380 SR_PRIV struct sr_serial_dev_inst *sr_serial_dev_inst_new(const char *port,
00381                 const char *serialcomm)
00382 {
00383         struct sr_serial_dev_inst *serial;
00384 
00385         if (!port) {
00386                 sr_err("Serial port required.");
00387                 return NULL;
00388         }
00389 
00390         if (!(serial = g_try_malloc0(sizeof(struct sr_serial_dev_inst)))) {
00391                 sr_err("Serial device instance malloc failed.");
00392                 return NULL;
00393         }
00394 
00395         serial->port = g_strdup(port);
00396         if (serialcomm)
00397                 serial->serialcomm = g_strdup(serialcomm);
00398 
00399         return serial;
00400 }
00401 
00402 /** @private
00403  *  Free struct sr_serial_dev_inst * allocated by sr_serial_dev_inst().
00404  *  @param serial   struct sr_serial_dev_inst * to free. Must not be NULL.
00405  */
00406 SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial)
00407 {
00408         g_free(serial->port);
00409         g_free(serial->serialcomm);
00410         g_free(serial);
00411 }
00412 #endif
00413 
00414 /** @private */
00415 SR_PRIV struct sr_usbtmc_dev_inst *sr_usbtmc_dev_inst_new(const char *device)
00416 {
00417         struct sr_usbtmc_dev_inst *usbtmc;
00418 
00419         if (!device) {
00420                 sr_err("Device name required.");
00421                 return NULL;
00422         }
00423 
00424         if (!(usbtmc = g_try_malloc0(sizeof(struct sr_usbtmc_dev_inst)))) {
00425                 sr_err("USBTMC device instance malloc failed.");
00426                 return NULL;
00427         }
00428 
00429         usbtmc->device = g_strdup(device);
00430         usbtmc->fd = -1;
00431 
00432         return usbtmc;
00433 }
00434 
00435 /** @private */
00436 SR_PRIV void sr_usbtmc_dev_inst_free(struct sr_usbtmc_dev_inst *usbtmc)
00437 {
00438         g_free(usbtmc->device);
00439         g_free(usbtmc);
00440 }
00441 
00442 /**
00443  * Get the list of devices/instances of the specified driver.
00444  *
00445  * @param driver The driver to use. Must not be NULL.
00446  *
00447  * @return The list of devices/instances of this driver, or NULL upon errors
00448  *         or if the list is empty.
00449  *
00450  * @since 0.2.0
00451  */
00452 SR_API GSList *sr_dev_list(const struct sr_dev_driver *driver)
00453 {
00454         if (driver && driver->dev_list)
00455                 return driver->dev_list();
00456         else
00457                 return NULL;
00458 }
00459 
00460 /**
00461  * Clear the list of device instances a driver knows about.
00462  *
00463  * @param driver The driver to use. This must be a pointer to one of
00464  *               the entries returned by sr_driver_list(). Must not be NULL.
00465  *
00466  * @retval SR_OK Success
00467  * @retval SR_ERR_ARG Invalid driver
00468  *
00469  * @since 0.2.0
00470  */
00471 SR_API int sr_dev_clear(const struct sr_dev_driver *driver)
00472 {
00473         int ret;
00474 
00475         if (!driver) {
00476                 sr_err("Invalid driver.");
00477                 return SR_ERR_ARG;
00478         }
00479 
00480         if (driver->dev_clear)
00481                 ret = driver->dev_clear();
00482         else
00483                 ret = std_dev_clear(driver, NULL);
00484 
00485         return ret;
00486 }
00487 
00488 /**
00489  * Open the specified device.
00490  *
00491  * @param sdi Device instance to use. Must not be NULL.
00492  *
00493  * @return SR_OK upon success, a negative error code upon errors.
00494  *
00495  * @since 0.2.0
00496  */
00497 SR_API int sr_dev_open(struct sr_dev_inst *sdi)
00498 {
00499         int ret;
00500 
00501         if (!sdi || !sdi->driver || !sdi->driver->dev_open)
00502                 return SR_ERR;
00503 
00504         ret = sdi->driver->dev_open(sdi);
00505 
00506         return ret;
00507 }
00508 
00509 /**
00510  * Close the specified device.
00511  *
00512  * @param sdi Device instance to use. Must not be NULL.
00513  *
00514  * @return SR_OK upon success, a negative error code upon errors.
00515  *
00516  * @since 0.2.0
00517  */
00518 SR_API int sr_dev_close(struct sr_dev_inst *sdi)
00519 {
00520         int ret;
00521 
00522         if (!sdi || !sdi->driver || !sdi->driver->dev_close)
00523                 return SR_ERR;
00524 
00525         ret = sdi->driver->dev_close(sdi);
00526 
00527         return ret;
00528 }
00529 
00530 /** @} */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines