]> sigrok.org Git - libsigrok.git/blob - src/serial_bt.c
33abec0ff481715993920aed1fc57a59433c44a7
[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         if (!data && dlen)
412                 return -1;
413         if (!data || !dlen)
414                 return 0;
415
416         ser_bt_mask_databits(serial, data, dlen);
417         sr_ser_queue_rx_data(serial, data, dlen);
418
419         return 0;
420 }
421
422 /* }}} */
423 /* {{{ wrap serial-over-BT operations in a common serial.c API */
424
425 /* See if a serial port's name refers to a BT type. */
426 SR_PRIV int ser_name_is_bt(struct sr_serial_dev_inst *serial)
427 {
428         size_t off;
429         char sep;
430
431         if (!serial)
432                 return 0;
433         if (!serial->port || !*serial->port)
434                 return 0;
435
436         /* Accept either "bt" alone, or "bt/" as a prefix. */
437         if (!g_str_has_prefix(serial->port, SER_BT_CONN_PREFIX))
438                 return 0;
439         off = strlen(SER_BT_CONN_PREFIX);
440         sep = serial->port[off];
441         if (sep != '\0' && sep != '/')
442                 return 0;
443
444         return 1;
445 }
446
447 /* The open() wrapper for BT ports. */
448 static int ser_bt_open(struct sr_serial_dev_inst *serial, int flags)
449 {
450         enum ser_bt_conn_t conn_type;
451         const char *remote_addr;
452         size_t rfcomm_channel;
453         uint16_t read_hdl, write_hdl, cccd_hdl, cccd_val;
454         int rc;
455         struct sr_bt_desc *desc;
456
457         (void)flags;
458
459         /* Derive BT specific parameters from the port spec. */
460         rc = ser_bt_parse_conn_spec(serial, serial->port,
461                         &conn_type, &remote_addr,
462                         &rfcomm_channel,
463                         &read_hdl, &write_hdl,
464                         &cccd_hdl, &cccd_val);
465         if (rc != SR_OK)
466                 return SR_ERR_ARG;
467
468         if (!conn_type || !remote_addr || !remote_addr[0]) {
469                 /* TODO Auto-search for available connections? */
470                 return SR_ERR_NA;
471         }
472
473         /* Create the connection. Only store params after successful use. */
474         desc = sr_bt_desc_new();
475         if (!desc)
476                 return SR_ERR;
477         serial->bt_desc = desc;
478         rc = sr_bt_config_addr_remote(desc, remote_addr);
479         if (rc < 0)
480                 return SR_ERR;
481         serial->bt_addr_remote = g_strdup(remote_addr);
482         switch (conn_type) {
483         case SER_BT_CONN_RFCOMM:
484                 rc = sr_bt_config_rfcomm(desc, rfcomm_channel);
485                 if (rc < 0)
486                         return SR_ERR;
487                 serial->bt_rfcomm_channel = rfcomm_channel;
488                 break;
489         case SER_BT_CONN_BLE122:
490         case SER_BT_CONN_NRF51:
491         case SER_BT_CONN_CC254x:
492         case SER_BT_CONN_AC6328:
493                 rc = sr_bt_config_notify(desc,
494                         read_hdl, write_hdl, cccd_hdl, cccd_val);
495                 if (rc < 0)
496                         return SR_ERR;
497                 serial->bt_notify_handle_read = read_hdl;
498                 serial->bt_notify_handle_write = write_hdl;
499                 serial->bt_notify_handle_cccd = cccd_hdl;
500                 serial->bt_notify_value_cccd = cccd_val;
501                 break;
502         default:
503                 /* Unsupported type, or incomplete implementation. */
504                 return SR_ERR_ARG;
505         }
506         serial->bt_conn_type = conn_type;
507
508         /* Make sure the receive buffer can accept input data. */
509         if (!serial->rcv_buffer)
510                 serial->rcv_buffer = g_string_sized_new(SER_BT_CHUNK_SIZE);
511         rc = sr_bt_config_cb_data(desc, ser_bt_data_cb, serial);
512         if (rc < 0)
513                 return SR_ERR;
514
515         /* Open the connection. */
516         switch (conn_type) {
517         case SER_BT_CONN_RFCOMM:
518                 rc = sr_bt_connect_rfcomm(desc);
519                 if (rc < 0)
520                         return SR_ERR;
521                 break;
522         case SER_BT_CONN_BLE122:
523         case SER_BT_CONN_NRF51:
524         case SER_BT_CONN_CC254x:
525         case SER_BT_CONN_AC6328:
526                 rc = sr_bt_connect_ble(desc);
527                 if (rc < 0)
528                         return SR_ERR;
529                 rc = sr_bt_start_notify(desc);
530                 if (rc < 0)
531                         return SR_ERR;
532                 break;
533         default:
534                 return SR_ERR_ARG;
535         }
536
537         return SR_OK;
538 }
539
540 static int ser_bt_close(struct sr_serial_dev_inst *serial)
541 {
542         if (!serial)
543                 return SR_ERR_ARG;
544
545         if (!serial->bt_desc)
546                 return SR_OK;
547
548         sr_bt_disconnect(serial->bt_desc);
549         sr_bt_desc_free(serial->bt_desc);
550         serial->bt_desc = NULL;
551
552         g_free(serial->bt_addr_local);
553         serial->bt_addr_local = NULL;
554         g_free(serial->bt_addr_remote);
555         serial->bt_addr_remote = NULL;
556         g_slist_free_full(serial->bt_source_args, g_free);
557         serial->bt_source_args = NULL;
558
559         return SR_OK;
560 }
561
562 /* Flush, discards pending RX data, empties buffers. */
563 static int ser_bt_flush(struct sr_serial_dev_inst *serial)
564 {
565         (void)serial;
566         /* EMPTY */
567
568         return SR_OK;
569 }
570
571 /* Drain, waits for completion of pending TX data. */
572 static int ser_bt_drain(struct sr_serial_dev_inst *serial)
573 {
574         (void)serial;
575         /* EMPTY */     /* TODO? */
576
577         return SR_ERR_BUG;
578 }
579
580 static int ser_bt_write(struct sr_serial_dev_inst *serial,
581                 const void *buf, size_t count,
582                 int nonblocking, unsigned int timeout_ms)
583 {
584         ssize_t wrlen;
585
586         /*
587          * TODO Support chunked transmission when callers' requests
588          * exceed the BT channel's capacity? See ser_hid_write().
589          */
590
591         switch (serial->bt_conn_type) {
592         case SER_BT_CONN_RFCOMM:
593                 (void)nonblocking;
594                 (void)timeout_ms;
595                 wrlen = sr_bt_write(serial->bt_desc, buf, count);
596                 if (wrlen < 0)
597                         return SR_ERR_IO;
598                 return wrlen;
599         case SER_BT_CONN_BLE122:
600         case SER_BT_CONN_NRF51:
601         case SER_BT_CONN_CC254x:
602         case SER_BT_CONN_AC6328:
603                 /*
604                  * Assume that when applications call the serial layer's
605                  * write routine, then the BLE chip/module does support
606                  * a TX handle. Just call the serial-BT library's write
607                  * routine.
608                  */
609                 (void)nonblocking;
610                 (void)timeout_ms;
611                 wrlen = sr_bt_write(serial->bt_desc, buf, count);
612                 if (wrlen < 0)
613                         return SR_ERR_IO;
614                 return wrlen;
615         default:
616                 return SR_ERR_ARG;
617         }
618         /* UNREACH */
619 }
620
621 static int ser_bt_read(struct sr_serial_dev_inst *serial,
622                 void *buf, size_t count,
623                 int nonblocking, unsigned int timeout_ms)
624 {
625         gint64 deadline_us, now_us;
626         uint8_t buffer[SER_BT_CHUNK_SIZE];
627         ssize_t rdlen;
628         int rc;
629         size_t dlen;
630
631         /*
632          * Immediately satisfy the caller's request from the RX buffer
633          * if the requested amount of data is available already.
634          */
635         if (sr_ser_has_queued_data(serial) >= count)
636                 return sr_ser_unqueue_rx_data(serial, buf, count);
637
638         /*
639          * When a timeout was specified, then determine the deadline
640          * where to stop reception.
641          */
642         deadline_us = 0;
643         if (timeout_ms) {
644                 now_us = g_get_monotonic_time();
645                 deadline_us = now_us + timeout_ms * 1000;
646         }
647
648         /*
649          * Keep receiving from the port until the caller's requested
650          * amount of data has become available, or the timeout has
651          * expired. In the absence of a timeout, stop reading when an
652          * attempt no longer yields receive data.
653          */
654         while (TRUE) {
655                 /* Run another attempt to receive data. */
656                 switch (serial->bt_conn_type) {
657                 case SER_BT_CONN_RFCOMM:
658                         rdlen = sr_bt_read(serial->bt_desc, buffer, sizeof(buffer));
659                         if (rdlen <= 0)
660                                 break;
661                         rc = ser_bt_data_cb(serial, buffer, rdlen);
662                         if (rc < 0)
663                                 rdlen = -1;
664                         break;
665                 case SER_BT_CONN_BLE122:
666                 case SER_BT_CONN_NRF51:
667                 case SER_BT_CONN_CC254x:
668                 case SER_BT_CONN_AC6328:
669                         dlen = sr_ser_has_queued_data(serial);
670                         rc = sr_bt_check_notify(serial->bt_desc);
671                         if (rc < 0)
672                                 rdlen = -1;
673                         else if (sr_ser_has_queued_data(serial) != dlen)
674                                 rdlen = +1;
675                         else
676                                 rdlen = 0;
677                         break;
678                 default:
679                         rdlen = -1;
680                         break;
681                 }
682
683                 /*
684                  * Stop upon receive errors, or timeout expiration. Only
685                  * stop upon empty reception in the absence of a timeout.
686                  */
687                 if (rdlen < 0)
688                         break;
689                 if (nonblocking && !rdlen)
690                         break;
691                 if (deadline_us) {
692                         now_us = g_get_monotonic_time();
693                         if (now_us > deadline_us)
694                                 break;
695                 }
696
697                 /* Also stop when sufficient data has become available. */
698                 if (sr_ser_has_queued_data(serial) >= count)
699                         break;
700         }
701
702         /*
703          * Satisfy the caller's demand for receive data from previously
704          * queued incoming data.
705          */
706         dlen = sr_ser_has_queued_data(serial);
707         if (dlen > count)
708                 dlen = count;
709         if (!dlen)
710                 return 0;
711
712         return sr_ser_unqueue_rx_data(serial, buf, dlen);
713 }
714
715 struct bt_source_args_t {
716         /* The application callback. */
717         sr_receive_data_callback cb;
718         void *cb_data;
719         /* The serial device, to store RX data. */
720         struct sr_serial_dev_inst *serial;
721 };
722
723 /*
724  * Gets periodically invoked by the glib main loop. "Drives" (checks)
725  * progress of BT communication, and invokes the application's callback
726  * which processes RX data (when some has become available), as well as
727  * handles application level timeouts.
728  */
729 static int bt_source_cb(int fd, int revents, void *cb_data)
730 {
731         struct bt_source_args_t *args;
732         struct sr_serial_dev_inst *serial;
733         uint8_t rx_buf[SER_BT_CHUNK_SIZE];
734         ssize_t rdlen;
735         size_t dlen;
736         int rc;
737
738         args = cb_data;
739         if (!args)
740                 return -1;
741         serial = args->serial;
742         if (!serial)
743                 return -1;
744         if (!serial->bt_conn_type)
745                 return -1;
746
747         /*
748          * Drain receive data which the channel might have pending.
749          * This is "a copy" of the "background part" of ser_bt_read(),
750          * without the timeout support code, and not knowing how much
751          * data the application is expecting.
752          */
753         do {
754                 switch (serial->bt_conn_type) {
755                 case SER_BT_CONN_RFCOMM:
756                         rdlen = sr_bt_read(serial->bt_desc, rx_buf, sizeof(rx_buf));
757                         if (rdlen <= 0)
758                                 break;
759                         rc = ser_bt_data_cb(serial, rx_buf, rdlen);
760                         if (rc < 0)
761                                 rdlen = -1;
762                         break;
763                 case SER_BT_CONN_BLE122:
764                 case SER_BT_CONN_NRF51:
765                 case SER_BT_CONN_CC254x:
766                 case SER_BT_CONN_AC6328:
767                         dlen = sr_ser_has_queued_data(serial);
768                         rc = sr_bt_check_notify(serial->bt_desc);
769                         if (rc < 0)
770                                 rdlen = -1;
771                         else if (sr_ser_has_queued_data(serial) != dlen)
772                                 rdlen = +1;
773                         else
774                                 rdlen = 0;
775                         break;
776                 default:
777                         rdlen = -1;
778                         break;
779                 }
780         } while (rdlen > 0);
781
782         /*
783          * When RX data became available (now or earlier), pass this
784          * condition to the application callback. Always periodically
785          * run the application callback, since it handles timeouts and
786          * might carry out other tasks as well like signalling progress.
787          */
788         if (sr_ser_has_queued_data(args->serial))
789                 revents |= G_IO_IN;
790         rc = args->cb(fd, revents, args->cb_data);
791
792         return rc;
793 }
794
795 /* TODO Can we use the Bluetooth socket's file descriptor? Probably not portably. */
796 #define WITH_MAXIMUM_TIMEOUT_VALUE      0
797 static int ser_bt_setup_source_add(struct sr_session *session,
798                 struct sr_serial_dev_inst *serial,
799                 int events, int timeout,
800                 sr_receive_data_callback cb, void *cb_data)
801 {
802         struct bt_source_args_t *args;
803         int rc;
804
805         (void)events;
806
807         /* Optionally enforce a minimum poll period. */
808         if (WITH_MAXIMUM_TIMEOUT_VALUE && timeout > WITH_MAXIMUM_TIMEOUT_VALUE)
809                 timeout = WITH_MAXIMUM_TIMEOUT_VALUE;
810
811         /* Allocate status container for background data reception. */
812         args = g_malloc0(sizeof(*args));
813         args->cb = cb;
814         args->cb_data = cb_data;
815         args->serial = serial;
816
817         /*
818          * Have a periodic timer installed. Register the allocated block
819          * with the serial device, since the GSource's finalizer won't
820          * free the memory, and we haven't bothered to create a custom
821          * BT specific GSource.
822          */
823         rc = sr_session_source_add(session, -1, events, timeout, bt_source_cb, args);
824         if (rc != SR_OK) {
825                 g_free(args);
826                 return rc;
827         }
828         serial->bt_source_args = g_slist_append(serial->bt_source_args, args);
829
830         return SR_OK;
831 }
832
833 static int ser_bt_setup_source_remove(struct sr_session *session,
834                 struct sr_serial_dev_inst *serial)
835 {
836         (void)serial;
837
838         (void)sr_session_source_remove(session, -1);
839         /* Release callback args here already? */
840
841         return SR_OK;
842 }
843
844 struct bt_scan_args_t {
845         GSList *port_list;
846         sr_ser_list_append_t append;
847         GSList *addr_list;
848         const char *bt_type;
849 };
850
851 static void scan_cb(void *cb_args, const char *addr, const char *name)
852 {
853         struct bt_scan_args_t *scan_args;
854         GSList *l;
855         char addr_text[20];
856         const struct scan_supported_item *item;
857         enum ser_bt_conn_t type;
858         char *port_name, *port_desc;
859         char *addr_copy;
860
861         scan_args = cb_args;
862         if (!scan_args)
863                 return;
864         sr_info("BT scan, found: %s - %s\n", addr, name);
865
866         /* Check whether the device was seen before. */
867         for (l = scan_args->addr_list; l; l = l->next) {
868                 if (strcmp(addr, l->data) == 0)
869                         return;
870         }
871
872         /* Substitute colons in the address by dashes. */
873         if (!addr || !*addr)
874                 return;
875         snprintf(addr_text, sizeof(addr_text), "%s", addr);
876         g_strcanon(addr_text, "0123456789abcdefABCDEF", '-');
877
878         /* Create a port name, and a description. */
879         item = scan_is_supported(name);
880         type = item ? item->type : SER_BT_CONN_UNKNOWN;
881         port_name = g_strdup_printf("%s/%s/%s%s",
882                 SER_BT_CONN_PREFIX, conn_name_text(type), addr_text,
883                 (item && item->add_params) ? item->add_params : "");
884         port_desc = g_strdup_printf("%s (%s)", name, scan_args->bt_type);
885
886         scan_args->port_list = scan_args->append(scan_args->port_list, port_name, port_desc);
887         g_free(port_name);
888         g_free(port_desc);
889
890         /* Keep track of the handled address. */
891         addr_copy = g_strdup(addr);
892         scan_args->addr_list = g_slist_append(scan_args->addr_list, addr_copy);
893 }
894
895 static GSList *ser_bt_list(GSList *list, sr_ser_list_append_t append)
896 {
897         static const int scan_duration = 3;
898
899         struct bt_scan_args_t scan_args;
900         struct sr_bt_desc *desc;
901
902         /*
903          * Implementor's note: This "list" routine is best-effort. We
904          * assume that registering callbacks always succeeds. Silently
905          * ignore failure to scan for devices. Just return those which
906          * we happen to find.
907          */
908
909         desc = sr_bt_desc_new();
910         if (!desc)
911                 return list;
912
913         memset(&scan_args, 0, sizeof(scan_args));
914         scan_args.port_list = list;
915         scan_args.append = append;
916
917         scan_args.addr_list = NULL;
918         scan_args.bt_type = "BT";
919         (void)sr_bt_config_cb_scan(desc, scan_cb, &scan_args);
920         (void)sr_bt_scan_bt(desc, scan_duration);
921         g_slist_free_full(scan_args.addr_list, g_free);
922
923         scan_args.addr_list = NULL;
924         scan_args.bt_type = "BLE";
925         (void)sr_bt_config_cb_scan(desc, scan_cb, &scan_args);
926         (void)sr_bt_scan_le(desc, scan_duration);
927         g_slist_free_full(scan_args.addr_list, g_free);
928
929         sr_bt_desc_free(desc);
930
931         return scan_args.port_list;
932 }
933
934 static struct ser_lib_functions serlib_bt = {
935         .open = ser_bt_open,
936         .close = ser_bt_close,
937         .flush = ser_bt_flush,
938         .drain = ser_bt_drain,
939         .write = ser_bt_write,
940         .read = ser_bt_read,
941         /*
942          * Bluetooth communication has no concept of bitrate, so ignore
943          * these arguments silently. Neither need we pass the frame format
944          * down to internal BT comm routines, nor need we keep the values
945          * here, since the caller will cache/register them already.
946          */
947         .set_params = std_dummy_set_params,
948         .set_handshake = std_dummy_set_handshake,
949         .setup_source_add = ser_bt_setup_source_add,
950         .setup_source_remove = ser_bt_setup_source_remove,
951         .list = ser_bt_list,
952         .get_frame_format = NULL,
953 };
954 SR_PRIV struct ser_lib_functions *ser_lib_funcs_bt = &serlib_bt;
955
956 /* }}} */
957 #else
958
959 SR_PRIV int ser_name_is_bt(struct sr_serial_dev_inst *serial)
960 {
961         (void)serial;
962
963         return 0;
964 }
965
966 SR_PRIV struct ser_lib_functions *ser_lib_funcs_bt = NULL;
967
968 #endif
969 #endif
970
971 /** @} */