]> sigrok.org Git - libsigrok.git/blame - src/scpi/scpi.c
scpi: Synchronize read, write and write+read operations.
[libsigrok.git] / src / scpi / scpi.c
CommitLineData
7b9d7320
DJ
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
fd20e59c 5 * Copyright (C) 2015 Bert Vermeulen <bert@biot.com>
7b9d7320
DJ
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
6ec6c43b 21#include <config.h>
7b9d7320
DJ
22#include <glib.h>
23#include <string.h>
c1aae900 24#include <libsigrok/libsigrok.h>
515ab088 25#include "libsigrok-internal.h"
5a1afc09 26#include "scpi.h"
7b9d7320 27
3544f848 28#define LOG_PREFIX "scpi"
7b9d7320
DJ
29
30#define SCPI_READ_RETRIES 100
1a46cc62 31#define SCPI_READ_RETRY_TIMEOUT_US (10 * 1000)
7b9d7320 32
fd20e59c
FS
33static const char *scpi_vendors[][2] = {
34 { "HEWLETT-PACKARD", "HP" },
35 { "Agilent Technologies", "Agilent" },
36 { "RIGOL TECHNOLOGIES", "Rigol" },
37 { "PHILIPS", "Philips" },
38 { "CHROMA", "Chroma" },
39 { "Chroma ATE", "Chroma" },
40};
41
aa1e3b40
DJ
42/**
43 * Parse a string representation of a boolean-like value into a gboolean.
44 * Similar to sr_parse_boolstring but rejects strings which do not represent
45 * a boolean-like value.
46 *
47 * @param str String to convert.
48 * @param ret Pointer to a gboolean where the result of the conversion will be
49 * stored.
50 *
51 * @return SR_OK on success, SR_ERR on failure.
52 */
d5976d8b 53static int parse_strict_bool(const char *str, gboolean *ret)
aa1e3b40
DJ
54{
55 if (!str)
56 return SR_ERR_ARG;
57
58 if (!g_strcmp0(str, "1") ||
59 !g_ascii_strncasecmp(str, "y", 1) ||
60 !g_ascii_strncasecmp(str, "t", 1) ||
61 !g_ascii_strncasecmp(str, "yes", 3) ||
62 !g_ascii_strncasecmp(str, "true", 4) ||
63 !g_ascii_strncasecmp(str, "on", 2)) {
aa1e3b40
DJ
64 *ret = TRUE;
65 return SR_OK;
aa1e3b40
DJ
66 } else if (!g_strcmp0(str, "0") ||
67 !g_ascii_strncasecmp(str, "n", 1) ||
68 !g_ascii_strncasecmp(str, "f", 1) ||
69 !g_ascii_strncasecmp(str, "no", 2) ||
70 !g_ascii_strncasecmp(str, "false", 5) ||
71 !g_ascii_strncasecmp(str, "off", 3)) {
aa1e3b40
DJ
72 *ret = FALSE;
73 return SR_OK;
74 }
75
76 return SR_ERR;
77}
78
f754c146 79SR_PRIV extern const struct sr_scpi_dev_inst scpi_serial_dev;
104ed125
AJ
80SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_raw_dev;
81SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_rigol_dev;
20ed3cee 82SR_PRIV extern const struct sr_scpi_dev_inst scpi_usbtmc_libusb_dev;
f754c146 83SR_PRIV extern const struct sr_scpi_dev_inst scpi_vxi_dev;
1fb2312f 84SR_PRIV extern const struct sr_scpi_dev_inst scpi_visa_dev;
7343ad1e 85SR_PRIV extern const struct sr_scpi_dev_inst scpi_libgpib_dev;
f754c146
AJ
86
87static const struct sr_scpi_dev_inst *scpi_devs[] = {
104ed125
AJ
88 &scpi_tcp_raw_dev,
89 &scpi_tcp_rigol_dev,
20ed3cee
AJ
90#ifdef HAVE_LIBUSB_1_0
91 &scpi_usbtmc_libusb_dev,
92#endif
613c1108 93#if HAVE_RPC
f754c146
AJ
94 &scpi_vxi_dev,
95#endif
1fb2312f
ML
96#ifdef HAVE_LIBREVISA
97 &scpi_visa_dev,
98#endif
bb2a4ed4 99#ifdef HAVE_LIBGPIB
7343ad1e 100 &scpi_libgpib_dev,
bb2a4ed4 101#endif
f754c146 102#ifdef HAVE_LIBSERIALPORT
d9251a2c 103 &scpi_serial_dev, /* Must be last as it matches any resource. */
f754c146
AJ
104#endif
105};
106
85b69c2b 107static struct sr_dev_inst *sr_scpi_scan_resource(struct drv_context *drvc,
b541f837
AJ
108 const char *resource, const char *serialcomm,
109 struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))
110{
111 struct sr_scpi_dev_inst *scpi;
112 struct sr_dev_inst *sdi;
113
114 if (!(scpi = scpi_dev_inst_new(drvc, resource, serialcomm)))
115 return NULL;
116
117 if (sr_scpi_open(scpi) != SR_OK) {
118 sr_info("Couldn't open SCPI device.");
119 sr_scpi_free(scpi);
120 return NULL;
121 };
122
a00106b7 123 sdi = probe_device(scpi);
b541f837
AJ
124
125 sr_scpi_close(scpi);
a00106b7
ML
126
127 if (sdi)
128 sdi->status = SR_ST_INACTIVE;
129 else
130 sr_scpi_free(scpi);
131
132 return sdi;
b541f837
AJ
133}
134
fd20e59c
FS
135/**
136 * Send a SCPI command with a variadic argument list without mutex.
137 *
138 * @param scpi Previously initialized SCPI device structure.
139 * @param format Format string.
140 * @param args Argument list.
141 *
142 * @return SR_OK on success, SR_ERR on failure.
143 */
144static int scpi_send_variadic(struct sr_scpi_dev_inst *scpi,
145 const char *format, va_list args)
146{
147 va_list args_copy;
148 char *buf;
149 int len, ret;
150
151 /* Get length of buffer required. */
152 va_copy(args_copy, args);
153 len = vsnprintf(NULL, 0, format, args_copy);
154 va_end(args_copy);
155
156 /* Allocate buffer and write out command. */
157 buf = g_malloc0(len + 2);
158 vsprintf(buf, format, args);
159 if (buf[len - 1] != '\n')
160 buf[len] = '\n';
161
162 /* Send command. */
163 ret = scpi->send(scpi->priv, buf);
164
165 /* Free command buffer. */
166 g_free(buf);
167
168 return ret;
169}
170
171/**
172 * Send a SCPI command without mutex.
173 *
174 * @param scpi Previously initialized SCPI device structure.
175 * @param format Format string, to be followed by any necessary arguments.
176 *
177 * @return SR_OK on success, SR_ERR on failure.
178 */
179static int scpi_send(struct sr_scpi_dev_inst *scpi, const char *format,
180 va_list args)
181{
182 return scpi_send_variadic(scpi, format, args);
183}
184
185/**
186 * Send data to SCPI device without mutex.
187 *
188 * TODO: This is only implemented in TcpRaw, but never used.
189 * TODO: Use Mutex at all?
190 *
191 * @param scpi Previously initialised SCPI device structure.
192 * @param buf Buffer with data to send.
193 * @param len Number of bytes to send.
194 *
195 * @return Number of bytes read, or SR_ERR upon failure.
196 */
197static int scpi_write_data(struct sr_scpi_dev_inst *scpi, char *buf, int maxlen)
198{
199 return scpi->write_data(scpi->priv, buf, maxlen);
200}
201
202/**
203 * Read part of a response from SCPI device without mutex.
204 *
205 * @param scpi Previously initialised SCPI device structure.
206 * @param buf Buffer to store result.
207 * @param maxlen Maximum number of bytes to read.
208 *
209 * @return Number of bytes read, or SR_ERR upon failure.
210 */
211static int scpi_read_data(struct sr_scpi_dev_inst *scpi, char *buf, int maxlen)
212{
213 return scpi->read_data(scpi->priv, buf, maxlen);
214}
215
216/**
217 * Do a non-blocking read of up to the allocated length, and
218 * check if a timeout has occured, without mutex.
219 *
220 * @param scpi Previously initialised SCPI device structure.
221 * @param response Buffer to which the response is appended.
222 * @param abs_timeout_us Absolute timeout in microseconds
223 *
224 * @return read length on success, SR_ERR* on failure.
225 */
226static int scpi_read_response(struct sr_scpi_dev_inst *scpi,
227 GString *response, gint64 abs_timeout_us)
228{
229 int len, space;
230
231 space = response->allocated_len - response->len;
232 len = scpi->read_data(scpi->priv, &response->str[response->len], space);
233
234 if (len < 0) {
235 sr_err("Incompletely read SCPI response.");
236 return SR_ERR;
237 }
238
239 if (len > 0) {
240 g_string_set_size(response, response->len + len);
241 return len;
242 }
243
244 if (g_get_monotonic_time() > abs_timeout_us) {
245 sr_err("Timed out waiting for SCPI response.");
246 return SR_ERR_TIMEOUT;
247 }
248
249 return 0;
250}
251
252/**
253 * Send a SCPI command, receive the reply and store the reply in
254 * scpi_response, without mutex.
255 *
256 * @param scpi Previously initialised SCPI device structure.
257 * @param command The SCPI command to send to the device.
258 * @param scpi_response Pointer where to store the SCPI response.
259 *
260 * @return SR_OK on success, SR_ERR on failure.
261 */
262static int scpi_get_data(struct sr_scpi_dev_inst *scpi,
263 const char *command, GString **scpi_response)
264{
265 int ret;
266 GString *response;
267 int space;
268 gint64 timeout;
269 va_list empty_va_list;
270
271 /* Optionally send caller provided command. */
272 if (command) {
273 if (scpi_send(scpi, command, empty_va_list) != SR_OK)
274 return SR_ERR;
275 }
276
277 /* Initiate SCPI read operation. */
278 if (sr_scpi_read_begin(scpi) != SR_OK)
279 return SR_ERR;
280
281 /* Keep reading until completion or until timeout. */
282 timeout = g_get_monotonic_time() + scpi->read_timeout_us;
283
284 response = *scpi_response;
285
286 while (!sr_scpi_read_complete(scpi)) {
287 /* Resize the buffer when free space drops below a threshold. */
288 space = response->allocated_len - response->len;
289 if (space < 128) {
290 int oldlen = response->len;
291 g_string_set_size(response, oldlen + 1024);
292 g_string_set_size(response, oldlen);
293 }
294
295 /* Read another chunk of the response. */
296 ret = scpi_read_response(scpi, response, timeout);
297
298 if (ret < 0)
299 return ret;
300 if (ret > 0)
301 timeout = g_get_monotonic_time() + scpi->read_timeout_us;
302 }
303
304 return SR_OK;
305}
306
b541f837
AJ
307SR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options,
308 struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))
309{
85b69c2b
BV
310 GSList *resources, *l, *devices;
311 struct sr_dev_inst *sdi;
b541f837
AJ
312 const char *resource = NULL;
313 const char *serialcomm = NULL;
314 gchar **res;
315 unsigned i;
316
317 for (l = options; l; l = l->next) {
318 struct sr_config *src = l->data;
319 switch (src->key) {
320 case SR_CONF_CONN:
321 resource = g_variant_get_string(src->data, NULL);
322 break;
323 case SR_CONF_SERIALCOMM:
324 serialcomm = g_variant_get_string(src->data, NULL);
325 break;
326 }
327 }
328
85b69c2b 329 devices = NULL;
b541f837
AJ
330 for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) {
331 if ((resource && strcmp(resource, scpi_devs[i]->prefix))
332 || !scpi_devs[i]->scan)
333 continue;
334 resources = scpi_devs[i]->scan(drvc);
335 for (l = resources; l; l = l->next) {
336 res = g_strsplit(l->data, ":", 2);
85b69c2b 337 if (res[0] && (sdi = sr_scpi_scan_resource(drvc, res[0],
b2c02b07 338 serialcomm ? serialcomm : res[1], probe_device))) {
85b69c2b 339 devices = g_slist_append(devices, sdi);
b2c02b07
SA
340 sdi->connection_id = g_strdup(l->data);
341 }
b541f837
AJ
342 g_strfreev(res);
343 }
344 g_slist_free_full(resources, g_free);
345 }
346
85b69c2b
BV
347 if (!devices && resource) {
348 sdi = sr_scpi_scan_resource(drvc, resource, serialcomm, probe_device);
cfd8ec53
BV
349 if (sdi)
350 devices = g_slist_append(NULL, sdi);
85b69c2b 351 }
b541f837
AJ
352
353 /* Tack a copy of the newly found devices onto the driver list. */
354 if (devices)
85b69c2b 355 drvc->instances = g_slist_concat(drvc->instances, g_slist_copy(devices));
b541f837
AJ
356
357 return devices;
358}
359
17bdda58
AJ
360SR_PRIV struct sr_scpi_dev_inst *scpi_dev_inst_new(struct drv_context *drvc,
361 const char *resource, const char *serialcomm)
c3515cea
AJ
362{
363 struct sr_scpi_dev_inst *scpi = NULL;
f754c146
AJ
364 const struct sr_scpi_dev_inst *scpi_dev;
365 gchar **params;
366 unsigned i;
c3515cea 367
f754c146
AJ
368 for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) {
369 scpi_dev = scpi_devs[i];
370 if (!strncmp(resource, scpi_dev->prefix, strlen(scpi_dev->prefix))) {
371 sr_dbg("Opening %s device %s.", scpi_dev->name, resource);
372 scpi = g_malloc(sizeof(*scpi));
373 *scpi = *scpi_dev;
374 scpi->priv = g_malloc0(scpi->priv_size);
37ef582d 375 scpi->read_timeout_us = 1000 * 1000;
f754c146 376 params = g_strsplit(resource, "/", 0);
17bdda58 377 if (scpi->dev_inst_new(scpi->priv, drvc, resource,
f754c146
AJ
378 params, serialcomm) != SR_OK) {
379 sr_scpi_free(scpi);
380 scpi = NULL;
381 }
382 g_strfreev(params);
383 break;
384 }
c3515cea 385 }
f754c146 386
c3515cea
AJ
387 return scpi;
388}
389
23f43dff
ML
390/**
391 * Open SCPI device.
392 *
393 * @param scpi Previously initialized SCPI device structure.
394 *
395 * @return SR_OK on success, SR_ERR on failure.
396 */
397SR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi)
398{
fd20e59c
FS
399 g_mutex_init(&scpi->scpi_mutex);
400
04229f7b 401 return scpi->open(scpi);
23f43dff
ML
402}
403
404/**
405 * Add an event source for an SCPI device.
406 *
7efe889e 407 * @param session The session to add the event source to.
23f43dff
ML
408 * @param scpi Previously initialized SCPI device structure.
409 * @param events Events to check for.
410 * @param timeout Max time to wait before the callback is called, ignored if 0.
411 * @param cb Callback function to add. Must not be NULL.
412 * @param cb_data Data for the callback function. Can be NULL.
413 *
414 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
415 * SR_ERR_MALLOC upon memory allocation errors.
416 */
102f1239
BV
417SR_PRIV int sr_scpi_source_add(struct sr_session *session,
418 struct sr_scpi_dev_inst *scpi, int events, int timeout,
419 sr_receive_data_callback cb, void *cb_data)
23f43dff 420{
102f1239 421 return scpi->source_add(session, scpi->priv, events, timeout, cb, cb_data);
23f43dff
ML
422}
423
424/**
425 * Remove event source for an SCPI device.
426 *
7efe889e 427 * @param session The session to remove the event source from.
23f43dff
ML
428 * @param scpi Previously initialized SCPI device structure.
429 *
430 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
431 * SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon
432 * internal errors.
433 */
102f1239
BV
434SR_PRIV int sr_scpi_source_remove(struct sr_session *session,
435 struct sr_scpi_dev_inst *scpi)
23f43dff 436{
102f1239 437 return scpi->source_remove(session, scpi->priv);
23f43dff
ML
438}
439
7b9d7320
DJ
440/**
441 * Send a SCPI command.
442 *
23f43dff 443 * @param scpi Previously initialized SCPI device structure.
504f40a5 444 * @param format Format string, to be followed by any necessary arguments.
7b9d7320
DJ
445 *
446 * @return SR_OK on success, SR_ERR on failure.
447 */
23f43dff 448SR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi,
504f40a5 449 const char *format, ...)
7b9d7320 450{
87c41083
ML
451 va_list args;
452 int ret;
453
454 va_start(args, format);
fd20e59c
FS
455 g_mutex_lock(&scpi->scpi_mutex);
456 ret = scpi_send_variadic(scpi, format, args);
457 g_mutex_unlock(&scpi->scpi_mutex);
87c41083
ML
458 va_end(args);
459
460 return ret;
461}
462
463/**
464 * Send a SCPI command with a variadic argument list.
465 *
466 * @param scpi Previously initialized SCPI device structure.
467 * @param format Format string.
468 * @param args Argument list.
469 *
470 * @return SR_OK on success, SR_ERR on failure.
471 */
472SR_PRIV int sr_scpi_send_variadic(struct sr_scpi_dev_inst *scpi,
473 const char *format, va_list args)
474{
fd20e59c 475 int ret;
504f40a5 476
fd20e59c
FS
477 g_mutex_lock(&scpi->scpi_mutex);
478 ret = scpi_send_variadic(scpi, format, args);
479 g_mutex_unlock(&scpi->scpi_mutex);
504f40a5
ML
480
481 return ret;
23f43dff 482}
7b9d7320 483
23f43dff 484/**
05c644ea 485 * Begin receiving an SCPI reply.
23f43dff
ML
486 *
487 * @param scpi Previously initialised SCPI device structure.
23f43dff 488 *
05c644ea 489 * @return SR_OK on success, SR_ERR on failure.
23f43dff 490 */
05c644ea 491SR_PRIV int sr_scpi_read_begin(struct sr_scpi_dev_inst *scpi)
23f43dff 492{
05c644ea 493 return scpi->read_begin(scpi->priv);
23f43dff 494}
7b9d7320 495
a1ff9c18
ML
496/**
497 * Read part of a response from SCPI device.
498 *
499 * @param scpi Previously initialised SCPI device structure.
500 * @param buf Buffer to store result.
501 * @param maxlen Maximum number of bytes to read.
502 *
503 * @return Number of bytes read, or SR_ERR upon failure.
504 */
05c644ea 505SR_PRIV int sr_scpi_read_data(struct sr_scpi_dev_inst *scpi,
a1ff9c18
ML
506 char *buf, int maxlen)
507{
fd20e59c
FS
508 int ret;
509
510 g_mutex_lock(&scpi->scpi_mutex);
511 ret = scpi_read_data(scpi, buf, maxlen);
512 g_mutex_unlock(&scpi->scpi_mutex);
513
514 return ret;
05c644ea
ML
515}
516
b6be55ce
SS
517/**
518 * Send data to SCPI device.
519 *
fd20e59c
FS
520 * TODO: This is only implemented in TcpRaw, but never used.
521 * TODO: Use Mutex at all?
522 *
b6be55ce
SS
523 * @param scpi Previously initialised SCPI device structure.
524 * @param buf Buffer with data to send.
525 * @param len Number of bytes to send.
526 *
527 * @return Number of bytes read, or SR_ERR upon failure.
528 */
529SR_PRIV int sr_scpi_write_data(struct sr_scpi_dev_inst *scpi,
530 char *buf, int maxlen)
531{
fd20e59c
FS
532 int ret;
533
534 g_mutex_lock(&scpi->scpi_mutex);
535 ret = scpi_write_data(scpi, buf, maxlen);
536 g_mutex_unlock(&scpi->scpi_mutex);
537
538 return ret;
b6be55ce
SS
539}
540
05c644ea
ML
541/**
542 * Check whether a complete SCPI response has been received.
543 *
544 * @param scpi Previously initialised SCPI device structure.
545 *
546 * @return 1 if complete, 0 otherwise.
547 */
548SR_PRIV int sr_scpi_read_complete(struct sr_scpi_dev_inst *scpi)
549{
550 return scpi->read_complete(scpi->priv);
a1ff9c18
ML
551}
552
23f43dff
ML
553/**
554 * Close SCPI device.
555 *
556 * @param scpi Previously initialized SCPI device structure.
557 *
558 * @return SR_OK on success, SR_ERR on failure.
559 */
560SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi)
561{
fd20e59c
FS
562 int ret;
563
564 g_mutex_lock(&scpi->scpi_mutex);
565 ret = scpi->close(scpi);
566 g_mutex_unlock(&scpi->scpi_mutex);
567 g_mutex_clear(&scpi->scpi_mutex);
568
569 return ret;
23f43dff 570}
7b9d7320 571
23f43dff
ML
572/**
573 * Free SCPI device.
574 *
81568546
UH
575 * @param scpi Previously initialized SCPI device structure. If NULL,
576 * this function does nothing.
23f43dff
ML
577 */
578SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi)
579{
81568546
UH
580 if (!scpi)
581 return;
582
23f43dff 583 scpi->free(scpi->priv);
f754c146 584 g_free(scpi->priv);
23f43dff 585 g_free(scpi);
7b9d7320
DJ
586}
587
588/**
589 * Send a SCPI command, receive the reply and store the reply in scpi_response.
590 *
23f43dff 591 * @param scpi Previously initialised SCPI device structure.
7b9d7320 592 * @param command The SCPI command to send to the device (can be NULL).
d5976d8b 593 * @param scpi_response Pointer where to store the SCPI response.
7b9d7320 594 *
c0d25779 595 * @return SR_OK on success, SR_ERR* on failure.
7b9d7320 596 */
23f43dff 597SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
d5976d8b 598 const char *command, char **scpi_response)
7b9d7320 599{
ff01b0ea
SB
600 GString *response;
601 response = g_string_sized_new(1024);
602
603 if (sr_scpi_get_data(scpi, command, &response) != SR_OK) {
604 if (response)
605 g_string_free(response, TRUE);
606 return SR_ERR;
607 }
608
609 /* Get rid of trailing linefeed if present */
610 if (response->len >= 1 && response->str[response->len - 1] == '\n')
611 g_string_truncate(response, response->len - 1);
612
613 /* Get rid of trailing carriage return if present */
614 if (response->len >= 1 && response->str[response->len - 1] == '\r')
615 g_string_truncate(response, response->len - 1);
616
617 sr_spew("Got response: '%.70s', length %" G_GSIZE_FORMAT ".",
618 response->str, response->len);
619
620 *scpi_response = g_string_free(response, FALSE);
621
622 return SR_OK;
623}
624
d64be25b
SB
625/**
626 * Do a non-blocking read of up to the allocated length, and
627 * check if a timeout has occured.
628 *
629 * @param scpi Previously initialised SCPI device structure.
630 * @param response Buffer to which the response is appended.
631 * @param abs_timeout_us Absolute timeout in microseconds
632 *
633 * @return read length on success, SR_ERR* on failure.
634 */
635SR_PRIV int sr_scpi_read_response(struct sr_scpi_dev_inst *scpi,
636 GString *response, gint64 abs_timeout_us)
637{
fd20e59c 638 int ret;
d64be25b 639
fd20e59c
FS
640 g_mutex_lock(&scpi->scpi_mutex);
641 ret = scpi_read_response(scpi, response, abs_timeout_us);
642 g_mutex_unlock(&scpi->scpi_mutex);
d64be25b 643
fd20e59c 644 return ret;
d64be25b
SB
645}
646
ff01b0ea
SB
647SR_PRIV int sr_scpi_get_data(struct sr_scpi_dev_inst *scpi,
648 const char *command, GString **scpi_response)
649{
d64be25b 650 int ret;
37ef582d 651
fd20e59c
FS
652 g_mutex_lock(&scpi->scpi_mutex);
653 ret = scpi_get_data(scpi, command, scpi_response);
654 g_mutex_unlock(&scpi->scpi_mutex);
05c644ea 655
fd20e59c 656 return ret;
d730f70e
DJ
657}
658
659/**
660 * Send a SCPI command, read the reply, parse it as a bool value and store the
661 * result in scpi_response.
662 *
23f43dff 663 * @param scpi Previously initialised SCPI device structure.
d730f70e
DJ
664 * @param command The SCPI command to send to the device (can be NULL).
665 * @param scpi_response Pointer where to store the parsed result.
666 *
c0d25779 667 * @return SR_OK on success, SR_ERR* on failure.
d730f70e 668 */
23f43dff 669SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
d730f70e
DJ
670 const char *command, gboolean *scpi_response)
671{
672 int ret;
673 char *response;
674
675 response = NULL;
676
c0d25779
BV
677 ret = sr_scpi_get_string(scpi, command, &response);
678 if (ret != SR_OK && !response)
679 return ret;
d730f70e 680
d5976d8b 681 if (parse_strict_bool(response, scpi_response) == SR_OK)
d730f70e
DJ
682 ret = SR_OK;
683 else
c0d25779 684 ret = SR_ERR_DATA;
d730f70e
DJ
685
686 g_free(response);
687
688 return ret;
689}
690
691/**
692 * Send a SCPI command, read the reply, parse it as an integer and store the
693 * result in scpi_response.
694 *
23f43dff 695 * @param scpi Previously initialised SCPI device structure.
d730f70e
DJ
696 * @param command The SCPI command to send to the device (can be NULL).
697 * @param scpi_response Pointer where to store the parsed result.
698 *
c0d25779 699 * @return SR_OK on success, SR_ERR* on failure.
d730f70e 700 */
23f43dff 701SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi,
d5976d8b 702 const char *command, int *scpi_response)
d730f70e
DJ
703{
704 int ret;
705 char *response;
706
707 response = NULL;
708
c0d25779
BV
709 ret = sr_scpi_get_string(scpi, command, &response);
710 if (ret != SR_OK && !response)
711 return ret;
d730f70e
DJ
712
713 if (sr_atoi(response, scpi_response) == SR_OK)
714 ret = SR_OK;
715 else
c0d25779 716 ret = SR_ERR_DATA;
d730f70e
DJ
717
718 g_free(response);
719
720 return ret;
721}
722
723/**
724 * Send a SCPI command, read the reply, parse it as a float and store the
725 * result in scpi_response.
726 *
23f43dff 727 * @param scpi Previously initialised SCPI device structure.
d730f70e
DJ
728 * @param command The SCPI command to send to the device (can be NULL).
729 * @param scpi_response Pointer where to store the parsed result.
730 *
c0d25779 731 * @return SR_OK on success, SR_ERR* on failure.
d730f70e 732 */
23f43dff 733SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
d730f70e
DJ
734 const char *command, float *scpi_response)
735{
736 int ret;
737 char *response;
738
739 response = NULL;
740
c0d25779
BV
741 ret = sr_scpi_get_string(scpi, command, &response);
742 if (ret != SR_OK && !response)
743 return ret;
d730f70e 744
13dbd151 745 if (sr_atof_ascii(response, scpi_response) == SR_OK)
d730f70e
DJ
746 ret = SR_OK;
747 else
c0d25779 748 ret = SR_ERR_DATA;
d730f70e
DJ
749
750 g_free(response);
751
752 return ret;
753}
754
755/**
756 * Send a SCPI command, read the reply, parse it as a double and store the
757 * result in scpi_response.
758 *
23f43dff 759 * @param scpi Previously initialised SCPI device structure.
d730f70e
DJ
760 * @param command The SCPI command to send to the device (can be NULL).
761 * @param scpi_response Pointer where to store the parsed result.
762 *
c0d25779 763 * @return SR_OK on success, SR_ERR* on failure.
d730f70e 764 */
23f43dff 765SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
d5976d8b 766 const char *command, double *scpi_response)
d730f70e
DJ
767{
768 int ret;
769 char *response;
770
771 response = NULL;
772
c0d25779
BV
773 ret = sr_scpi_get_string(scpi, command, &response);
774 if (ret != SR_OK && !response)
775 return ret;
d730f70e 776
4f0463a0 777 if (sr_atod_ascii(response, scpi_response) == SR_OK)
d730f70e
DJ
778 ret = SR_OK;
779 else
c0d25779 780 ret = SR_ERR_DATA;
d730f70e
DJ
781
782 g_free(response);
783
7b9d7320
DJ
784 return ret;
785}
786
f5922ade
DJ
787/**
788 * Send a SCPI *OPC? command, read the reply and return the result of the
789 * command.
790 *
23f43dff 791 * @param scpi Previously initialised SCPI device structure.
f5922ade 792 *
c0d25779 793 * @return SR_OK on success, SR_ERR* on failure.
f5922ade 794 */
23f43dff 795SR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi)
f5922ade
DJ
796{
797 unsigned int i;
798 gboolean opc;
799
0a1f7b09 800 for (i = 0; i < SCPI_READ_RETRIES; i++) {
da6f107e 801 opc = FALSE;
23f43dff 802 sr_scpi_get_bool(scpi, SCPI_CMD_OPC, &opc);
f5922ade
DJ
803 if (opc)
804 return SR_OK;
1a46cc62 805 g_usleep(SCPI_READ_RETRY_TIMEOUT_US);
f5922ade
DJ
806 }
807
808 return SR_ERR;
809}
810
8acbb89a
DJ
811/**
812 * Send a SCPI command, read the reply, parse it as comma separated list of
813 * floats and store the as an result in scpi_response.
814 *
23f43dff 815 * @param scpi Previously initialised SCPI device structure.
8acbb89a
DJ
816 * @param command The SCPI command to send to the device (can be NULL).
817 * @param scpi_response Pointer where to store the parsed result.
818 *
c0d25779 819 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
d5976d8b
UH
820 * error or upon no response. The allocated response must be freed by
821 * the caller in the case of an SR_OK as well as in the case of
822 * parsing error.
8acbb89a 823 */
23f43dff 824SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
d5976d8b 825 const char *command, GArray **scpi_response)
8acbb89a
DJ
826{
827 int ret;
828 float tmp;
829 char *response;
d5976d8b 830 gchar **ptr, **tokens;
8acbb89a
DJ
831 GArray *response_array;
832
8acbb89a
DJ
833 response = NULL;
834 tokens = NULL;
835
c0d25779
BV
836 ret = sr_scpi_get_string(scpi, command, &response);
837 if (ret != SR_OK && !response)
838 return ret;
8acbb89a
DJ
839
840 tokens = g_strsplit(response, ",", 0);
841 ptr = tokens;
842
843 response_array = g_array_sized_new(TRUE, FALSE, sizeof(float), 256);
844
d5976d8b 845 while (*ptr) {
13dbd151 846 if (sr_atof_ascii(*ptr, &tmp) == SR_OK)
8acbb89a
DJ
847 response_array = g_array_append_val(response_array,
848 tmp);
849 else
c0d25779 850 ret = SR_ERR_DATA;
8acbb89a
DJ
851
852 ptr++;
853 }
854 g_strfreev(tokens);
855 g_free(response);
856
c0d25779 857 if (ret != SR_OK && response_array->len == 0) {
8acbb89a
DJ
858 g_array_free(response_array, TRUE);
859 *scpi_response = NULL;
c0d25779 860 return SR_ERR_DATA;
8acbb89a
DJ
861 }
862
863 *scpi_response = response_array;
864
1a323dd8
DJ
865 return ret;
866}
867
868/**
869 * Send a SCPI command, read the reply, parse it as comma separated list of
870 * unsigned 8 bit integers and store the as an result in scpi_response.
871 *
23f43dff 872 * @param scpi Previously initialised SCPI device structure.
1a323dd8
DJ
873 * @param command The SCPI command to send to the device (can be NULL).
874 * @param scpi_response Pointer where to store the parsed result.
875 *
c0d25779 876 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
d5976d8b
UH
877 * error or upon no response. The allocated response must be freed by
878 * the caller in the case of an SR_OK as well as in the case of
879 * parsing error.
1a323dd8 880 */
23f43dff 881SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi,
d5976d8b 882 const char *command, GArray **scpi_response)
1a323dd8 883{
d5976d8b 884 int tmp, ret;
1a323dd8 885 char *response;
d5976d8b 886 gchar **ptr, **tokens;
1a323dd8
DJ
887 GArray *response_array;
888
1a323dd8
DJ
889 response = NULL;
890 tokens = NULL;
891
c0d25779
BV
892 ret = sr_scpi_get_string(scpi, command, &response);
893 if (ret != SR_OK && !response)
894 return ret;
1a323dd8
DJ
895
896 tokens = g_strsplit(response, ",", 0);
897 ptr = tokens;
898
899 response_array = g_array_sized_new(TRUE, FALSE, sizeof(uint8_t), 256);
900
d5976d8b 901 while (*ptr) {
1a323dd8
DJ
902 if (sr_atoi(*ptr, &tmp) == SR_OK)
903 response_array = g_array_append_val(response_array,
904 tmp);
905 else
c0d25779 906 ret = SR_ERR_DATA;
1a323dd8
DJ
907
908 ptr++;
909 }
910 g_strfreev(tokens);
911 g_free(response);
912
913 if (response_array->len == 0) {
914 g_array_free(response_array, TRUE);
915 *scpi_response = NULL;
c0d25779 916 return SR_ERR_DATA;
1a323dd8
DJ
917 }
918
919 *scpi_response = response_array;
920
8acbb89a
DJ
921 return ret;
922}
d3de86f3 923
ff01b0ea
SB
924/**
925 * Send a SCPI command, read the reply, parse it as binary data with a
926 * "definite length block" header and store the as an result in scpi_response.
927 *
928 * @param scpi Previously initialised SCPI device structure.
929 * @param command The SCPI command to send to the device (can be NULL).
930 * @param scpi_response Pointer where to store the parsed result.
931 *
932 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
933 * error or upon no response. The allocated response must be freed by
934 * the caller in the case of an SR_OK as well as in the case of
935 * parsing error.
936 */
937SR_PRIV int sr_scpi_get_block(struct sr_scpi_dev_inst *scpi,
938 const char *command, GByteArray **scpi_response)
939{
940 int ret;
941 GString* response;
26e8c6a2 942 char buf[10];
ff01b0ea
SB
943 long llen;
944 long datalen;
d64be25b 945 gint64 timeout;
fd20e59c
FS
946 va_list empty_va_list;
947
948 g_mutex_lock(&scpi->scpi_mutex);
d64be25b
SB
949
950 if (command)
fd20e59c
FS
951 if (scpi_send(scpi, command, empty_va_list) != SR_OK) {
952 g_mutex_unlock(&scpi->scpi_mutex);
d64be25b 953 return SR_ERR;
fd20e59c 954 }
d64be25b 955
fd20e59c
FS
956 if (sr_scpi_read_begin(scpi) != SR_OK) {
957 g_mutex_unlock(&scpi->scpi_mutex);
d64be25b 958 return SR_ERR;
fd20e59c 959 }
ff01b0ea 960
26e8c6a2
GS
961 /*
962 * Assume an initial maximum length, optionally gets adjusted below.
963 * Prepare a NULL return value for when error paths will be taken.
964 */
ff01b0ea 965 response = g_string_sized_new(1024);
d64be25b
SB
966
967 timeout = g_get_monotonic_time() + scpi->read_timeout_us;
968
ff01b0ea
SB
969 *scpi_response = NULL;
970
26e8c6a2 971 /* Get (the first chunk of) the response. */
d64be25b 972 while (response->len < 2) {
fd20e59c 973 ret = scpi_read_response(scpi, response, timeout);
d64be25b 974 if (ret < 0) {
fd20e59c 975 g_mutex_unlock(&scpi->scpi_mutex);
d64be25b
SB
976 g_string_free(response, TRUE);
977 return ret;
978 }
ff01b0ea
SB
979 }
980
26e8c6a2
GS
981 /*
982 * SCPI protocol data blocks are preceeded with a length spec.
983 * The length spec consists of a '#' marker, one digit which
984 * specifies the character count of the length spec, and the
985 * respective number of characters which specify the data block's
986 * length. Raw data bytes follow (thus one must no longer assume
987 * that the received input stream would be an ASCIIZ string).
988 *
989 * Get the data block length, and strip off the length spec from
990 * the input buffer, leaving just the data bytes.
991 */
ff01b0ea 992 if (response->str[0] != '#') {
fd20e59c 993 g_mutex_unlock(&scpi->scpi_mutex);
ff01b0ea
SB
994 g_string_free(response, TRUE);
995 return SR_ERR_DATA;
996 }
ff01b0ea 997 buf[0] = response->str[1];
26e8c6a2 998 buf[1] = '\0';
ff01b0ea
SB
999 ret = sr_atol(buf, &llen);
1000 if ((ret != SR_OK) || (llen == 0)) {
fd20e59c 1001 g_mutex_unlock(&scpi->scpi_mutex);
ff01b0ea
SB
1002 g_string_free(response, TRUE);
1003 return ret;
1004 }
d64be25b
SB
1005
1006 while (response->len < (unsigned long)(2 + llen)) {
fd20e59c 1007 ret = scpi_read_response(scpi, response, timeout);
d64be25b 1008 if (ret < 0) {
fd20e59c 1009 g_mutex_unlock(&scpi->scpi_mutex);
d64be25b
SB
1010 g_string_free(response, TRUE);
1011 return ret;
1012 }
1013 }
1014
ff01b0ea 1015 memcpy(buf, &response->str[2], llen);
26e8c6a2 1016 buf[llen] = '\0';
ff01b0ea
SB
1017 ret = sr_atol(buf, &datalen);
1018 if ((ret != SR_OK) || (datalen == 0)) {
fd20e59c 1019 g_mutex_unlock(&scpi->scpi_mutex);
ff01b0ea
SB
1020 g_string_free(response, TRUE);
1021 return ret;
1022 }
ff01b0ea
SB
1023 g_string_erase(response, 0, 2 + llen);
1024
26e8c6a2
GS
1025 /*
1026 * If the initially assumed length does not cover the data block
1027 * length, then re-allocate the buffer size to the now known
1028 * length, and keep reading more chunks of response data.
1029 */
ff01b0ea
SB
1030 if (response->len < (unsigned long)(datalen)) {
1031 int oldlen = response->len;
1032 g_string_set_size(response, datalen);
1033 g_string_set_size(response, oldlen);
1034 }
d64be25b 1035
ff01b0ea 1036 while (response->len < (unsigned long)(datalen)) {
fd20e59c 1037 ret = scpi_read_response(scpi, response, timeout);
d64be25b 1038 if (ret < 0) {
fd20e59c 1039 g_mutex_unlock(&scpi->scpi_mutex);
ff01b0ea
SB
1040 g_string_free(response, TRUE);
1041 return ret;
1042 }
d64be25b
SB
1043 if (ret > 0)
1044 timeout = g_get_monotonic_time() + scpi->read_timeout_us;
ff01b0ea
SB
1045 }
1046
fd20e59c
FS
1047 g_mutex_unlock(&scpi->scpi_mutex);
1048
26e8c6a2 1049 /* Convert received data to byte array. */
ff01b0ea
SB
1050 *scpi_response = g_byte_array_new_take(
1051 (guint8*)g_string_free(response, FALSE), datalen);
1052
d64be25b 1053 return SR_OK;
ff01b0ea
SB
1054}
1055
7b9d7320
DJ
1056/**
1057 * Send the *IDN? SCPI command, receive the reply, parse it and store the
1058 * reply as a sr_scpi_hw_info structure in the supplied scpi_response pointer.
1059 *
d5976d8b
UH
1060 * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
1061 *
23f43dff 1062 * @param scpi Previously initialised SCPI device structure.
7b9d7320
DJ
1063 * @param scpi_response Pointer where to store the hw_info structure.
1064 *
c0d25779 1065 * @return SR_OK upon success, SR_ERR* on failure.
7b9d7320 1066 */
23f43dff 1067SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
7b9d7320
DJ
1068 struct sr_scpi_hw_info **scpi_response)
1069{
c0d25779 1070 int num_tokens, ret;
7b9d7320
DJ
1071 char *response;
1072 gchar **tokens;
7b9d7320 1073 struct sr_scpi_hw_info *hw_info;
47bbc4b5 1074 gchar *idn_substr;
7b9d7320
DJ
1075
1076 response = NULL;
1077 tokens = NULL;
1078
c0d25779
BV
1079 ret = sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response);
1080 if (ret != SR_OK && !response)
1081 return ret;
7b9d7320
DJ
1082
1083 /*
1084 * The response to a '*IDN?' is specified by the SCPI spec. It contains
1085 * a comma-separated list containing the manufacturer name, instrument
1086 * model, serial number of the instrument and the firmware version.
1087 */
1088 tokens = g_strsplit(response, ",", 0);
1089
1090 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
1091
0c08023f 1092 if (num_tokens < 4) {
d5976d8b 1093 sr_dbg("IDN response not according to spec: %80.s.", response);
7b9d7320
DJ
1094 g_strfreev(tokens);
1095 g_free(response);
c0d25779 1096 return SR_ERR_DATA;
7b9d7320
DJ
1097 }
1098 g_free(response);
1099
91219afc 1100 hw_info = g_malloc0(sizeof(struct sr_scpi_hw_info));
47bbc4b5
SP
1101
1102 idn_substr = g_strstr_len(tokens[0], -1, "IDN ");
1103 if (idn_substr == NULL)
1104 hw_info->manufacturer = g_strstrip(g_strdup(tokens[0]));
1105 else
1106 hw_info->manufacturer = g_strstrip(g_strdup(idn_substr + 4));
1107
558d438d
BV
1108 hw_info->model = g_strstrip(g_strdup(tokens[1]));
1109 hw_info->serial_number = g_strstrip(g_strdup(tokens[2]));
1110 hw_info->firmware_version = g_strstrip(g_strdup(tokens[3]));
7b9d7320
DJ
1111
1112 g_strfreev(tokens);
1113
1114 *scpi_response = hw_info;
1115
1116 return SR_OK;
1117}
1118
1119/**
1120 * Free a sr_scpi_hw_info struct.
1121 *
7b365c47
UH
1122 * @param hw_info Pointer to the struct to free. If NULL, this
1123 * function does nothing.
7b9d7320
DJ
1124 */
1125SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info)
1126{
7b365c47
UH
1127 if (!hw_info)
1128 return;
1129
1130 g_free(hw_info->manufacturer);
1131 g_free(hw_info->model);
1132 g_free(hw_info->serial_number);
1133 g_free(hw_info->firmware_version);
1134 g_free(hw_info);
7b9d7320 1135}
fd20e59c
FS
1136
1137SR_PRIV const char *sr_vendor_alias(const char *raw_vendor)
1138{
1139 unsigned int i;
1140
1141 for (i = 0; i < ARRAY_SIZE(scpi_vendors); i++) {
1142 if (!g_ascii_strcasecmp(raw_vendor, scpi_vendors[i][0]))
1143 return scpi_vendors[i][1];
1144 }
1145
1146 return raw_vendor;
1147}
1148
1149SR_PRIV const char *sr_scpi_cmd_get(const struct scpi_command *cmdtable, int command)
1150{
1151 unsigned int i;
1152 const char *cmd;
1153
1154 if (!cmdtable)
1155 return NULL;
1156
1157 cmd = NULL;
1158 for (i = 0; cmdtable[i].string; i++) {
1159 if (cmdtable[i].command == command) {
1160 cmd = cmdtable[i].string;
1161 break;
1162 }
1163 }
1164
1165 return cmd;
1166}
1167
1168SR_PRIV int sr_scpi_cmd(const struct sr_dev_inst *sdi, const struct scpi_command *cmdtable,
1169 int command, ...)
1170{
1171 struct sr_scpi_dev_inst *scpi;
1172 va_list args;
1173 int ret;
1174 const char *cmd;
1175
1176 if (!(cmd = sr_scpi_cmd_get(cmdtable, command))) {
1177 /* Device does not implement this command, that's OK. */
1178 return SR_OK;
1179 }
1180
1181 scpi = sdi->conn;
1182 va_start(args, command);
1183 ret = sr_scpi_send_variadic(scpi, cmd, args);
1184 va_end(args);
1185
1186 return ret;
1187}
1188
1189SR_PRIV int sr_scpi_cmd_resp(const struct sr_dev_inst *sdi,
1190 const struct scpi_command *cmdtable,
1191 GVariant **gvar, const GVariantType *gvtype, int command, ...)
1192{
1193 struct sr_scpi_dev_inst *scpi;
1194 va_list args;
1195 const char *cmd;
1196 GString *response;
1197 char *s;
1198 gboolean b;
1199 double d;
1200 int ret;
1201
1202 scpi = sdi->conn;
1203
1204 if (!(cmd = sr_scpi_cmd_get(cmdtable, command))) {
1205 /* Device does not implement this command. */
1206 return SR_ERR_NA;
1207 }
1208
1209 g_mutex_lock(&scpi->scpi_mutex);
1210
1211 va_start(args, command);
1212 ret = scpi_send_variadic(scpi, cmd, args);
1213 va_end(args);
1214 if (ret != SR_OK) {
1215 g_mutex_unlock(&scpi->scpi_mutex);
1216 return ret;
1217 }
1218
1219 response = g_string_sized_new(1024);
1220 ret = scpi_get_data(scpi, NULL, &response);
1221 if (ret != SR_OK) {
1222 g_mutex_unlock(&scpi->scpi_mutex);
1223 if (response)
1224 g_string_free(response, TRUE);
1225 return ret;
1226 }
1227
1228 g_mutex_unlock(&scpi->scpi_mutex);
1229
1230 /* Get rid of trailing linefeed if present */
1231 if (response->len >= 1 && response->str[response->len - 1] == '\n')
1232 g_string_truncate(response, response->len - 1);
1233
1234 /* Get rid of trailing carriage return if present */
1235 if (response->len >= 1 && response->str[response->len - 1] == '\r')
1236 g_string_truncate(response, response->len - 1);
1237
1238 s = g_string_free(response, FALSE);
1239
1240 ret = SR_OK;
1241 if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_BOOLEAN)) {
1242 if ((ret = parse_strict_bool(s, &b)) == SR_OK)
1243 *gvar = g_variant_new_boolean(b);
1244 } else if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_DOUBLE)) {
1245 if ((ret = sr_atod_ascii(s, &d)) == SR_OK)
1246 *gvar = g_variant_new_double(d);
1247 } else if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_STRING)) {
1248 *gvar = g_variant_new_string(s);
1249 } else {
1250 sr_err("Unable to convert to desired GVariant type.");
1251 ret = SR_ERR_NA;
1252 }
1253
1254 g_free(s);
1255
1256 return ret;
1257}