+ struct sr_dev_inst *sdi;
+ struct dev_context *devc;
+ struct sr_probe *probe;
+ uint32_t tmp_int, ui;
+ uint8_t key, type, token;
+ GString *tmp_str, *devname, *version;
+ guchar tmp_c;
+
+ sdi = sr_dev_inst_new(0, SR_ST_INACTIVE, NULL, NULL, NULL);
+ sdi->driver = odi;
+ devc = ols_dev_new();
+ sdi->priv = devc;
+
+ devname = g_string_new("");
+ version = g_string_new("");
+
+ key = 0xff;
+ while (key) {
+ if (serial_read(fd, &key, 1) != 1 || key == 0x00)
+ break;
+ type = key >> 5;
+ token = key & 0x1f;
+ switch (type) {
+ case 0:
+ /* NULL-terminated string */
+ tmp_str = g_string_new("");
+ while (serial_read(fd, &tmp_c, 1) == 1 && tmp_c != '\0')
+ g_string_append_c(tmp_str, tmp_c);
+ sr_dbg("ols: got metadata key 0x%.2x value '%s'",
+ key, tmp_str->str);
+ switch (token) {
+ case 0x01:
+ /* Device name */
+ devname = g_string_append(devname, tmp_str->str);
+ break;
+ case 0x02:
+ /* FPGA firmware version */
+ if (version->len)
+ g_string_append(version, ", ");
+ g_string_append(version, "FPGA version ");
+ g_string_append(version, tmp_str->str);
+ break;
+ case 0x03:
+ /* Ancillary version */
+ if (version->len)
+ g_string_append(version, ", ");
+ g_string_append(version, "Ancillary version ");
+ g_string_append(version, tmp_str->str);
+ break;
+ default:
+ sr_info("ols: unknown token 0x%.2x: '%s'",
+ token, tmp_str->str);
+ break;
+ }
+ g_string_free(tmp_str, TRUE);
+ break;
+ case 1:
+ /* 32-bit unsigned integer */
+ if (serial_read(fd, &tmp_int, 4) != 4)
+ break;
+ tmp_int = reverse32(tmp_int);
+ sr_dbg("ols: got metadata key 0x%.2x value 0x%.8x",
+ key, tmp_int);
+ switch (token) {
+ case 0x00:
+ /* Number of usable probes */
+ for (ui = 0; ui < tmp_int; ui++) {
+ if (!(probe = sr_probe_new(ui, SR_PROBE_LOGIC, TRUE,
+ probe_names[ui])))
+ return 0;
+ sdi->probes = g_slist_append(sdi->probes, probe);
+ }
+ break;
+ case 0x01:
+ /* Amount of sample memory available (bytes) */
+ devc->max_samples = tmp_int;
+ break;
+ case 0x02:
+ /* Amount of dynamic memory available (bytes) */
+ /* what is this for? */
+ break;
+ case 0x03:
+ /* Maximum sample rate (hz) */
+ devc->max_samplerate = tmp_int;
+ break;
+ case 0x04:
+ /* protocol version */
+ devc->protocol_version = tmp_int;
+ break;
+ default:
+ sr_info("ols: unknown token 0x%.2x: 0x%.8x",
+ token, tmp_int);
+ break;
+ }
+ break;
+ case 2:
+ /* 8-bit unsigned integer */
+ if (serial_read(fd, &tmp_c, 1) != 1)
+ break;
+ sr_dbg("ols: got metadata key 0x%.2x value 0x%.2x",
+ key, tmp_c);
+ switch (token) {
+ case 0x00:
+ /* Number of usable probes */
+ for (ui = 0; ui < tmp_c; ui++) {
+ if (!(probe = sr_probe_new(ui, SR_PROBE_LOGIC, TRUE,
+ probe_names[ui])))
+ return 0;
+ sdi->probes = g_slist_append(sdi->probes, probe);
+ }
+ break;
+ case 0x01:
+ /* protocol version */
+ devc->protocol_version = tmp_c;
+ break;
+ default:
+ sr_info("ols: unknown token 0x%.2x: 0x%.2x",
+ token, tmp_c);
+ break;
+ }
+ break;
+ default:
+ /* unknown type */
+ break;
+ }
+ }
+
+ sdi->model = devname->str;
+ sdi->version = version->str;
+ g_string_free(devname, FALSE);
+ g_string_free(version, FALSE);