+#define READ_TIMEOUT_MS 1000
+
+static int send_cmd(const struct sr_dev_inst *sdi, const char *cmd,
+ char *replybuf, int replybufsize)
+{
+ char *bufptr;
+ int len, ret;
+ struct sr_serial_dev_inst *serial;
+
+ serial = sdi->conn;
+
+ /* Send the command (blocking, with timeout). */
+ if ((ret = serial_write_blocking(serial, cmd,
+ strlen(cmd), serial_timeout(serial,
+ strlen(cmd)))) < (int)strlen(cmd)) {
+ sr_err("Unable to send command.");
+ return SR_ERR;
+ }
+
+ /* Read the reply (blocking, with timeout). */
+ memset(replybuf, 0, replybufsize);
+ bufptr = replybuf;
+ len = replybufsize;
+ ret = serial_readline(serial, &bufptr, &len, READ_TIMEOUT_MS);
+
+ /* If we got 0 characters (possibly one \r or \n), retry once. */
+ if (len == 0) {
+ len = replybufsize;
+ ret = serial_readline(serial, &bufptr, &len, READ_TIMEOUT_MS);
+ }
+
+ if (g_str_has_prefix((const char *)&bufptr, "err ")) {
+ sr_err("Device replied with an error: '%s'.", bufptr);
+ return SR_ERR;
+ }
+
+ return ret;
+}
+
+SR_PRIV int reloadpro_set_current_limit(const struct sr_dev_inst *sdi,
+ float current)
+{
+ int ret, ma;
+ char buf[100];
+ char *cmd;
+
+ if (current < 0 || current > 6) {
+ sr_err("The current limit must be 0-6 A (was %f A).", current);
+ return SR_ERR_ARG;
+ }
+
+ /* Hardware expects current in mA, integer (0..6000). */
+ ma = (int)(current * 1000);
+
+ sr_err("Setting current limit to %f A (%d mA).", current, ma);
+
+ cmd = g_strdup_printf("set %d\n", ma);
+ if ((ret = send_cmd(sdi, cmd, (char *)&buf, sizeof(buf))) < 0) {
+ sr_err("Error sending current limit command: %d.", ret);
+ g_free(cmd);
+ return SR_ERR;
+ }
+ g_free(cmd);
+
+ return SR_OK;
+}
+
+SR_PRIV int reloadpro_set_on_off(const struct sr_dev_inst *sdi, gboolean on)
+{
+ int ret;
+ char buf[100];
+ const char *cmd;
+
+ cmd = (on) ? "on\n" : "off\n";
+ if ((ret = send_cmd(sdi, cmd, (char *)&buf, sizeof(buf))) < 0) {
+ sr_err("Error sending on/off command: %d.", ret);
+ return SR_ERR;
+ }
+
+ return SR_OK;
+}
+
+SR_PRIV int reloadpro_get_current_limit(const struct sr_dev_inst *sdi,
+ float *current)
+{
+ int ret;
+ char buf[100];
+
+ if ((ret = send_cmd(sdi, "set\n", (char *)&buf, sizeof(buf))) < 0) {
+ sr_err("Error sending current limit query: %d.", ret);
+ return SR_ERR;
+ }
+
+ /* Hardware sends current in mA, integer (0..6000). */
+ *current = g_ascii_strtod(buf + 4, NULL) / 1000;
+
+ return SR_OK;
+}
+
+SR_PRIV int reloadpro_get_voltage_current(const struct sr_dev_inst *sdi,
+ float *voltage, float *current)
+{
+ int ret;
+ char buf[100];
+ char **tokens;
+
+ if ((ret = send_cmd(sdi, "read\n", (char *)&buf, sizeof(buf))) < 0) {
+ sr_err("Error sending voltage/current query: %d.", ret);
+ return SR_ERR;
+ }
+
+ /* Reply: "read <current> <voltage>". */
+ tokens = g_strsplit((const char *)&buf, " ", 3);
+ if (voltage)
+ *voltage = g_ascii_strtod(tokens[2], NULL) / 1000;
+ if (current)
+ *current = g_ascii_strtod(tokens[1], NULL) / 1000;
+ g_strfreev(tokens);
+
+ return SR_OK;
+}
+
+static void handle_packet(const struct sr_dev_inst *sdi)