Skip to content

Commit 0e4a85a

Browse files
committed
serial_bt: support more key=value parameters for conn=bt/ specs
Extend the syntax for conn=bt/ specs. Accept RFCOMM channel numbers, as well as BLE handles for RX, TX, and CCCD, as well as a CCCD value. This allows users to unbreak their "cables" without necessity of adjusting source code.
1 parent 0f63fbe commit 0e4a85a

File tree

1 file changed

+85
-2
lines changed

1 file changed

+85
-2
lines changed

src/serial_bt.c

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
#define SER_BT_CONN_PREFIX "bt"
3333
#define SER_BT_CHUNK_SIZE 1200
3434

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+
3541
/**
3642
* @file
3743
*
@@ -145,6 +151,10 @@ static int ser_bt_parse_conn_spec(
145151
char **fields, *field;
146152
enum ser_bt_conn_t type;
147153
const char *addr;
154+
int ret_parse, ret;
155+
size_t fields_count, field_idx;
156+
char *endp;
157+
unsigned long parm_val;
148158

149159
if (conn_type)
150160
*conn_type = SER_BT_CONN_UNKNOWN;
@@ -241,10 +251,83 @@ static int ser_bt_parse_conn_spec(
241251
return SR_ERR_ARG;
242252
}
243253

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+
}
245328

246329
g_strfreev(fields);
247-
return SR_OK;
330+
return ret_parse;
248331
}
249332

250333
static void ser_bt_mask_databits(struct sr_serial_dev_inst *serial,

0 commit comments

Comments
 (0)