+/**
+ * Read single byte from serial port.
+ *
+ * @retval -1 Timeout or error.
+ * @retval other Byte.
+ */
+static int read_byte(struct sr_serial_dev_inst *serial, gint64 timeout)
+{
+ uint8_t result = 0;
+ int rc = 0;
+
+ for (;;) {
+ rc = serial_read(serial, &result, 1);
+ if (rc == 1) {
+ sr_spew("read: 0x%02x/%d", result, result);
+ return result;
+ }
+ if (g_get_monotonic_time() > timeout)
+ return -1;
+ g_usleep(2000);
+ }
+}
+
+/**
+ * Try to detect GMC 1x/2x multimeter model in send mode for max. 1 second.
+ *
+ * @param serial Configured, open serial port.
+ *
+ * @retval NULL Detection failed.
+ * @retval other Model code.
+ */
+static enum model scan_model_sm(struct sr_serial_dev_inst *serial)
+{
+ int byte, bytecnt, cnt;
+ enum model model;
+ gint64 timeout_us;
+
+ model = METRAHIT_NONE;
+ timeout_us = g_get_monotonic_time() + 1 * 1000 * 1000;
+
+ /*
+ * Try to find message consisting of device code and several
+ * (at least 4) data bytes.
+ */
+ for (bytecnt = 0; bytecnt < 100; bytecnt++) {
+ byte = read_byte(serial, timeout_us);
+ if ((byte == -1) || (timeout_us < g_get_monotonic_time()))
+ break;
+ if ((byte & MSGID_MASK) == MSGID_INF) {
+ if (!(model = gmc_decode_model_sm(byte & MSGC_MASK)))
+ break;
+ /* Now expect (at least) 4 data bytes. */
+ for (cnt = 0; cnt < 4; cnt++) {
+ byte = read_byte(serial, timeout_us);
+ if ((byte == -1) ||
+ ((byte & MSGID_MASK) != MSGID_DATA))
+ {
+ model = METRAHIT_NONE;
+ bytecnt = 100;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return model;
+}
+
+/**
+ * Scan for Metrahit 1x and Metrahit 2x in send mode using Gossen Metrawatt
+ * 'RS232' interface.
+ *
+ * The older 1x models use 8192 baud and the newer 2x 9600 baud.
+ * The DMM usually sends up to about 20 messages per second. However, depending
+ * on configuration and measurement mode the intervals can be much larger and
+ * then the detection might not work.
+ */