scpi.c 25 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * This file is part of the libsigrok project.
 *
 * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

20
#include <config.h>
21 22
#include <glib.h>
#include <string.h>
23
#include <libsigrok/libsigrok.h>
24
#include "libsigrok-internal.h"
25
#include "scpi.h"
26

27
#define LOG_PREFIX "scpi"
28 29

#define SCPI_READ_RETRIES 100
30
#define SCPI_READ_RETRY_TIMEOUT_US (10 * 1000)
31

32 33 34 35 36 37 38 39 40 41 42
/**
 * Parse a string representation of a boolean-like value into a gboolean.
 * Similar to sr_parse_boolstring but rejects strings which do not represent
 * a boolean-like value.
 *
 * @param str String to convert.
 * @param ret Pointer to a gboolean where the result of the conversion will be
 * stored.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
43
static int parse_strict_bool(const char *str, gboolean *ret)
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
{
	if (!str)
		return SR_ERR_ARG;

	if (!g_strcmp0(str, "1") ||
	    !g_ascii_strncasecmp(str, "y", 1) ||
	    !g_ascii_strncasecmp(str, "t", 1) ||
	    !g_ascii_strncasecmp(str, "yes", 3) ||
	    !g_ascii_strncasecmp(str, "true", 4) ||
	    !g_ascii_strncasecmp(str, "on", 2)) {
		*ret = TRUE;
		return SR_OK;
	} else if (!g_strcmp0(str, "0") ||
		   !g_ascii_strncasecmp(str, "n", 1) ||
		   !g_ascii_strncasecmp(str, "f", 1) ||
		   !g_ascii_strncasecmp(str, "no", 2) ||
		   !g_ascii_strncasecmp(str, "false", 5) ||
		   !g_ascii_strncasecmp(str, "off", 3)) {
		*ret = FALSE;
		return SR_OK;
	}

	return SR_ERR;
}

69
SR_PRIV extern const struct sr_scpi_dev_inst scpi_serial_dev;
70 71
SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_raw_dev;
SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_rigol_dev;
72
SR_PRIV extern const struct sr_scpi_dev_inst scpi_usbtmc_libusb_dev;
73
SR_PRIV extern const struct sr_scpi_dev_inst scpi_vxi_dev;
74
SR_PRIV extern const struct sr_scpi_dev_inst scpi_visa_dev;
75
SR_PRIV extern const struct sr_scpi_dev_inst scpi_libgpib_dev;
76 77

static const struct sr_scpi_dev_inst *scpi_devs[] = {
78 79
	&scpi_tcp_raw_dev,
	&scpi_tcp_rigol_dev,
80 81 82
#ifdef HAVE_LIBUSB_1_0
	&scpi_usbtmc_libusb_dev,
#endif
83
#if HAVE_RPC
84 85
	&scpi_vxi_dev,
#endif
86 87 88
#ifdef HAVE_LIBREVISA
	&scpi_visa_dev,
#endif
89
#ifdef HAVE_LIBGPIB
90
	&scpi_libgpib_dev,
91
#endif
92
#ifdef HAVE_LIBSERIALPORT
93
	&scpi_serial_dev, /* Must be last as it matches any resource. */
94 95 96
#endif
};

97
static struct sr_dev_inst *sr_scpi_scan_resource(struct drv_context *drvc,
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
		const char *resource, const char *serialcomm,
		struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))
{
	struct sr_scpi_dev_inst *scpi;
	struct sr_dev_inst *sdi;

	if (!(scpi = scpi_dev_inst_new(drvc, resource, serialcomm)))
		return NULL;

	if (sr_scpi_open(scpi) != SR_OK) {
		sr_info("Couldn't open SCPI device.");
		sr_scpi_free(scpi);
		return NULL;
	};

113
	sdi = probe_device(scpi);
114 115

	sr_scpi_close(scpi);
116 117 118 119 120 121 122

	if (sdi)
		sdi->status = SR_ST_INACTIVE;
	else
		sr_scpi_free(scpi);

	return sdi;
123 124 125 126 127
}

SR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options,
		struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))
{
128 129
	GSList *resources, *l, *devices;
	struct sr_dev_inst *sdi;
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
	const char *resource = NULL;
	const char *serialcomm = NULL;
	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;
		}
	}

147
	devices = NULL;
148 149 150 151 152 153 154
	for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) {
		if ((resource && strcmp(resource, scpi_devs[i]->prefix))
		    || !scpi_devs[i]->scan)
			continue;
		resources = scpi_devs[i]->scan(drvc);
		for (l = resources; l; l = l->next) {
			res = g_strsplit(l->data, ":", 2);
155
			if (res[0] && (sdi = sr_scpi_scan_resource(drvc, res[0],
156
			               serialcomm ? serialcomm : res[1], probe_device))) {
157
				devices = g_slist_append(devices, sdi);
158 159
				sdi->connection_id = g_strdup(l->data);
			}
160 161 162 163 164
			g_strfreev(res);
		}
		g_slist_free_full(resources, g_free);
	}

165 166
	if (!devices && resource) {
		sdi = sr_scpi_scan_resource(drvc, resource, serialcomm, probe_device);
167 168
		if (sdi)
			devices = g_slist_append(NULL, sdi);
169
	}
170 171 172

	/* Tack a copy of the newly found devices onto the driver list. */
	if (devices)
173
		drvc->instances = g_slist_concat(drvc->instances, g_slist_copy(devices));
174 175 176 177

	return devices;
}

178 179
SR_PRIV struct sr_scpi_dev_inst *scpi_dev_inst_new(struct drv_context *drvc,
		const char *resource, const char *serialcomm)
180 181
{
	struct sr_scpi_dev_inst *scpi = NULL;
182 183 184
	const struct sr_scpi_dev_inst *scpi_dev;
	gchar **params;
	unsigned i;
185

186 187 188 189 190 191 192
	for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) {
		scpi_dev = scpi_devs[i];
		if (!strncmp(resource, scpi_dev->prefix, strlen(scpi_dev->prefix))) {
			sr_dbg("Opening %s device %s.", scpi_dev->name, resource);
			scpi = g_malloc(sizeof(*scpi));
			*scpi = *scpi_dev;
			scpi->priv = g_malloc0(scpi->priv_size);
193
			scpi->read_timeout_us = 1000 * 1000;
194
			params = g_strsplit(resource, "/", 0);
195
			if (scpi->dev_inst_new(scpi->priv, drvc, resource,
196 197 198 199 200 201 202
			                       params, serialcomm) != SR_OK) {
				sr_scpi_free(scpi);
				scpi = NULL;
			}
			g_strfreev(params);
			break;
		}
203
	}
204

205 206 207
	return scpi;
}

208 209 210 211 212 213 214 215 216
/**
 * Open SCPI device.
 *
 * @param scpi Previously initialized SCPI device structure.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi)
{
217
	return scpi->open(scpi);
218 219 220 221 222
}

/**
 * Add an event source for an SCPI device.
 *
223
 * @param session The session to add the event source to.
224 225 226 227 228 229 230 231 232
 * @param scpi Previously initialized SCPI device structure.
 * @param events Events to check for.
 * @param timeout Max time to wait before the callback is called, ignored if 0.
 * @param cb Callback function to add. Must not be NULL.
 * @param cb_data Data for the callback function. Can be NULL.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
 *         SR_ERR_MALLOC upon memory allocation errors.
 */
233 234 235
SR_PRIV int sr_scpi_source_add(struct sr_session *session,
		struct sr_scpi_dev_inst *scpi, int events, int timeout,
		sr_receive_data_callback cb, void *cb_data)
236
{
237
	return scpi->source_add(session, scpi->priv, events, timeout, cb, cb_data);
238 239 240 241 242
}

/**
 * Remove event source for an SCPI device.
 *
243
 * @param session The session to remove the event source from.
244 245 246 247 248 249
 * @param scpi Previously initialized SCPI device structure.
 *
 * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
 *         SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon
 *         internal errors.
 */
250 251
SR_PRIV int sr_scpi_source_remove(struct sr_session *session,
		struct sr_scpi_dev_inst *scpi)
252
{
253
	return scpi->source_remove(session, scpi->priv);
254 255
}

256 257 258
/**
 * Send a SCPI command.
 *
259
 * @param scpi Previously initialized SCPI device structure.
260
 * @param format Format string, to be followed by any necessary arguments.
261 262 263
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
264
SR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi,
265
			 const char *format, ...)
266
{
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
	va_list args;
	int ret;

	va_start(args, format);
	ret = sr_scpi_send_variadic(scpi, format, args);
	va_end(args);

	return ret;
}

/**
 * Send a SCPI command with a variadic argument list.
 *
 * @param scpi Previously initialized SCPI device structure.
 * @param format Format string.
 * @param args Argument list.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_send_variadic(struct sr_scpi_dev_inst *scpi,
			 const char *format, va_list args)
{
	va_list args_copy;
290 291 292 293
	char *buf;
	int len, ret;

	/* Get length of buffer required. */
294 295 296
	va_copy(args_copy, args);
	len = vsnprintf(NULL, 0, format, args_copy);
	va_end(args_copy);
297 298

	/* Allocate buffer and write out command. */
299
	buf = g_malloc0(len + 2);
300
	vsprintf(buf, format, args);
301 302
	if (buf[len - 1] != '\n')
		buf[len] = '\n';
303 304 305 306 307 308 309 310

	/* Send command. */
	ret = scpi->send(scpi->priv, buf);

	/* Free command buffer. */
	g_free(buf);

	return ret;
311
}
312

313
/**
314
 * Begin receiving an SCPI reply.
315 316 317
 *
 * @param scpi Previously initialised SCPI device structure.
 *
318
 * @return SR_OK on success, SR_ERR on failure.
319
 */
320
SR_PRIV int sr_scpi_read_begin(struct sr_scpi_dev_inst *scpi)
321
{
322
	return scpi->read_begin(scpi->priv);
323
}
324

325 326 327 328 329 330 331 332 333
/**
 * Read part of a response from SCPI device.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param buf Buffer to store result.
 * @param maxlen Maximum number of bytes to read.
 *
 * @return Number of bytes read, or SR_ERR upon failure.
 */
334
SR_PRIV int sr_scpi_read_data(struct sr_scpi_dev_inst *scpi,
335 336
			char *buf, int maxlen)
{
337 338 339
	return scpi->read_data(scpi->priv, buf, maxlen);
}

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
/**
 * Send data to SCPI device.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param buf Buffer with data to send.
 * @param len Number of bytes to send.
 *
 * @return Number of bytes read, or SR_ERR upon failure.
 */
SR_PRIV int sr_scpi_write_data(struct sr_scpi_dev_inst *scpi,
			char *buf, int maxlen)
{
	return scpi->write_data(scpi->priv, buf, maxlen);
}

355 356 357 358 359 360 361 362 363 364
/**
 * Check whether a complete SCPI response has been received.
 *
 * @param scpi Previously initialised SCPI device structure.
 *
 * @return 1 if complete, 0 otherwise.
 */
SR_PRIV int sr_scpi_read_complete(struct sr_scpi_dev_inst *scpi)
{
	return scpi->read_complete(scpi->priv);
365 366
}

367 368 369 370 371 372 373 374 375
/**
 * Close SCPI device.
 *
 * @param scpi Previously initialized SCPI device structure.
 *
 * @return SR_OK on success, SR_ERR on failure.
 */
SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi)
{
376
	return scpi->close(scpi);
377
}
378

379 380 381
/**
 * Free SCPI device.
 *
382 383
 * @param scpi Previously initialized SCPI device structure. If NULL,
 *             this function does nothing.
384 385 386
 */
SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi)
{
387 388 389
	if (!scpi)
		return;

390
	scpi->free(scpi->priv);
391
	g_free(scpi->priv);
392
	g_free(scpi);
393 394 395 396 397
}

/**
 * Send a SCPI command, receive the reply and store the reply in scpi_response.
 *
398
 * @param scpi Previously initialised SCPI device structure.
399
 * @param command The SCPI command to send to the device (can be NULL).
400
 * @param scpi_response Pointer where to store the SCPI response.
401
 *
402
 * @return SR_OK on success, SR_ERR* on failure.
403
 */
404
SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
405
			       const char *command, char **scpi_response)
406
{
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
	GString *response;
	response = g_string_sized_new(1024);

	if (sr_scpi_get_data(scpi, command, &response) != SR_OK) {
		if (response)
			g_string_free(response, TRUE);
		return SR_ERR;
	}

	/* Get rid of trailing linefeed if present */
	if (response->len >= 1 && response->str[response->len - 1] == '\n')
		g_string_truncate(response, response->len - 1);

	/* Get rid of trailing carriage return if present */
	if (response->len >= 1 && response->str[response->len - 1] == '\r')
		g_string_truncate(response, response->len - 1);

	sr_spew("Got response: '%.70s', length %" G_GSIZE_FORMAT ".",
		response->str, response->len);

	*scpi_response = g_string_free(response, FALSE);

	return SR_OK;
}

432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
/**
 * Do a non-blocking read of up to the allocated length, and
 * check if a timeout has occured.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param response Buffer to which the response is appended.
 * @param abs_timeout_us Absolute timeout in microseconds
 *
 * @return read length on success, SR_ERR* on failure.
 */
SR_PRIV int sr_scpi_read_response(struct sr_scpi_dev_inst *scpi,
				  GString *response, gint64 abs_timeout_us)
{
	int len, space;

	space = response->allocated_len - response->len;
	len = sr_scpi_read_data(scpi, &response->str[response->len], space);

	if (len < 0) {
		sr_err("Incompletely read SCPI response.");
		return SR_ERR;
	}

	if (len > 0) {
		g_string_set_size(response, response->len + len);
		return len;
	}

	if (g_get_monotonic_time() > abs_timeout_us) {
		sr_err("Timed out waiting for SCPI response.");
		return SR_ERR_TIMEOUT;
	}

	return 0;
}

468 469 470
SR_PRIV int sr_scpi_get_data(struct sr_scpi_dev_inst *scpi,
			     const char *command, GString **scpi_response)
{
471
	int ret;
472
	GString *response;
473
	int space;
474
	gint64 timeout;
475

476
	/* Optionally send caller provided command. */
Gerhard Sittig's avatar
Gerhard Sittig committed
477
	if (command) {
478
		if (sr_scpi_send(scpi, command) != SR_OK)
479
			return SR_ERR;
Gerhard Sittig's avatar
Gerhard Sittig committed
480
	}
481

482
	/* Initiate SCPI read operation. */
483 484 485
	if (sr_scpi_read_begin(scpi) != SR_OK)
		return SR_ERR;

486
	/* Keep reading until completion or until timeout. */
487
	timeout = g_get_monotonic_time() + scpi->read_timeout_us;
488

489
	response = *scpi_response;
490 491

	while (!sr_scpi_read_complete(scpi)) {
492
		/* Resize the buffer when free space drops below a threshold. */
493 494
		space = response->allocated_len - response->len;
		if (space < 128) {
495 496 497
			int oldlen = response->len;
			g_string_set_size(response, oldlen + 1024);
			g_string_set_size(response, oldlen);
498 499
		}

500 501
		/* Read another chunk of the response. */
		ret = sr_scpi_read_response(scpi, response, timeout);
502

503 504 505 506
		if (ret < 0)
			return ret;
		if (ret > 0)
			timeout = g_get_monotonic_time() + scpi->read_timeout_us;
507 508 509
	}

	return SR_OK;
510 511 512 513 514 515
}

/**
 * Send a SCPI command, read the reply, parse it as a bool value and store the
 * result in scpi_response.
 *
516
 * @param scpi Previously initialised SCPI device structure.
517 518 519
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
520
 * @return SR_OK on success, SR_ERR* on failure.
521
 */
522
SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
523 524 525 526 527 528 529
			     const char *command, gboolean *scpi_response)
{
	int ret;
	char *response;

	response = NULL;

530 531 532
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
533

534
	if (parse_strict_bool(response, scpi_response) == SR_OK)
535 536
		ret = SR_OK;
	else
537
		ret = SR_ERR_DATA;
538 539 540 541 542 543 544 545 546 547

	g_free(response);

	return ret;
}

/**
 * Send a SCPI command, read the reply, parse it as an integer and store the
 * result in scpi_response.
 *
548
 * @param scpi Previously initialised SCPI device structure.
549 550 551
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
552
 * @return SR_OK on success, SR_ERR* on failure.
553
 */
554
SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi,
555
			    const char *command, int *scpi_response)
556 557 558 559 560 561
{
	int ret;
	char *response;

	response = NULL;

562 563 564
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
565 566 567 568

	if (sr_atoi(response, scpi_response) == SR_OK)
		ret = SR_OK;
	else
569
		ret = SR_ERR_DATA;
570 571 572 573 574 575 576 577 578 579

	g_free(response);

	return ret;
}

/**
 * Send a SCPI command, read the reply, parse it as a float and store the
 * result in scpi_response.
 *
580
 * @param scpi Previously initialised SCPI device structure.
581 582 583
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
584
 * @return SR_OK on success, SR_ERR* on failure.
585
 */
586
SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
587 588 589 590 591 592 593
			      const char *command, float *scpi_response)
{
	int ret;
	char *response;

	response = NULL;

594 595 596
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
597

598
	if (sr_atof_ascii(response, scpi_response) == SR_OK)
599 600
		ret = SR_OK;
	else
601
		ret = SR_ERR_DATA;
602 603 604 605 606 607 608 609 610 611

	g_free(response);

	return ret;
}

/**
 * Send a SCPI command, read the reply, parse it as a double and store the
 * result in scpi_response.
 *
612
 * @param scpi Previously initialised SCPI device structure.
613 614 615
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
616
 * @return SR_OK on success, SR_ERR* on failure.
617
 */
618
SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
619
			       const char *command, double *scpi_response)
620 621 622 623 624 625
{
	int ret;
	char *response;

	response = NULL;

626 627 628
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
629

630
	if (sr_atod_ascii(response, scpi_response) == SR_OK)
631 632
		ret = SR_OK;
	else
633
		ret = SR_ERR_DATA;
634 635 636

	g_free(response);

637 638 639
	return ret;
}

640 641 642 643
/**
 * Send a SCPI *OPC? command, read the reply and return the result of the
 * command.
 *
644
 * @param scpi Previously initialised SCPI device structure.
645
 *
646
 * @return SR_OK on success, SR_ERR* on failure.
647
 */
648
SR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi)
649 650 651 652
{
	unsigned int i;
	gboolean opc;

653
	for (i = 0; i < SCPI_READ_RETRIES; i++) {
654
		sr_scpi_get_bool(scpi, SCPI_CMD_OPC, &opc);
655 656
		if (opc)
			return SR_OK;
657
		g_usleep(SCPI_READ_RETRY_TIMEOUT_US);
658 659 660 661 662
	}

	return SR_ERR;
}

663 664 665 666
/**
 * Send a SCPI command, read the reply, parse it as comma separated list of
 * floats and store the as an result in scpi_response.
 *
667
 * @param scpi Previously initialised SCPI device structure.
668 669 670
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
671
 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
672 673 674
 *         error or upon no response. The allocated response must be freed by
 *         the caller in the case of an SR_OK as well as in the case of
 *         parsing error.
675
 */
676
SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
677
			       const char *command, GArray **scpi_response)
678 679 680 681
{
	int ret;
	float tmp;
	char *response;
682
	gchar **ptr, **tokens;
683 684 685 686 687
	GArray *response_array;

	response = NULL;
	tokens = NULL;

688 689 690
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
691 692 693 694 695 696

	tokens = g_strsplit(response, ",", 0);
	ptr = tokens;

	response_array = g_array_sized_new(TRUE, FALSE, sizeof(float), 256);

697
	while (*ptr) {
698
		if (sr_atof_ascii(*ptr, &tmp) == SR_OK)
699 700 701
			response_array = g_array_append_val(response_array,
							    tmp);
		else
702
			ret = SR_ERR_DATA;
703 704 705 706 707 708

		ptr++;
	}
	g_strfreev(tokens);
	g_free(response);

709
	if (ret != SR_OK && response_array->len == 0) {
710 711
		g_array_free(response_array, TRUE);
		*scpi_response = NULL;
712
		return SR_ERR_DATA;
713 714 715 716
	}

	*scpi_response = response_array;

717 718 719 720 721 722 723
	return ret;
}

/**
 * Send a SCPI command, read the reply, parse it as comma separated list of
 * unsigned 8 bit integers and store the as an result in scpi_response.
 *
724
 * @param scpi Previously initialised SCPI device structure.
725 726 727
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
728
 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
729 730 731
 *         error or upon no response. The allocated response must be freed by
 *         the caller in the case of an SR_OK as well as in the case of
 *         parsing error.
732
 */
733
SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi,
734
			       const char *command, GArray **scpi_response)
735
{
736
	int tmp, ret;
737
	char *response;
738
	gchar **ptr, **tokens;
739 740 741 742 743
	GArray *response_array;

	response = NULL;
	tokens = NULL;

744 745 746
	ret = sr_scpi_get_string(scpi, command, &response);
	if (ret != SR_OK && !response)
		return ret;
747 748 749 750 751 752

	tokens = g_strsplit(response, ",", 0);
	ptr = tokens;

	response_array = g_array_sized_new(TRUE, FALSE, sizeof(uint8_t), 256);

753
	while (*ptr) {
754 755 756 757
		if (sr_atoi(*ptr, &tmp) == SR_OK)
			response_array = g_array_append_val(response_array,
							    tmp);
		else
758
			ret = SR_ERR_DATA;
759 760 761 762 763 764 765 766 767

		ptr++;
	}
	g_strfreev(tokens);
	g_free(response);

	if (response_array->len == 0) {
		g_array_free(response_array, TRUE);
		*scpi_response = NULL;
768
		return SR_ERR_DATA;
769 770 771 772
	}

	*scpi_response = response_array;

773 774
	return ret;
}
Gerhard Sittig's avatar
Gerhard Sittig committed
775

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
/**
 * Send a SCPI command, read the reply, parse it as binary data with a
 * "definite length block" header and store the as an result in scpi_response.
 *
 * @param scpi Previously initialised SCPI device structure.
 * @param command The SCPI command to send to the device (can be NULL).
 * @param scpi_response Pointer where to store the parsed result.
 *
 * @return SR_OK upon successfully parsing all values, SR_ERR* upon a parsing
 *         error or upon no response. The allocated response must be freed by
 *         the caller in the case of an SR_OK as well as in the case of
 *         parsing error.
 */
SR_PRIV int sr_scpi_get_block(struct sr_scpi_dev_inst *scpi,
			       const char *command, GByteArray **scpi_response)
{
	int ret;
	GString* response;
794
	char buf[10];
795 796
	long llen;
	long datalen;
797 798 799 800 801 802 803 804
	gint64 timeout;

	if (command)
		if (sr_scpi_send(scpi, command) != SR_OK)
			return SR_ERR;

	if (sr_scpi_read_begin(scpi) != SR_OK)
		return SR_ERR;
805

806 807 808 809
	/*
	 * Assume an initial maximum length, optionally gets adjusted below.
	 * Prepare a NULL return value for when error paths will be taken.
	 */
810
	response = g_string_sized_new(1024);
811 812 813

	timeout = g_get_monotonic_time() + scpi->read_timeout_us;

814 815
	*scpi_response = NULL;

816
	/* Get (the first chunk of) the response. */
817 818 819 820 821 822
	while (response->len < 2) {
		ret = sr_scpi_read_response(scpi, response, timeout);
		if (ret < 0) {
			g_string_free(response, TRUE);
			return ret;
		}
823 824
	}

825 826 827 828 829 830 831 832 833 834 835
	/*
	 * SCPI protocol data blocks are preceeded with a length spec.
	 * The length spec consists of a '#' marker, one digit which
	 * specifies the character count of the length spec, and the
	 * respective number of characters which specify the data block's
	 * length. Raw data bytes follow (thus one must no longer assume
	 * that the received input stream would be an ASCIIZ string).
	 *
	 * Get the data block length, and strip off the length spec from
	 * the input buffer, leaving just the data bytes.
	 */
836 837 838 839 840
	if (response->str[0] != '#') {
		g_string_free(response, TRUE);
		return SR_ERR_DATA;
	}
	buf[0] = response->str[1];
841
	buf[1] = '\0';
842 843 844 845 846
	ret = sr_atol(buf, &llen);
	if ((ret != SR_OK) || (llen == 0)) {
		g_string_free(response, TRUE);
		return ret;
	}
847 848 849 850 851 852 853 854 855

	while (response->len < (unsigned long)(2 + llen)) {
		ret = sr_scpi_read_response(scpi, response, timeout);
		if (ret < 0) {
			g_string_free(response, TRUE);
			return ret;
		}
	}

856
	memcpy(buf, &response->str[2], llen);
857
	buf[llen] = '\0';
858 859 860 861 862 863 864
	ret = sr_atol(buf, &datalen);
	if ((ret != SR_OK) || (datalen == 0)) {
		g_string_free(response, TRUE);
		return ret;
	}
	g_string_erase(response, 0, 2 + llen);

865 866 867 868 869
	/*
	 * If the initially assumed length does not cover the data block
	 * length, then re-allocate the buffer size to the now known
	 * length, and keep reading more chunks of response data.
	 */
870 871 872 873 874
	if (response->len < (unsigned long)(datalen)) {
		int oldlen = response->len;
		g_string_set_size(response, datalen);
		g_string_set_size(response, oldlen);
	}
875

876
	while (response->len < (unsigned long)(datalen)) {
877 878
		ret = sr_scpi_read_response(scpi, response, timeout);
		if (ret < 0) {
879 880 881
			g_string_free(response, TRUE);
			return ret;
		}
882 883
		if (ret > 0)
			timeout = g_get_monotonic_time() + scpi->read_timeout_us;
884 885
	}

886
	/* Convert received data to byte array. */
887 888 889
	*scpi_response = g_byte_array_new_take(
		(guint8*)g_string_free(response, FALSE), datalen);

890
	return SR_OK;
891 892
}

893 894 895 896
/**
 * Send the *IDN? SCPI command, receive the reply, parse it and store the
 * reply as a sr_scpi_hw_info structure in the supplied scpi_response pointer.
 *
897 898
 * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
 *
899
 * @param scpi Previously initialised SCPI device structure.
900 901
 * @param scpi_response Pointer where to store the hw_info structure.
 *
902
 * @return SR_OK upon success, SR_ERR* on failure.
903
 */
904
SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
905 906
			      struct sr_scpi_hw_info **scpi_response)
{
907
	int num_tokens, ret;
908 909 910
	char *response;
	gchar **tokens;
	struct sr_scpi_hw_info *hw_info;
911
	gchar *idn_substr;
912 913 914 915

	response = NULL;
	tokens = NULL;

916 917 918
	ret = sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response);
	if (ret != SR_OK && !response)
		return ret;
919

Martin Ling's avatar
Martin Ling committed
920 921
	sr_info("Got IDN string: '%s'", response);

922 923 924 925 926 927 928 929 930
	/*
	 * The response to a '*IDN?' is specified by the SCPI spec. It contains
	 * a comma-separated list containing the manufacturer name, instrument
	 * model, serial number of the instrument and the firmware version.
	 */
	tokens = g_strsplit(response, ",", 0);

	for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);

931
	if (num_tokens < 4) {
932
		sr_dbg("IDN response not according to spec: %80.s.", response);
933 934
		g_strfreev(tokens);
		g_free(response);
935
		return SR_ERR_DATA;
936 937 938
	}
	g_free(response);

939
	hw_info = g_malloc0(sizeof(struct sr_scpi_hw_info));
940 941 942 943 944 945 946

	idn_substr = g_strstr_len(tokens[0], -1, "IDN ");
	if (idn_substr == NULL)
		hw_info->manufacturer = g_strstrip(g_strdup(tokens[0]));
	else
		hw_info->manufacturer = g_strstrip(g_strdup(idn_substr + 4));

947 948 949
	hw_info->model = g_strstrip(g_strdup(tokens[1]));
	hw_info->serial_number = g_strstrip(g_strdup(tokens[2]));
	hw_info->firmware_version = g_strstrip(g_strdup(tokens[3]));
950 951 952 953 954 955 956 957 958 959 960

	g_strfreev(tokens);

	*scpi_response = hw_info;

	return SR_OK;
}

/**
 * Free a sr_scpi_hw_info struct.
 *
961 962
 * @param hw_info Pointer to the struct to free. If NULL, this
 *                function does nothing.
963 964 965
 */
SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info)
{
966 967 968 969 970 971 972 973
	if (!hw_info)
		return;

	g_free(hw_info->manufacturer);
	g_free(hw_info->model);
	g_free(hw_info->serial_number);
	g_free(hw_info->firmware_version);
	g_free(hw_info);
974
}