X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fserial_bt.c;h=977f248b5eb4b62fc682a939fe7664cda4c63789;hb=HEAD;hp=a9041ce874cda66f47c4baf90b436bd9aab79697;hpb=c622c88c446a2f5e1c045657ef233c147a1f43d4;p=libsigrok.git diff --git a/src/serial_bt.c b/src/serial_bt.c index a9041ce8..977f248b 100644 --- a/src/serial_bt.c +++ b/src/serial_bt.c @@ -37,6 +37,7 @@ #define SER_BT_PARAM_PREFIX_HDL_TX "handle_tx=" #define SER_BT_PARAM_PREFIX_HDL_CCCD "handle_cccd=" #define SER_BT_PARAM_PREFIX_VAL_CCCD "value_cccd=" +#define SER_BT_PARAM_PREFIX_BLE_MTU "mtu=" /** * @file @@ -54,25 +55,68 @@ /* {{{ support for serial-over-BT channels */ +/* + * This builtin database of known devices (keyed by their names as + * provided during BT/BLE scans) can help improve the presentation of + * scan results. Ideally users could take the output and pass it to + * subsequent program invocations, not having to "come up with" the + * conn= spec, or only having to touch it up minimally. GUI dialogs + * could present scan results such that users just need to pick an + * item to open a connection. + * + * The current implementation guesses connection types from device + * names, and optionally amends them with additional parameters if + * experience shows that individual devices need these extra specs. + * + * This database may have to move to a separate source file should + * its size grow to amounts that are considered inappropriate here + * in the serial transport's BT dispatcher. For now the item count + * is small. + */ + static const struct scan_supported_item { const char *name; enum ser_bt_conn_t type; const char *add_params; } scan_supported_items[] = { - /* Guess connection types from device names (useful for scans). */ { "121GW", SER_BT_CONN_BLE122, NULL, }, { "Adafruit Bluefruit LE 8134", SER_BT_CONN_NRF51, NULL, }, + { "DL24M_BLE", SER_BT_CONN_AC6328, NULL, }, + { "DL24M_SPP", SER_BT_CONN_RFCOMM, "/channel=2", }, { "HC-05", SER_BT_CONN_RFCOMM, NULL, }, + { "TC66C", SER_BT_CONN_DIALOG, "/mtu=200", }, + { "UC96_BLE", SER_BT_CONN_AC6328, NULL, }, + { "UC96_SPP", SER_BT_CONN_RFCOMM, "/channel=2", }, { "UM25C", SER_BT_CONN_RFCOMM, NULL, }, { NULL, SER_BT_CONN_UNKNOWN, NULL, }, }; +static const struct scan_supported_item *scan_is_supported(const char *name) +{ + size_t idx; + const struct scan_supported_item *item; + + for (idx = 0; idx < ARRAY_SIZE(scan_supported_items); idx++) { + item = &scan_supported_items[idx]; + if (!item->name) + break; + if (strcmp(name, item->name) != 0) + continue; + return item; + } + + return NULL; +} + static const char *ser_bt_conn_names[SER_BT_CONN_MAX] = { [SER_BT_CONN_UNKNOWN] = "", [SER_BT_CONN_RFCOMM] = "rfcomm", [SER_BT_CONN_BLE122] = "ble122", [SER_BT_CONN_NRF51] = "nrf51", [SER_BT_CONN_CC254x] = "cc254x", + [SER_BT_CONN_AC6328] = "ac6328", + [SER_BT_CONN_DIALOG] = "dialog", + [SER_BT_CONN_NOTIFY] = "notify", }; static enum ser_bt_conn_t lookup_conn_name(const char *name) @@ -150,7 +194,8 @@ static int ser_bt_parse_conn_spec( enum ser_bt_conn_t *conn_type, const char **remote_addr, size_t *rfcomm_channel, uint16_t *read_hdl, uint16_t *write_hdl, - uint16_t *cccd_hdl, uint16_t *cccd_val) + uint16_t *cccd_hdl, uint16_t *cccd_val, + uint16_t *ble_mtu) { char **fields, *field; enum ser_bt_conn_t type; @@ -174,6 +219,8 @@ static int ser_bt_parse_conn_spec( *cccd_hdl = 0; if (cccd_val) *cccd_val = 0; + if (ble_mtu) + *ble_mtu = 0; if (!serial || !spec || !spec[0]) return SR_ERR_ARG; @@ -251,6 +298,33 @@ static int ser_bt_parse_conn_spec( if (cccd_val) *cccd_val = 0x0001; break; + case SER_BT_CONN_AC6328: + if (read_hdl) + *read_hdl = 12; + if (write_hdl) + *write_hdl = 15; + if (cccd_hdl) + *cccd_hdl = 13; + if (cccd_val) + *cccd_val = 0x0001; + break; + case SER_BT_CONN_DIALOG: + if (read_hdl) + *read_hdl = 23; + if (write_hdl) + *write_hdl = 18; + if (cccd_hdl) + *cccd_hdl = 0; + if (cccd_val) + *cccd_val = 0x0001; + if (ble_mtu) + *ble_mtu = 400; + break; + case SER_BT_CONN_NOTIFY: + /* All other values must be provided externally. */ + if (cccd_val) + *cccd_val = 0x0001; + break; default: return SR_ERR_ARG; } @@ -327,6 +401,18 @@ static int ser_bt_parse_conn_spec( *cccd_val = parm_val; continue; } + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_BLE_MTU)) { + field += strlen(SER_BT_PARAM_PREFIX_BLE_MTU); + endp = NULL; + ret = sr_atoul_base(field, &parm_val, &endp, 0); + if (ret != SR_OK || !endp || *endp != '\0') { + ret_parse = SR_ERR_ARG; + break; + } + if (ble_mtu) + *ble_mtu = parm_val; + continue; + } return SR_ERR_DATA; } @@ -358,6 +444,11 @@ static int ser_bt_data_cb(void *cb_data, uint8_t *data, size_t dlen) if (!serial) return -1; + if (!data && dlen) + return -1; + if (!data || !dlen) + return 0; + ser_bt_mask_databits(serial, data, dlen); sr_ser_queue_rx_data(serial, data, dlen); @@ -396,6 +487,7 @@ static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags) const char *remote_addr; size_t rfcomm_channel; uint16_t read_hdl, write_hdl, cccd_hdl, cccd_val; + uint16_t ble_mtu; int rc; struct sr_bt_desc *desc; @@ -406,7 +498,8 @@ static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags) &conn_type, &remote_addr, &rfcomm_channel, &read_hdl, &write_hdl, - &cccd_hdl, &cccd_val); + &cccd_hdl, &cccd_val, + &ble_mtu); if (rc != SR_OK) return SR_ERR_ARG; @@ -434,14 +527,19 @@ static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags) case SER_BT_CONN_BLE122: case SER_BT_CONN_NRF51: case SER_BT_CONN_CC254x: + case SER_BT_CONN_AC6328: + case SER_BT_CONN_DIALOG: + case SER_BT_CONN_NOTIFY: rc = sr_bt_config_notify(desc, - read_hdl, write_hdl, cccd_hdl, cccd_val); + read_hdl, write_hdl, cccd_hdl, cccd_val, + ble_mtu); if (rc < 0) return SR_ERR; serial->bt_notify_handle_read = read_hdl; serial->bt_notify_handle_write = write_hdl; serial->bt_notify_handle_cccd = cccd_hdl; serial->bt_notify_value_cccd = cccd_val; + serial->bt_ble_mtu = ble_mtu; break; default: /* Unsupported type, or incomplete implementation. */ @@ -466,6 +564,9 @@ static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags) case SER_BT_CONN_BLE122: case SER_BT_CONN_NRF51: case SER_BT_CONN_CC254x: + case SER_BT_CONN_AC6328: + case SER_BT_CONN_DIALOG: + case SER_BT_CONN_NOTIFY: rc = sr_bt_connect_ble(desc); if (rc < 0) return SR_ERR; @@ -542,6 +643,9 @@ static int ser_bt_write(struct sr_serial_dev_inst *serial, case SER_BT_CONN_BLE122: case SER_BT_CONN_NRF51: case SER_BT_CONN_CC254x: + case SER_BT_CONN_AC6328: + case SER_BT_CONN_DIALOG: + case SER_BT_CONN_NOTIFY: /* * Assume that when applications call the serial layer's * write routine, then the BLE chip/module does support @@ -607,6 +711,9 @@ static int ser_bt_read(struct sr_serial_dev_inst *serial, case SER_BT_CONN_BLE122: case SER_BT_CONN_NRF51: case SER_BT_CONN_CC254x: + case SER_BT_CONN_AC6328: + case SER_BT_CONN_DIALOG: + case SER_BT_CONN_NOTIFY: dlen = sr_ser_has_queued_data(serial); rc = sr_bt_check_notify(serial->bt_desc); if (rc < 0) @@ -704,6 +811,9 @@ static int bt_source_cb(int fd, int revents, void *cb_data) case SER_BT_CONN_BLE122: case SER_BT_CONN_NRF51: case SER_BT_CONN_CC254x: + case SER_BT_CONN_AC6328: + case SER_BT_CONN_DIALOG: + case SER_BT_CONN_NOTIFY: dlen = sr_ser_has_queued_data(serial); rc = sr_bt_check_notify(serial->bt_desc); if (rc < 0) @@ -781,23 +891,6 @@ static int ser_bt_setup_source_remove(struct sr_session *session, return SR_OK; } -static const struct scan_supported_item *scan_is_supported(const char *name) -{ - size_t idx; - const struct scan_supported_item *item; - - for (idx = 0; idx < ARRAY_SIZE(scan_supported_items); idx++) { - item = &scan_supported_items[idx]; - if (!item->name) - break; - if (strcmp(name, item->name) != 0) - continue; - return item; - } - - return NULL; -} - struct bt_scan_args_t { GSList *port_list; sr_ser_list_append_t append;