X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fserial_bt.c;h=a851dad8c6fff16a1e2874b7fb165a08b41c11b3;hb=b7721913feb5f4dfdbbe0ad60dd6cf931757998b;hp=42d6289a51126b9f10db2d55e978add48404eaa4;hpb=82b9f3d116ce0c982291a2dfdd15cd8a1c4cc16e;p=libsigrok.git diff --git a/src/serial_bt.c b/src/serial_bt.c index 42d6289a..a851dad8 100644 --- a/src/serial_bt.c +++ b/src/serial_bt.c @@ -32,6 +32,12 @@ #define SER_BT_CONN_PREFIX "bt" #define SER_BT_CHUNK_SIZE 1200 +#define SER_BT_PARAM_PREFIX_CHANNEL "channel=" +#define SER_BT_PARAM_PREFIX_HDL_RX "handle_rx=" +#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=" + /** * @file * @@ -142,9 +148,13 @@ static int ser_bt_parse_conn_spec( uint16_t *read_hdl, uint16_t *write_hdl, uint16_t *cccd_hdl, uint16_t *cccd_val) { + char **fields, *field; enum ser_bt_conn_t type; const char *addr; - char **fields, *field; + int ret_parse, ret; + size_t fields_count, field_idx; + char *endp; + unsigned long parm_val; if (conn_type) *conn_type = SER_BT_CONN_UNKNOWN; @@ -161,9 +171,6 @@ static int ser_bt_parse_conn_spec( if (cccd_val) *cccd_val = 0; - type = SER_BT_CONN_UNKNOWN; - addr = NULL; - if (!serial || !spec || !spec[0]) return SR_ERR_ARG; @@ -244,10 +251,83 @@ static int ser_bt_parse_conn_spec( return SR_ERR_ARG; } - /* TODO Evaluate optionally trailing fields, override defaults? */ + /* + * Preset a successful return value for the conn= parse call. + * Scan optional additional fields which specify more params. + * Update the defaults which were setup above. Pessimize the + * routine's return value in error paths. + */ + ret_parse = SR_OK; + fields_count = g_strv_length(fields); + for (field_idx = 3; field_idx < fields_count; field_idx++) { + field = fields[field_idx]; + if (!field || !*field) + continue; + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_CHANNEL)) { + field += strlen(SER_BT_PARAM_PREFIX_CHANNEL); + 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 (rfcomm_channel) + *rfcomm_channel = parm_val; + continue; + } + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_RX)) { + field += strlen(SER_BT_PARAM_PREFIX_HDL_RX); + 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 (read_hdl) + *read_hdl = parm_val; + continue; + } + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_TX)) { + field += strlen(SER_BT_PARAM_PREFIX_HDL_TX); + 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 (write_hdl) + *write_hdl = parm_val; + continue; + } + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_CCCD)) { + field += strlen(SER_BT_PARAM_PREFIX_HDL_CCCD); + 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 (cccd_hdl) + *cccd_hdl = parm_val; + continue; + } + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_VAL_CCCD)) { + field += strlen(SER_BT_PARAM_PREFIX_VAL_CCCD); + 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 (cccd_val) + *cccd_val = parm_val; + continue; + } + return SR_ERR_DATA; + } g_strfreev(fields); - return SR_OK; + return ret_parse; } static void ser_bt_mask_databits(struct sr_serial_dev_inst *serial, @@ -498,7 +578,6 @@ static int ser_bt_read(struct sr_serial_dev_inst *serial, * where to stop reception. */ deadline_us = 0; - now_us = 0; /* Silence a (false) compiler warning. */ if (timeout_ms) { now_us = g_get_monotonic_time(); deadline_us = now_us + timeout_ms * 1000; @@ -816,6 +895,7 @@ static struct ser_lib_functions serlib_bt = { * here, since the caller will cache/register them already. */ .set_params = std_dummy_set_params, + .set_handshake = std_dummy_set_handshake, .setup_source_add = ser_bt_setup_source_add, .setup_source_remove = ser_bt_setup_source_remove, .list = ser_bt_list,