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