]> sigrok.org Git - libsigrok.git/blob - src/serial_bt.c
strutil: add more space in hexdumps after 8 and 16 data bytes
[libsigrok.git] / src / serial_bt.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2018-2019 Gerhard Sittig <gerhard.sittig@gmx.net>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <glib.h>
22 #include <libsigrok/libsigrok.h>
23 #include "libsigrok-internal.h"
24 #include <string.h>
25 #include <memory.h>
26
27 #define LOG_PREFIX "serial-bt"
28
29 #ifdef HAVE_SERIAL_COMM
30 #ifdef HAVE_BLUETOOTH
31
32 #define SER_BT_CONN_PREFIX      "bt"
33 #define SER_BT_CHUNK_SIZE       1200
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
41 /**
42  * @file
43  *
44  * Serial port handling, wraps the external BT/BLE dependencies.
45  */
46
47 /**
48  * @defgroup grp_serial_bt Serial port handling, BT/BLE group
49  *
50  * Make serial-over-BT communication appear like a regular serial port.
51  *
52  * @{
53  */
54
55 /* {{{ support for serial-over-BT channels */
56
57 /*
58  * This builtin database of known devices (keyed by their names as
59  * provided during BT/BLE scans) can help improve the presentation of
60  * scan results. Ideally users could take the output and pass it to
61  * subsequent program invocations, not having to "come up with" the
62  * conn= spec, or only having to touch it up minimally. GUI dialogs
63  * could present scan results such that users just need to pick an
64  * item to open a connection.
65  *
66  * The current implementation guesses connection types from device
67  * names, and optionally amends them with additional parameters if
68  * experience shows that individual devices need these extra specs.
69  *
70  * This database may have to move to a separate source file should
71  * its size grow to amounts that are considered inappropriate here
72  * in the serial transport's BT dispatcher. For now the item count
73  * is small.
74  */
75
76 static const struct scan_supported_item {
77         const char *name;
78         enum ser_bt_conn_t type;
79         const char *add_params;
80 } scan_supported_items[] = {
81         { "121GW", SER_BT_CONN_BLE122, NULL, },
82         { "Adafruit Bluefruit LE 8134", SER_BT_CONN_NRF51, NULL, },
83         { "DL24M_BLE", SER_BT_CONN_AC6328, NULL, },
84         { "DL24M_SPP", SER_BT_CONN_RFCOMM, "/channel=2", },
85         { "HC-05", SER_BT_CONN_RFCOMM, NULL, },
86         { "UC96_BLE", SER_BT_CONN_AC6328, NULL, },
87         { "UC96_SPP", SER_BT_CONN_RFCOMM, "/channel=2", },
88         { "UM25C", SER_BT_CONN_RFCOMM, NULL, },
89         { NULL, SER_BT_CONN_UNKNOWN, NULL, },
90 };
91
92 static const struct scan_supported_item *scan_is_supported(const char *name)
93 {
94         size_t idx;
95         const struct scan_supported_item *item;
96
97         for (idx = 0; idx < ARRAY_SIZE(scan_supported_items); idx++) {
98                 item = &scan_supported_items[idx];
99                 if (!item->name)
100                         break;
101                 if (strcmp(name, item->name) != 0)
102                         continue;
103                 return item;
104         }
105
106         return NULL;
107 }
108
109 static const char *ser_bt_conn_names[SER_BT_CONN_MAX] = {
110         [SER_BT_CONN_UNKNOWN] = "<type>",
111         [SER_BT_CONN_RFCOMM] = "rfcomm",
112         [SER_BT_CONN_BLE122] = "ble122",
113         [SER_BT_CONN_NRF51] = "nrf51",
114         [SER_BT_CONN_CC254x] = "cc254x",
115         [SER_BT_CONN_AC6328] = "ac6328",
116 };
117
118 static enum ser_bt_conn_t lookup_conn_name(const char *name)
119 {
120         size_t idx;
121         const char *item;
122
123         if (!name || !*name)
124                 return SER_BT_CONN_UNKNOWN;
125         idx = ARRAY_SIZE(ser_bt_conn_names);
126         while (idx-- > 0) {
127                 item = ser_bt_conn_names[idx];
128                 if (strcmp(item, name) == 0)
129                         return idx;
130         }
131
132         return SER_BT_CONN_UNKNOWN;
133 }
134
135 static const char *conn_name_text(enum ser_bt_conn_t type)
136 {
137         if (type >= ARRAY_SIZE(ser_bt_conn_names))
138                 type = SER_BT_CONN_UNKNOWN;
139
140         return ser_bt_conn_names[type];
141 }
142
143 /**
144  * Parse conn= specs for serial over Bluetooth communication.
145  *
146  * @param[in] serial The serial port that is about to get opened.
147  * @param[in] spec The caller provided conn= specification.
148  * @param[out] conn_type The type of BT comm (BT RFCOMM, BLE notify).
149  * @param[out] remote_addr The remote device address.
150  * @param[out] rfcomm_channel The RFCOMM channel (if applicable).
151  * @param[out] read_hdl The BLE notify read handle (if applicable).
152  * @param[out] write_hdl The BLE notify write handle (if applicable).
153  * @param[out] cccd_hdl The BLE notify CCCD handle (if applicable).
154  * @param[out] cccd_val The BLE notify CCCD value (if applicable).
155  *
156  * @return 0 upon success, non-zero upon failure.
157  *
158  * Summary of parsing rules as they are implemented:
159  * - Implementor's note: Automatic scan for available devices is not
160  *   yet implemented. So strictly speaking some parts of the input
161  *   spec are optional, but fallbacks may not take effect ATM.
162  * - Insist on the "bt" prefix. Accept "bt" alone without any other
163  *   additional field.
164  * - The first field that follows is the connection type. Supported
165  *   types are 'rfcomm', 'ble122', 'cc254x', and potentially others
166  *   in a future implementation.
167  * - The next field is the remote device's address, either separated
168  *   by colons or dashes or spaces, or not separated at all.
169  * - Other parameters (RFCOMM channel, notify handles and write values)
170  *   get derived from the connection type.
171  * - More fields after the remote address are options which override
172  *   builtin defaults (RFCOMM channels, BLE handles, etc).
173  *
174  * Supported formats resulting from these rules:
175  *   bt/<conn>/<addr>[/<param>]...
176  *
177  * Examples:
178  *   bt/rfcomm/11-22-33-44-55-66
179  *   bt/rfcomm/11-22-33-44-55-66/channel=2
180  *   bt/ble122/88:6b:12:34:56:78
181  *   bt/cc254x/0123456789ab
182  *
183  * It's assumed that users easily can create those conn= specs from
184  * available information, or that scan routines will create such specs
185  * that copy'n'paste results (or GUI choices from previous scan results)
186  * can get processed here.
187  */
188 static int ser_bt_parse_conn_spec(
189         struct sr_serial_dev_inst *serial, const char *spec,
190         enum ser_bt_conn_t *conn_type, const char **remote_addr,
191         size_t *rfcomm_channel,
192         uint16_t *read_hdl, uint16_t *write_hdl,
193         uint16_t *cccd_hdl, uint16_t *cccd_val)
194 {
195         char **fields, *field;
196         enum ser_bt_conn_t type;
197         const char *addr;
198         int ret_parse, ret;
199         size_t fields_count, field_idx;
200         char *endp;
201         unsigned long parm_val;
202
203         if (conn_type)
204                 *conn_type = SER_BT_CONN_UNKNOWN;
205         if (remote_addr)
206                 *remote_addr = NULL;
207         if (rfcomm_channel)
208                 *rfcomm_channel = 0;
209         if (read_hdl)
210                 *read_hdl = 0;
211         if (write_hdl)
212                 *write_hdl = 0;
213         if (cccd_hdl)
214                 *cccd_hdl = 0;
215         if (cccd_val)
216                 *cccd_val = 0;
217
218         if (!serial || !spec || !spec[0])
219                 return SR_ERR_ARG;
220
221         /* Evaluate the mandatory first three fields. */
222         fields = g_strsplit_set(spec, "/", 0);
223         if (!fields)
224                 return SR_ERR_ARG;
225         if (g_strv_length(fields) < 3) {
226                 g_strfreev(fields);
227                 return SR_ERR_ARG;
228         }
229         field = fields[0];
230         if (strcmp(field, SER_BT_CONN_PREFIX) != 0) {
231                 g_strfreev(fields);
232                 return SR_ERR_ARG;
233         }
234         field = fields[1];
235         type = lookup_conn_name(field);
236         if (!type) {
237                 g_strfreev(fields);
238                 return SR_ERR_ARG;
239         }
240         if (conn_type)
241                 *conn_type = type;
242         field = fields[2];
243         if (!field || !*field) {
244                 g_strfreev(fields);
245                 return SR_ERR_ARG;
246         }
247         addr = g_strdup(field);
248         if (remote_addr)
249                 *remote_addr = addr;
250
251         /* Derive default parameters that match the connection type. */
252         /* TODO Lookup defaults from a table? */
253         switch (type) {
254         case SER_BT_CONN_RFCOMM:
255                 if (rfcomm_channel)
256                         *rfcomm_channel = 1;
257                 break;
258         case SER_BT_CONN_BLE122:
259                 if (read_hdl)
260                         *read_hdl = 8;
261                 if (write_hdl)
262                         *write_hdl = 0;
263                 if (cccd_hdl)
264                         *cccd_hdl = 9;
265                 if (cccd_val)
266                         *cccd_val = 0x0003;
267                 break;
268         case SER_BT_CONN_NRF51:
269                 /* TODO
270                  * Are these values appropriate? Check the learn article at
271                  * https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend?view=all
272                  */
273                 if (read_hdl)
274                         *read_hdl = 13;
275                 if (write_hdl)
276                         *write_hdl = 11;
277                 if (cccd_hdl)
278                         *cccd_hdl = 14;
279                 if (cccd_val)
280                         *cccd_val = 0x0001;
281                 /* TODO 'random' type, sec-level=high */
282                 break;
283         case SER_BT_CONN_CC254x:
284                 /* TODO Are these values appropriate? Just guessing here. */
285                 if (read_hdl)
286                         *read_hdl = 20;
287                 if (write_hdl)
288                         *write_hdl = 0;
289                 if (cccd_hdl)
290                         *cccd_hdl = 21;
291                 if (cccd_val)
292                         *cccd_val = 0x0001;
293                 break;
294         case SER_BT_CONN_AC6328:
295                 if (read_hdl)
296                         *read_hdl = 12;
297                 if (write_hdl)
298                         *write_hdl = 15;
299                 if (cccd_hdl)
300                         *cccd_hdl = 13;
301                 if (cccd_val)
302                         *cccd_val = 0x0001;
303                 break;
304         default:
305                 return SR_ERR_ARG;
306         }
307
308         /*
309          * Preset a successful return value for the conn= parse call.
310          * Scan optional additional fields which specify more params.
311          * Update the defaults which were setup above. Pessimize the
312          * routine's return value in error paths.
313          */
314         ret_parse = SR_OK;
315         fields_count = g_strv_length(fields);
316         for (field_idx = 3; field_idx < fields_count; field_idx++) {
317                 field = fields[field_idx];
318                 if (!field || !*field)
319                         continue;
320                 if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_CHANNEL)) {
321                         field += strlen(SER_BT_PARAM_PREFIX_CHANNEL);
322                         endp = NULL;
323                         ret = sr_atoul_base(field, &parm_val, &endp, 0);
324                         if (ret != SR_OK || !endp || *endp != '\0') {
325                                 ret_parse = SR_ERR_ARG;
326                                 break;
327                         }
328                         if (rfcomm_channel)
329                                 *rfcomm_channel = parm_val;
330                         continue;
331                 }
332                 if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_RX)) {
333                         field += strlen(SER_BT_PARAM_PREFIX_HDL_RX);
334                         endp = NULL;
335                         ret = sr_atoul_base(field, &parm_val, &endp, 0);
336                         if (ret != SR_OK || !endp || *endp != '\0') {
337                                 ret_parse = SR_ERR_ARG;
338                                 break;
339                         }
340                         if (read_hdl)
341                                 *read_hdl = parm_val;
342                         continue;
343                 }
344                 if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_TX)) {
345                         field += strlen(SER_BT_PARAM_PREFIX_HDL_TX);
346                         endp = NULL;
347                         ret = sr_atoul_base(field, &parm_val, &endp, 0);
348                         if (ret != SR_OK || !endp || *endp != '\0') {
349                                 ret_parse = SR_ERR_ARG;
350                                 break;
351                         }
352                         if (write_hdl)
353                                 *write_hdl = parm_val;
354                         continue;
355                 }
356                 if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_HDL_CCCD)) {
357                         field += strlen(SER_BT_PARAM_PREFIX_HDL_CCCD);
358                         endp = NULL;
359                         ret = sr_atoul_base(field, &parm_val, &endp, 0);
360                         if (ret != SR_OK || !endp || *endp != '\0') {
361                                 ret_parse = SR_ERR_ARG;
362                                 break;
363                         }
364                         if (cccd_hdl)
365                                 *cccd_hdl = parm_val;
366                         continue;
367                 }
368                 if (g_str_has_prefix(field, SER_BT_PARAM_PREFIX_VAL_CCCD)) {
369                         field += strlen(SER_BT_PARAM_PREFIX_VAL_CCCD);
370                         endp = NULL;
371                         ret = sr_atoul_base(field, &parm_val, &endp, 0);
372                         if (ret != SR_OK || !endp || *endp != '\0') {
373                                 ret_parse = SR_ERR_ARG;
374                                 break;
375                         }
376                         if (cccd_val)
377                                 *cccd_val = parm_val;
378                         continue;
379                 }
380                 return SR_ERR_DATA;
381         }
382
383         g_strfreev(fields);
384         return ret_parse;
385 }
386
387 static void ser_bt_mask_databits(struct sr_serial_dev_inst *serial,
388         uint8_t *data, size_t len)
389 {
390         uint32_t mask32;
391         uint8_t mask;
392         size_t idx;
393
394         if ((serial->comm_params.data_bits % 8) == 0)
395                 return;
396
397         mask32 = (1UL << serial->comm_params.data_bits) - 1;
398         mask = mask32 & 0xff;
399         for (idx = 0; idx < len; idx++)
400                 data[idx] &= mask;
401 }
402
403 static int ser_bt_data_cb(void *cb_data, uint8_t *data, size_t dlen)
404 {
405         struct sr_serial_dev_inst *serial;
406
407         serial = cb_data;
408         if (!serial)
409                 return -1;
410
411         ser_bt_mask_databits(serial, data, dlen);
412         sr_ser_queue_rx_data(serial, data, dlen);
413
414         return 0;
415 }
416
417 /* }}} */
418 /* {{{ wrap serial-over-BT operations in a common serial.c API */
419
420 /* See if a serial port's name refers to a BT type. */
421 SR_PRIV int ser_name_is_bt(struct sr_serial_dev_inst *serial)
422 {
423         size_t off;
424         char sep;
425
426         if (!serial)
427                 return 0;
428         if (!serial->port || !*serial->port)
429                 return 0;
430
431         /* Accept either "bt" alone, or "bt/" as a prefix. */
432         if (!g_str_has_prefix(serial->port, SER_BT_CONN_PREFIX))
433                 return 0;
434         off = strlen(SER_BT_CONN_PREFIX);
435         sep = serial->port[off];
436         if (sep != '\0' && sep != '/')
437                 return 0;
438
439         return 1;
440 }
441
442 /* The open() wrapper for BT ports. */
443 static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags)
444 {
445         enum ser_bt_conn_t conn_type;
446         const char *remote_addr;
447         size_t rfcomm_channel;
448         uint16_t read_hdl, write_hdl, cccd_hdl, cccd_val;
449         int rc;
450         struct sr_bt_desc *desc;
451
452         (void)flags;
453
454         /* Derive BT specific parameters from the port spec. */
455         rc = ser_bt_parse_conn_spec(serial, serial->port,
456                         &conn_type, &remote_addr,
457                         &rfcomm_channel,
458                         &read_hdl, &write_hdl,
459                         &cccd_hdl, &cccd_val);
460         if (rc != SR_OK)
461                 return SR_ERR_ARG;
462
463         if (!conn_type || !remote_addr || !remote_addr[0]) {
464                 /* TODO Auto-search for available connections? */
465                 return SR_ERR_NA;
466         }
467
468         /* Create the connection. Only store params after successful use. */
469         desc = sr_bt_desc_new();
470         if (!desc)
471                 return SR_ERR;
472         serial->bt_desc = desc;
473         rc = sr_bt_config_addr_remote(desc, remote_addr);
474         if (rc < 0)
475                 return SR_ERR;
476         serial->bt_addr_remote = g_strdup(remote_addr);
477         switch (conn_type) {
478         case SER_BT_CONN_RFCOMM:
479                 rc = sr_bt_config_rfcomm(desc, rfcomm_channel);
480                 if (rc < 0)
481                         return SR_ERR;
482                 serial->bt_rfcomm_channel = rfcomm_channel;
483                 break;
484         case SER_BT_CONN_BLE122:
485         case SER_BT_CONN_NRF51:
486         case SER_BT_CONN_CC254x:
487         case SER_BT_CONN_AC6328:
488                 rc = sr_bt_config_notify(desc,
489                         read_hdl, write_hdl, cccd_hdl, cccd_val);
490                 if (rc < 0)
491                         return SR_ERR;
492                 serial->bt_notify_handle_read = read_hdl;
493                 serial->bt_notify_handle_write = write_hdl;
494                 serial->bt_notify_handle_cccd = cccd_hdl;
495                 serial->bt_notify_value_cccd = cccd_val;
496                 break;
497         default:
498                 /* Unsupported type, or incomplete implementation. */
499                 return SR_ERR_ARG;
500         }
501         serial->bt_conn_type = conn_type;
502
503         /* Make sure the receive buffer can accept input data. */
504         if (!serial->rcv_buffer)
505                 serial->rcv_buffer = g_string_sized_new(SER_BT_CHUNK_SIZE);
506         rc = sr_bt_config_cb_data(desc, ser_bt_data_cb, serial);
507         if (rc < 0)
508                 return SR_ERR;
509
510         /* Open the connection. */
511         switch (conn_type) {
512         case SER_BT_CONN_RFCOMM:
513                 rc = sr_bt_connect_rfcomm(desc);
514                 if (rc < 0)
515                         return SR_ERR;
516                 break;
517         case SER_BT_CONN_BLE122:
518         case SER_BT_CONN_NRF51:
519         case SER_BT_CONN_CC254x:
520         case SER_BT_CONN_AC6328:
521                 rc = sr_bt_connect_ble(desc);
522                 if (rc < 0)
523                         return SR_ERR;
524                 rc = sr_bt_start_notify(desc);
525                 if (rc < 0)
526                         return SR_ERR;
527                 break;
528         default:
529                 return SR_ERR_ARG;
530         }
531
532         return SR_OK;
533 }
534
535 static int ser_bt_close(struct sr_serial_dev_inst *serial)
536 {
537         if (!serial)
538                 return SR_ERR_ARG;
539
540         if (!serial->bt_desc)
541                 return SR_OK;
542
543         sr_bt_disconnect(serial->bt_desc);
544         sr_bt_desc_free(serial->bt_desc);
545         serial->bt_desc = NULL;
546
547         g_free(serial->bt_addr_local);
548         serial->bt_addr_local = NULL;
549         g_free(serial->bt_addr_remote);
550         serial->bt_addr_remote = NULL;
551         g_slist_free_full(serial->bt_source_args, g_free);
552         serial->bt_source_args = NULL;
553
554         return SR_OK;
555 }
556
557 /* Flush, discards pending RX data, empties buffers. */
558 static int ser_bt_flush(struct sr_serial_dev_inst *serial)
559 {
560         (void)serial;
561         /* EMPTY */
562
563         return SR_OK;
564 }
565
566 /* Drain, waits for completion of pending TX data. */
567 static int ser_bt_drain(struct sr_serial_dev_inst *serial)
568 {
569         (void)serial;
570         /* EMPTY */     /* TODO? */
571
572         return SR_ERR_BUG;
573 }
574
575 static int ser_bt_write(struct sr_serial_dev_inst *serial,
576                 const void *buf, size_t count,
577                 int nonblocking, unsigned int timeout_ms)
578 {
579         ssize_t wrlen;
580
581         /*
582          * TODO Support chunked transmission when callers' requests
583          * exceed the BT channel's capacity? See ser_hid_write().
584          */
585
586         switch (serial->bt_conn_type) {
587         case SER_BT_CONN_RFCOMM:
588                 (void)nonblocking;
589                 (void)timeout_ms;
590                 wrlen = sr_bt_write(serial->bt_desc, buf, count);
591                 if (wrlen < 0)
592                         return SR_ERR_IO;
593                 return wrlen;
594         case SER_BT_CONN_BLE122:
595         case SER_BT_CONN_NRF51:
596         case SER_BT_CONN_CC254x:
597         case SER_BT_CONN_AC6328:
598                 /*
599                  * Assume that when applications call the serial layer's
600                  * write routine, then the BLE chip/module does support
601                  * a TX handle. Just call the serial-BT library's write
602                  * routine.
603                  */
604                 (void)nonblocking;
605                 (void)timeout_ms;
606                 wrlen = sr_bt_write(serial->bt_desc, buf, count);
607                 if (wrlen < 0)
608                         return SR_ERR_IO;
609                 return wrlen;
610         default:
611                 return SR_ERR_ARG;
612         }
613         /* UNREACH */
614 }
615
616 static int ser_bt_read(struct sr_serial_dev_inst *serial,
617                 void *buf, size_t count,
618                 int nonblocking, unsigned int timeout_ms)
619 {
620         gint64 deadline_us, now_us;
621         uint8_t buffer[SER_BT_CHUNK_SIZE];
622         ssize_t rdlen;
623         int rc;
624         size_t dlen;
625
626         /*
627          * Immediately satisfy the caller's request from the RX buffer
628          * if the requested amount of data is available already.
629          */
630         if (sr_ser_has_queued_data(serial) >= count)
631                 return sr_ser_unqueue_rx_data(serial, buf, count);
632
633         /*
634          * When a timeout was specified, then determine the deadline
635          * where to stop reception.
636          */
637         deadline_us = 0;
638         if (timeout_ms) {
639                 now_us = g_get_monotonic_time();
640                 deadline_us = now_us + timeout_ms * 1000;
641         }
642
643         /*
644          * Keep receiving from the port until the caller's requested
645          * amount of data has become available, or the timeout has
646          * expired. In the absence of a timeout, stop reading when an
647          * attempt no longer yields receive data.
648          */
649         while (TRUE) {
650                 /* Run another attempt to receive data. */
651                 switch (serial->bt_conn_type) {
652                 case SER_BT_CONN_RFCOMM:
653                         rdlen = sr_bt_read(serial->bt_desc, buffer, sizeof(buffer));
654                         if (rdlen <= 0)
655                                 break;
656                         rc = ser_bt_data_cb(serial, buffer, rdlen);
657                         if (rc < 0)
658                                 rdlen = -1;
659                         break;
660                 case SER_BT_CONN_BLE122:
661                 case SER_BT_CONN_NRF51:
662                 case SER_BT_CONN_CC254x:
663                 case SER_BT_CONN_AC6328:
664                         dlen = sr_ser_has_queued_data(serial);
665                         rc = sr_bt_check_notify(serial->bt_desc);
666                         if (rc < 0)
667                                 rdlen = -1;
668                         else if (sr_ser_has_queued_data(serial) != dlen)
669                                 rdlen = +1;
670                         else
671                                 rdlen = 0;
672                         break;
673                 default:
674                         rdlen = -1;
675                         break;
676                 }
677
678                 /*
679                  * Stop upon receive errors, or timeout expiration. Only
680                  * stop upon empty reception in the absence of a timeout.
681                  */
682                 if (rdlen < 0)
683                         break;
684                 if (nonblocking && !rdlen)
685                         break;
686                 if (deadline_us) {
687                         now_us = g_get_monotonic_time();
688                         if (now_us > deadline_us)
689                                 break;
690                 }
691
692                 /* Also stop when sufficient data has become available. */
693                 if (sr_ser_has_queued_data(serial) >= count)
694                         break;
695         }
696
697         /*
698          * Satisfy the caller's demand for receive data from previously
699          * queued incoming data.
700          */
701         dlen = sr_ser_has_queued_data(serial);
702         if (dlen > count)
703                 dlen = count;
704         if (!dlen)
705                 return 0;
706
707         return sr_ser_unqueue_rx_data(serial, buf, dlen);
708 }
709
710 struct bt_source_args_t {
711         /* The application callback. */
712         sr_receive_data_callback cb;
713         void *cb_data;
714         /* The serial device, to store RX data. */
715         struct sr_serial_dev_inst *serial;
716 };
717
718 /*
719  * Gets periodically invoked by the glib main loop. "Drives" (checks)
720  * progress of BT communication, and invokes the application's callback
721  * which processes RX data (when some has become available), as well as
722  * handles application level timeouts.
723  */
724 static int bt_source_cb(int fd, int revents, void *cb_data)
725 {
726         struct bt_source_args_t *args;
727         struct sr_serial_dev_inst *serial;
728         uint8_t rx_buf[SER_BT_CHUNK_SIZE];
729         ssize_t rdlen;
730         size_t dlen;
731         int rc;
732
733         args = cb_data;
734         if (!args)
735                 return -1;
736         serial = args->serial;
737         if (!serial)
738                 return -1;
739         if (!serial->bt_conn_type)
740                 return -1;
741
742         /*
743          * Drain receive data which the channel might have pending.
744          * This is "a copy" of the "background part" of ser_bt_read(),
745          * without the timeout support code, and not knowing how much
746          * data the application is expecting.
747          */
748         do {
749                 switch (serial->bt_conn_type) {
750                 case SER_BT_CONN_RFCOMM:
751                         rdlen = sr_bt_read(serial->bt_desc, rx_buf, sizeof(rx_buf));
752                         if (rdlen <= 0)
753                                 break;
754                         rc = ser_bt_data_cb(serial, rx_buf, rdlen);
755                         if (rc < 0)
756                                 rdlen = -1;
757                         break;
758                 case SER_BT_CONN_BLE122:
759                 case SER_BT_CONN_NRF51:
760                 case SER_BT_CONN_CC254x:
761                 case SER_BT_CONN_AC6328:
762                         dlen = sr_ser_has_queued_data(serial);
763                         rc = sr_bt_check_notify(serial->bt_desc);
764                         if (rc < 0)
765                                 rdlen = -1;
766                         else if (sr_ser_has_queued_data(serial) != dlen)
767                                 rdlen = +1;
768                         else
769                                 rdlen = 0;
770                         break;
771                 default:
772                         rdlen = -1;
773                         break;
774                 }
775         } while (rdlen > 0);
776
777         /*
778          * When RX data became available (now or earlier), pass this
779          * condition to the application callback. Always periodically
780          * run the application callback, since it handles timeouts and
781          * might carry out other tasks as well like signalling progress.
782          */
783         if (sr_ser_has_queued_data(args->serial))
784                 revents |= G_IO_IN;
785         rc = args->cb(fd, revents, args->cb_data);
786
787         return rc;
788 }
789
790 /* TODO Can we use the Bluetooth socket's file descriptor? Probably not portably. */
791 #define WITH_MAXIMUM_TIMEOUT_VALUE      0
792 static int ser_bt_setup_source_add(struct sr_session *session,
793                 struct sr_serial_dev_inst *serial,
794                 int events, int timeout,
795                 sr_receive_data_callback cb, void *cb_data)
796 {
797         struct bt_source_args_t *args;
798         int rc;
799
800         (void)events;
801
802         /* Optionally enforce a minimum poll period. */
803         if (WITH_MAXIMUM_TIMEOUT_VALUE && timeout > WITH_MAXIMUM_TIMEOUT_VALUE)
804                 timeout = WITH_MAXIMUM_TIMEOUT_VALUE;
805
806         /* Allocate status container for background data reception. */
807         args = g_malloc0(sizeof(*args));
808         args->cb = cb;
809         args->cb_data = cb_data;
810         args->serial = serial;
811
812         /*
813          * Have a periodic timer installed. Register the allocated block
814          * with the serial device, since the GSource's finalizer won't
815          * free the memory, and we haven't bothered to create a custom
816          * BT specific GSource.
817          */
818         rc = sr_session_source_add(session, -1, events, timeout, bt_source_cb, args);
819         if (rc != SR_OK) {
820                 g_free(args);
821                 return rc;
822         }
823         serial->bt_source_args = g_slist_append(serial->bt_source_args, args);
824
825         return SR_OK;
826 }
827
828 static int ser_bt_setup_source_remove(struct sr_session *session,
829                 struct sr_serial_dev_inst *serial)
830 {
831         (void)serial;
832
833         (void)sr_session_source_remove(session, -1);
834         /* Release callback args here already? */
835
836         return SR_OK;
837 }
838
839 struct bt_scan_args_t {
840         GSList *port_list;
841         sr_ser_list_append_t append;
842         GSList *addr_list;
843         const char *bt_type;
844 };
845
846 static void scan_cb(void *cb_args, const char *addr, const char *name)
847 {
848         struct bt_scan_args_t *scan_args;
849         GSList *l;
850         char addr_text[20];
851         const struct scan_supported_item *item;
852         enum ser_bt_conn_t type;
853         char *port_name, *port_desc;
854         char *addr_copy;
855
856         scan_args = cb_args;
857         if (!scan_args)
858                 return;
859         sr_info("BT scan, found: %s - %s\n", addr, name);
860
861         /* Check whether the device was seen before. */
862         for (l = scan_args->addr_list; l; l = l->next) {
863                 if (strcmp(addr, l->data) == 0)
864                         return;
865         }
866
867         /* Substitute colons in the address by dashes. */
868         if (!addr || !*addr)
869                 return;
870         snprintf(addr_text, sizeof(addr_text), "%s", addr);
871         g_strcanon(addr_text, "0123456789abcdefABCDEF", '-');
872
873         /* Create a port name, and a description. */
874         item = scan_is_supported(name);
875         type = item ? item->type : SER_BT_CONN_UNKNOWN;
876         port_name = g_strdup_printf("%s/%s/%s%s",
877                 SER_BT_CONN_PREFIX, conn_name_text(type), addr_text,
878                 (item && item->add_params) ? item->add_params : "");
879         port_desc = g_strdup_printf("%s (%s)", name, scan_args->bt_type);
880
881         scan_args->port_list = scan_args->append(scan_args->port_list, port_name, port_desc);
882         g_free(port_name);
883         g_free(port_desc);
884
885         /* Keep track of the handled address. */
886         addr_copy = g_strdup(addr);
887         scan_args->addr_list = g_slist_append(scan_args->addr_list, addr_copy);
888 }
889
890 static GSList *ser_bt_list(GSList *list, sr_ser_list_append_t append)
891 {
892         static const int scan_duration = 3;
893
894         struct bt_scan_args_t scan_args;
895         struct sr_bt_desc *desc;
896
897         /*
898          * Implementor's note: This "list" routine is best-effort. We
899          * assume that registering callbacks always succeeds. Silently
900          * ignore failure to scan for devices. Just return those which
901          * we happen to find.
902          */
903
904         desc = sr_bt_desc_new();
905         if (!desc)
906                 return list;
907
908         memset(&scan_args, 0, sizeof(scan_args));
909         scan_args.port_list = list;
910         scan_args.append = append;
911
912         scan_args.addr_list = NULL;
913         scan_args.bt_type = "BT";
914         (void)sr_bt_config_cb_scan(desc, scan_cb, &scan_args);
915         (void)sr_bt_scan_bt(desc, scan_duration);
916         g_slist_free_full(scan_args.addr_list, g_free);
917
918         scan_args.addr_list = NULL;
919         scan_args.bt_type = "BLE";
920         (void)sr_bt_config_cb_scan(desc, scan_cb, &scan_args);
921         (void)sr_bt_scan_le(desc, scan_duration);
922         g_slist_free_full(scan_args.addr_list, g_free);
923
924         sr_bt_desc_free(desc);
925
926         return scan_args.port_list;
927 }
928
929 static struct ser_lib_functions serlib_bt = {
930         .open = ser_bt_open,
931         .close = ser_bt_close,
932         .flush = ser_bt_flush,
933         .drain = ser_bt_drain,
934         .write = ser_bt_write,
935         .read = ser_bt_read,
936         /*
937          * Bluetooth communication has no concept of bitrate, so ignore
938          * these arguments silently. Neither need we pass the frame format
939          * down to internal BT comm routines, nor need we keep the values
940          * here, since the caller will cache/register them already.
941          */
942         .set_params = std_dummy_set_params,
943         .set_handshake = std_dummy_set_handshake,
944         .setup_source_add = ser_bt_setup_source_add,
945         .setup_source_remove = ser_bt_setup_source_remove,
946         .list = ser_bt_list,
947         .get_frame_format = NULL,
948 };
949 SR_PRIV struct ser_lib_functions *ser_lib_funcs_bt = &serlib_bt;
950
951 /* }}} */
952 #else
953
954 SR_PRIV int ser_name_is_bt(struct sr_serial_dev_inst *serial)
955 {
956         (void)serial;
957
958         return 0;
959 }
960
961 SR_PRIV struct ser_lib_functions *ser_lib_funcs_bt = NULL;
962
963 #endif
964 #endif
965
966 /** @} */