+SR_PRIV char *scpi_cmd_get(const struct sr_dev_inst *sdi, int command)
+{
+ struct dev_context *devc;
+ unsigned int i;
+ char *cmd;
+
+ devc = sdi->priv;
+ cmd = NULL;
+ for (i = 0; i < devc->device->num_commands; i++) {
+ if (devc->device->commands[i].command == command) {
+ cmd = devc->device->commands[i].string;
+ break;
+ }
+ }
+
+ return cmd;
+}
+
+SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...)
+{
+ struct sr_scpi_dev_inst *scpi;
+ va_list args;
+ int ret;
+ char *cmd;
+
+ if (!(cmd = scpi_cmd_get(sdi, command))) {
+ /* Device does not implement this command, that's OK. */
+ return SR_OK_CONTINUE;
+ }
+
+ scpi = sdi->conn;
+ va_start(args, command);
+ ret = sr_scpi_send_variadic(scpi, cmd, args);
+ va_end(args);
+
+ return ret;
+}
+
+SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, GVariant **gvar,
+ const GVariantType *gvtype, int command, ...)
+{
+ struct sr_scpi_dev_inst *scpi;
+ va_list args;
+ double d;
+ int ret;
+ char *cmd, *s;
+
+ if (!(cmd = scpi_cmd_get(sdi, command))) {
+ /* Device does not implement this command, that's OK. */
+ return SR_OK_CONTINUE;
+ }
+
+ scpi = sdi->conn;
+ va_start(args, command);
+ ret = sr_scpi_send_variadic(scpi, cmd, args);
+ va_end(args);
+ if (ret != SR_OK)
+ return ret;
+
+ if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_BOOLEAN)) {
+ if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK)
+ return ret;
+ if (!strcasecmp(s, "ON") || !strcasecmp(s, "1") || !strcasecmp(s, "YES"))
+ *gvar = g_variant_new_boolean(TRUE);
+ else if (!strcasecmp(s, "OFF") || !strcasecmp(s, "0") || !strcasecmp(s, "NO"))
+ *gvar = g_variant_new_boolean(FALSE);
+ else
+ ret = SR_ERR;
+ } if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_DOUBLE)) {
+ if ((ret = sr_scpi_get_double(scpi, NULL, &d)) == SR_OK)
+ *gvar = g_variant_new_double(d);
+ } if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_STRING)) {
+ if ((ret = sr_scpi_get_string(scpi, NULL, &s)) == SR_OK)
+ *gvar = g_variant_new_string(s);
+ }
+
+ return ret;
+}
+