|
32 | 32 | #define SER_BT_CONN_PREFIX "bt" |
33 | 33 | #define SER_BT_CHUNK_SIZE 1200 |
34 | 34 |
|
| 35 | +#define SER_BT_PARAM_PREFIX_CHANNEL "channel=" |
| 36 | +#define SER_BT_PARAM_PREFIX_HDL_RX "handle_rx=" |
| 37 | +#define SER_BT_PARAM_PREFIX_HDL_TX "handle_tx=" |
| 38 | +#define SER_BT_PARAM_PREFIX_HDL_CCCD "handle_cccd=" |
| 39 | +#define SER_BT_PARAM_PREFIX_VAL_CCCD "value_cccd=" |
| 40 | + |
35 | 41 | /** |
36 | 42 | * @file |
37 | 43 | * |
@@ -145,6 +151,10 @@ static int ser_bt_parse_conn_spec( |
145 | 151 | char **fields, *field; |
146 | 152 | enum ser_bt_conn_t type; |
147 | 153 | const char *addr; |
| 154 | + int ret_parse, ret; |
| 155 | + size_t fields_count, field_idx; |
| 156 | + char *endp; |
| 157 | + unsigned long parm_val; |
148 | 158 |
|
149 | 159 | if (conn_type) |
150 | 160 | *conn_type = SER_BT_CONN_UNKNOWN; |
@@ -241,10 +251,83 @@ static int ser_bt_parse_conn_spec( |
241 | 251 | return SR_ERR_ARG; |
242 | 252 | } |
243 | 253 |
|
244 | | - /* TODO Evaluate optionally trailing fields, override defaults? */ |
| 254 | + /* |
| 255 | + * Preset a successful return value for the conn= parse call. |
| 256 | + * Scan optional additional fields which specify more params. |
| 257 | + * Update the defaults which were setup above. Pessimize the |
| 258 | + * routine's return value in error paths. |
| 259 | + */ |
| 260 | + ret_parse = SR_OK; |
| 261 | + fields_count = g_strv_length(fields); |
| 262 | + for (field_idx = 3; field_idx < fields_count; field_idx++) { |
| 263 | + field = fields[field_idx]; |
| 264 | + if (!field || !*field) |
| 265 | + continue; |
| 266 | + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_CHANNEL)) { |
| 267 | + field += strlen(SER_BT_PARAM_PREFIX_CHANNEL); |
| 268 | + endp = NULL; |
| 269 | + ret = sr_atoul_base(field, &parm_val, &endp, 0); |
| 270 | + if (ret != SR_OK || !endp || *endp != '\0') { |
| 271 | + ret_parse = SR_ERR_ARG; |
| 272 | + break; |
| 273 | + } |
| 274 | + if (rfcomm_channel) |
| 275 | + *rfcomm_channel = parm_val; |
| 276 | + continue; |
| 277 | + } |
| 278 | + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_RX)) { |
| 279 | + field += strlen(SER_BT_PARAM_PREFIX_HDL_RX); |
| 280 | + endp = NULL; |
| 281 | + ret = sr_atoul_base(field, &parm_val, &endp, 0); |
| 282 | + if (ret != SR_OK || !endp || *endp != '\0') { |
| 283 | + ret_parse = SR_ERR_ARG; |
| 284 | + break; |
| 285 | + } |
| 286 | + if (read_hdl) |
| 287 | + *read_hdl = parm_val; |
| 288 | + continue; |
| 289 | + } |
| 290 | + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_TX)) { |
| 291 | + field += strlen(SER_BT_PARAM_PREFIX_HDL_TX); |
| 292 | + endp = NULL; |
| 293 | + ret = sr_atoul_base(field, &parm_val, &endp, 0); |
| 294 | + if (ret != SR_OK || !endp || *endp != '\0') { |
| 295 | + ret_parse = SR_ERR_ARG; |
| 296 | + break; |
| 297 | + } |
| 298 | + if (write_hdl) |
| 299 | + *write_hdl = parm_val; |
| 300 | + continue; |
| 301 | + } |
| 302 | + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_CCCD)) { |
| 303 | + field += strlen(SER_BT_PARAM_PREFIX_HDL_CCCD); |
| 304 | + endp = NULL; |
| 305 | + ret = sr_atoul_base(field, &parm_val, &endp, 0); |
| 306 | + if (ret != SR_OK || !endp || *endp != '\0') { |
| 307 | + ret_parse = SR_ERR_ARG; |
| 308 | + break; |
| 309 | + } |
| 310 | + if (cccd_hdl) |
| 311 | + *cccd_hdl = parm_val; |
| 312 | + continue; |
| 313 | + } |
| 314 | + if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_VAL_CCCD)) { |
| 315 | + field += strlen(SER_BT_PARAM_PREFIX_VAL_CCCD); |
| 316 | + endp = NULL; |
| 317 | + ret = sr_atoul_base(field, &parm_val, &endp, 0); |
| 318 | + if (ret != SR_OK || !endp || *endp != '\0') { |
| 319 | + ret_parse = SR_ERR_ARG; |
| 320 | + break; |
| 321 | + } |
| 322 | + if (cccd_val) |
| 323 | + *cccd_val = parm_val; |
| 324 | + continue; |
| 325 | + } |
| 326 | + return SR_ERR_DATA; |
| 327 | + } |
245 | 328 |
|
246 | 329 | g_strfreev(fields); |
247 | | - return SR_OK; |
| 330 | + return ret_parse; |
248 | 331 | } |
249 | 332 |
|
250 | 333 | static void ser_bt_mask_databits(struct sr_serial_dev_inst *serial, |
|
0 commit comments