-
- analog->mqflags = 0;
-
- /* Give some debug info about the package. */
- asciilen = hdr->len - 4;
- sr_dbg("DMM flags: %.2x %.2x %.2x %.2x",
- bfunc[3], bfunc[2], bfunc[1], bfunc[0]);
- /* Value is an ASCII string. */
- sr_dbg("DMM packet: \"%.*s\"", asciilen, bfunc + 4);
-
- parse_flags(buf, &flags);
- if (parse_value((const char *)(bfunc + 4), asciilen, floatval) != SR_OK)
+ txt = (const char *)&bfunc[4];
+ txtlen = hdr->len - 4;
+ sr_dbg("DMM bfunc: %02x %02x %02x %02x, text '%.*s'",
+ bfunc[3], bfunc[2], bfunc[1], bfunc[0], txtlen, txt);
+
+ memset(&flags, 0, sizeof(flags));
+ parse_flags(bfunc, &flags);
+ if (flags.is_decibel && flags.is_ohm) {
+ /*
+ * The reference impedance for the dBm function is in an
+ * unexpected format. Naive conversion of non-space chars
+ * gives incorrect results. Isolate the 4..1200 Ohms value
+ * instead, ignore the "0." and exponent parts of the
+ * response text.
+ */
+ if (strncmp(txt, " 0.", strlen(" 0.")) == 0 && strstr(txt, " E")) {
+ txt = &txt[strlen(" 0.")];
+ txtlen -= strlen(" 0.");
+ p = strchr(txt, 'E');
+ if (p)
+ *p = '\0';
+ }
+ }
+ if (flags.is_fahrenheit || flags.is_celsius) {
+ /*
+ * The value text in temperature mode includes the C/F
+ * suffix between the mantissa and the exponent, which
+ * breaks the text to number conversion. Example data:
+ * " 0.0217CE+3". Remove the C/F unit identifier.
+ */
+ unit = strchr(txt, flags.is_fahrenheit ? 'F' : 'C');
+ if (!unit)
+ return SR_ERR;
+ *unit = ' ';
+ }
+ ret = parse_value(txt, txtlen, floatval);
+ sr_dbg("floatval: %f, ret %d", *floatval, ret);
+ if (ret != SR_OK)