]> sigrok.org Git - libsigrok.git/blobdiff - src/scpi/scpi.c
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / src / scpi / scpi.c
index ec0ddc555c73b37b6cdec6799ecf9573fee3534c..8d24ceea97e29c88de244fae03600a8cf52b6507 100644 (file)
@@ -38,6 +38,7 @@ static const char *scpi_vendors[][2] = {
        { "Keysight Technologies", "Keysight" },
        { "PHILIPS", "Philips" },
        { "RIGOL TECHNOLOGIES", "Rigol" },
+       { "Siglent Technologies", "Siglent" },
 };
 
 /**
@@ -315,33 +316,32 @@ SR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options,
 {
        GSList *resources, *l, *devices;
        struct sr_dev_inst *sdi;
-       const char *resource = NULL;
-       const char *serialcomm = NULL;
+       const char *resource, *conn;
+       const char *serialcomm, *comm;
        gchar **res;
        unsigned i;
 
-       for (l = options; l; l = l->next) {
-               struct sr_config *src = l->data;
-               switch (src->key) {
-               case SR_CONF_CONN:
-                       resource = g_variant_get_string(src->data, NULL);
-                       break;
-               case SR_CONF_SERIALCOMM:
-                       serialcomm = g_variant_get_string(src->data, NULL);
-                       break;
-               }
-       }
+       resource = NULL;
+       serialcomm = NULL;
+       (void)sr_serial_extract_options(options, &resource, &serialcomm);
 
        devices = NULL;
        for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) {
-               if ((resource && strcmp(resource, scpi_devs[i]->prefix))
-                   || !scpi_devs[i]->scan)
+               if (resource && strcmp(resource, scpi_devs[i]->prefix) != 0)
+                       continue;
+               if (!scpi_devs[i]->scan)
                        continue;
                resources = scpi_devs[i]->scan(drvc);
                for (l = resources; l; l = l->next) {
                        res = g_strsplit(l->data, ":", 2);
-                       if (res[0] && (sdi = sr_scpi_scan_resource(drvc, res[0],
-                                      serialcomm ? serialcomm : res[1], probe_device))) {
+                       if (!res[0]) {
+                               g_strfreev(res);
+                               continue;
+                       }
+                       conn = res[0];
+                       comm = serialcomm ? : res[1];
+                       sdi = sr_scpi_scan_resource(drvc, conn, comm, probe_device);
+                       if (sdi) {
                                devices = g_slist_append(devices, sdi);
                                sdi->connection_id = g_strdup(l->data);
                        }
@@ -1038,7 +1038,29 @@ SR_PRIV int sr_scpi_get_block(struct sr_scpi_dev_inst *scpi,
        buf[0] = response->str[1];
        buf[1] = '\0';
        ret = sr_atol(buf, &llen);
-       if ((ret != SR_OK) || (llen == 0)) {
+       /*
+        * The form "#0..." is legal, and does not mean "empty response",
+        * but means that the number of data bytes is not known (or was
+        * not communicated) at this time. Instead the block ends at an
+        * "END MESSAGE" termination sequence. Which translates to active
+        * EOI while a text line termination is sent (CR or LF, and this
+        * text line termination is not part of the block's data value).
+        * Since this kind of #0... response is considered rare, and
+        * depends on specific support in physical transports underneath
+        * the SCPI layer, let's flag the condition and bail out with an
+        * error here, until it's found to be a genuine issue in the field.
+        *
+        * The SCPI 1999.0 specification (see page 220 and following in
+        * the "HCOPy" description) references IEEE 488.2, especially
+        * section 8.7.9 for DEFINITE LENGTH and section 8.7.10 for
+        * INDEFINITE LENGTH ARBITRARY BLOCK RESPONSE DATA. The latter
+        * with a leading "#0" length and a trailing "NL^END" marker.
+        */
+       if (ret == SR_OK && !llen) {
+               sr_err("unsupported INDEFINITE LENGTH ARBITRARY BLOCK RESPONSE");
+               ret = SR_ERR_NA;
+       }
+       if (ret != SR_OK) {
                g_mutex_unlock(&scpi->scpi_mutex);
                g_string_free(response, TRUE);
                return ret;