1 /*
2  * This file is part of the sigrok 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 /*
21  * Scan support for Bluetooth LE devices is modelled after the MIT licensed
22  * https://github.com/carsonmcdonald/bluez-experiments experiments/scantest.c
23  * example source code which is:
24  *
25  * The MIT License (MIT)
26  *
27  * Copyright (c) 2013 Carson McDonald
28  *
29  * Permission is hereby granted, free of charge, to any person obtaining a copy of
30  * this software and associated documentation files (the "Software"), to deal in
31  * the Software without restriction, including without limitation the rights to
32  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
33  * the Software, and to permit persons to whom the Software is furnished to do so,
34  * subject to the following conditions:
35  *
36  * The above copyright notice and this permission notice shall be included in all
37  * copies or substantial portions of the Software.
38  *
39  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
41  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
42  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
43  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
44  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45  */
46 
47 /*
48  * This file implements an internal platform agnostic API of libsigrok
49  * for Bluetooth communication, as well as the first implementation on a
50  * specific platform which is based on the BlueZ library and got tested
51  * on Linux.
52  *
53  * TODO
54  * - Separate the "common" from the "bluez specific" parts. The current
55  *   implementation uses the fact that HAVE_BLUETOOTH exclusively depends
56  *   on HAVE_LIBBLUEZ, and thus both are identical.
57  * - Add missing features to the Linux platform support: Scan without
58  *   root privileges, UUID to handle translation.
59  * - Add support for other platforms.
60  */
61 
62 #include "config.h"
63 
64 /* Unconditionally compile the source, optionally end up empty. */
65 #ifdef HAVE_BLUETOOTH
66 
67 #ifdef HAVE_LIBBLUEZ
68 #include <bluetooth/bluetooth.h>
69 #include <bluetooth/hci.h>
70 #include <bluetooth/hci_lib.h>
71 #include <bluetooth/l2cap.h>
72 #include <bluetooth/rfcomm.h>
73 #endif
74 #include <ctype.h>
75 #include <errno.h>
76 #include <glib.h>
77 #include <poll.h>
78 #include <stdarg.h>
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <string.h>
82 #include <sys/uio.h>
83 #include <sys/socket.h>
84 #include <time.h>
85 #include <unistd.h>
86 
87 #include <libsigrok/libsigrok.h>
88 #include "libsigrok-internal.h"
89 
90 /** @cond PRIVATE */
91 #define LOG_PREFIX "bt-bluez"
92 /** @endcond */
93 
94 #define CONNECT_BLE_TIMEOUT	20	/* Connect timeout in seconds. */
95 #define STORE_MAC_REVERSE	1
96 #define ACCEPT_NONSEP_MAC	1
97 
98 /* Silence warning about (currently) unused routine. */
99 #define WITH_WRITE_TYPE_HANDLE	0
100 
101 /* {{{ compat decls */
102 /*
103  * The availability of conversion helpers in <bluetooth/bluetooth.h>
104  * appears to be version dependent. Let's provide the helper here if
105  * the header doesn't.
106  */
107 
108 #if !defined HAVE_BT_PUT_LE16
bt_put_le16(uint16_t v,uint8_t * p)109 static inline void bt_put_le16(uint16_t v, uint8_t *p)
110 {
111 	p[0] = (v >> 0) & 0xff;
112 	p[1] = (v >> 8) & 0xff;
113 }
114 #endif
115 
116 /* }}} compat decls */
117 /* {{{ Linux socket specific decls */
118 
119 #define BLE_ATT_ERROR_RESP		0x01
120 #define BLE_ATT_EXCHANGE_MTU_REQ	0x02
121 #define BLE_ATT_EXCHANGE_MTU_RESP	0x03
122 #define BLE_ATT_FIND_INFORMATION_REQ	0x04
123 #define BLE_ATT_FIND_INFORMATION_RESP	0x05
124 #define BLE_ATT_FIND_BY_TYPE_REQ	0x06
125 #define BLE_ATT_FIND_BY_TYPE_RESP	0x07
126 #define BLE_ATT_READ_BY_TYPE_REQ	0x08
127 #define BLE_ATT_READ_BY_TYPE_RESP	0x09
128 #define BLE_ATT_READ_REQ		0x0a
129 #define BLE_ATT_READ_RESP		0x0b
130 #define BLE_ATT_READ_BLOB_REQ		0x0c
131 #define BLE_ATT_READ_BLOB_RESP		0x0d
132 #define BLE_ATT_READ_MULTIPLE_REQ	0x0e
133 #define BLE_ATT_READ_MULTIPLE_RESP	0x0f
134 #define BLE_ATT_READ_BY_GROUP_REQ	0x10
135 #define BLE_ATT_READ_BY_GROUP_RESP	0x11
136 #define BLE_ATT_WRITE_REQ		0x12
137 #define BLE_ATT_WRITE_RESP		0x13
138 #define BLE_ATT_WRITE_CMD		0x16
139 #define BLE_ATT_HANDLE_NOTIFICATION	0x1b
140 #define BLE_ATT_HANDLE_INDICATION	0x1d
141 #define BLE_ATT_HANDLE_CONFIRMATION	0x1e
142 #define BLE_ATT_SIGNED_WRITE_CMD	0x52
143 
144 /* }}} Linux socket specific decls */
145 /* {{{ conversion */
146 
147 /*
148  * Convert textual MAC presentation to array of bytes. In contrast to
149  * BlueZ conversion, accept colon or dash separated input as well as a
150  * dense format without separators (001122334455). We expect to use the
151  * library in an environment where colons are not always available as a
152  * separator in user provided specs, while users do want to use some
153  * separator for readability.
154  *
155  * TODO Instead of doing the actual conversion here (and dealing with
156  * BlueZ' internal byte order for device address bytes), we might as
157  * well just transform the input string to an output string, and always
158  * use the officially provided str2ba() conversion routine.
159  */
sr_bt_mac_text_to_bytes(const char * text,uint8_t * buf)160 static int sr_bt_mac_text_to_bytes(const char *text, uint8_t *buf)
161 {
162 	size_t len;
163 	long v;
164 	char *endp;
165 	char numbuf[3];
166 
167 	len = 6;
168 	if (STORE_MAC_REVERSE)
169 		buf += len;
170 	endp = (char *)text;
171 	while (len && endp && *endp) {
172 		text = endp;
173 		if (ACCEPT_NONSEP_MAC) {
174 			numbuf[0] = endp[0];
175 			numbuf[1] = endp[0] ? endp[1] : '\0';
176 			numbuf[2] = '\0';
177 		}
178 		endp = NULL;
179 		v = strtol(ACCEPT_NONSEP_MAC ? numbuf : text, &endp, 16);
180 		if (!endp)
181 			break;
182 		if (*endp != ':' && *endp != '-' && *endp != '\0')
183 			break;
184 		if (v < 0 || v > 255)
185 			break;
186 		if (STORE_MAC_REVERSE)
187 			*(--buf) = v;
188 		else
189 			*buf++ = v;
190 		len--;
191 		if (ACCEPT_NONSEP_MAC)
192 			endp = (char *)text + (endp - numbuf);
193 		if (*endp == ':' || *endp == '-')
194 			endp++;
195 	}
196 
197 	if (len) {
198 		sr_err("Failed to parse MAC, too few bytes in '%s'", text);
199 		return -1;
200 	}
201 	while (isspace(*endp))
202 		endp++;
203 	if (*endp) {
204 		sr_err("Failed to parse MAC, excess data in '%s'", text);
205 		return -1;
206 	}
207 
208 	return 0;
209 }
210 
211 /* }}} conversion */
212 /* {{{ helpers */
213 
sr_bt_adapter_get_address(size_t idx)214 SR_PRIV const char *sr_bt_adapter_get_address(size_t idx)
215 {
216 	int rc;
217 	struct hci_dev_info info;
218 	char addr[20];
219 
220 	rc = hci_devinfo(idx, &info);
221 	sr_spew("DIAG: hci_devinfo(%zu) => rc %d", idx, rc);
222 	if (rc < 0)
223 		return NULL;
224 
225 	rc = ba2str(&info.bdaddr, addr);
226 	sr_spew("DIAG: ba2str() => rc %d", rc);
227 	if (rc < 0)
228 		return NULL;
229 
230 	return g_strdup(addr);
231 }
232 
233 /* }}} helpers */
234 /* {{{ descriptor */
235 
236 struct sr_bt_desc {
237 	/* User servicable options. */
238 	sr_bt_scan_cb scan_cb;
239 	void *scan_cb_data;
240 	sr_bt_data_cb data_cb;
241 	void *data_cb_data;
242 	char local_addr[20];
243 	char remote_addr[20];
244 	size_t rfcomm_channel;
245 	uint16_t read_handle;
246 	uint16_t write_handle;
247 	uint16_t cccd_handle;
248 	uint16_t cccd_value;
249 	/* Internal state. */
250 	int devid;
251 	int fd;
252 	struct hci_filter orig_filter;
253 };
254 
255 static int sr_bt_desc_open(struct sr_bt_desc *desc, int *id_ref);
256 static void sr_bt_desc_close(struct sr_bt_desc *desc);
257 static int sr_bt_check_socket_usable(struct sr_bt_desc *desc);
258 static ssize_t sr_bt_write_type(struct sr_bt_desc *desc, uint8_t type);
259 #if WITH_WRITE_TYPE_HANDLE
260 static ssize_t sr_bt_write_type_handle(struct sr_bt_desc *desc,
261 	uint8_t type, uint16_t handle);
262 #endif
263 static ssize_t sr_bt_write_type_handle_bytes(struct sr_bt_desc *desc,
264 	uint8_t type, uint16_t handle, const uint8_t *data, size_t len);
265 static ssize_t sr_bt_char_write_req(struct sr_bt_desc *desc,
266 	uint16_t handle, const void *data, size_t len);
267 
sr_bt_desc_new(void)268 SR_PRIV struct sr_bt_desc *sr_bt_desc_new(void)
269 {
270 	struct sr_bt_desc *desc;
271 
272 	desc = g_malloc0(sizeof(*desc));
273 	if (!desc)
274 		return NULL;
275 
276 	desc->devid = -1;
277 	desc->fd = -1;
278 
279 	return desc;
280 }
281 
sr_bt_desc_free(struct sr_bt_desc * desc)282 SR_PRIV void sr_bt_desc_free(struct sr_bt_desc *desc)
283 {
284 	if (!desc)
285 		return;
286 
287 	sr_bt_desc_close(desc);
288 	g_free(desc);
289 }
290 
sr_bt_config_cb_scan(struct sr_bt_desc * desc,sr_bt_scan_cb cb,void * cb_data)291 SR_PRIV int sr_bt_config_cb_scan(struct sr_bt_desc *desc,
292 	sr_bt_scan_cb cb, void *cb_data)
293 {
294 	if (!desc)
295 		return -1;
296 
297 	desc->scan_cb = cb;
298 	desc->scan_cb_data = cb_data;
299 
300 	return 0;
301 }
302 
sr_bt_config_cb_data(struct sr_bt_desc * desc,sr_bt_data_cb cb,void * cb_data)303 SR_PRIV int sr_bt_config_cb_data(struct sr_bt_desc *desc,
304 	sr_bt_data_cb cb, void *cb_data)
305 {
306 	if (!desc)
307 		return -1;
308 
309 	desc->data_cb = cb;
310 	desc->data_cb_data = cb_data;
311 
312 	return 0;
313 }
314 
sr_bt_config_addr_local(struct sr_bt_desc * desc,const char * addr)315 SR_PRIV int sr_bt_config_addr_local(struct sr_bt_desc *desc, const char *addr)
316 {
317 	bdaddr_t mac_bytes;
318 	int rc;
319 
320 	if (!desc)
321 		return -1;
322 
323 	if (!addr || !addr[0]) {
324 		desc->local_addr[0] = '\0';
325 		return 0;
326 	}
327 
328 	rc = sr_bt_mac_text_to_bytes(addr, &mac_bytes.b[0]);
329 	if (rc < 0)
330 		return -1;
331 
332 	rc = ba2str(&mac_bytes, desc->local_addr);
333 	if (rc < 0)
334 		return -1;
335 
336 	return 0;
337 }
338 
sr_bt_config_addr_remote(struct sr_bt_desc * desc,const char * addr)339 SR_PRIV int sr_bt_config_addr_remote(struct sr_bt_desc *desc, const char *addr)
340 {
341 	bdaddr_t mac_bytes;
342 	int rc;
343 
344 	if (!desc)
345 		return -1;
346 
347 	if (!addr || !addr[0]) {
348 		desc->remote_addr[0] = '\0';
349 		return 0;
350 	}
351 
352 	rc = sr_bt_mac_text_to_bytes(addr, &mac_bytes.b[0]);
353 	if (rc < 0)
354 		return -1;
355 
356 	rc = ba2str(&mac_bytes, desc->remote_addr);
357 	if (rc < 0)
358 		return -1;
359 
360 	return 0;
361 }
362 
sr_bt_config_rfcomm(struct sr_bt_desc * desc,size_t channel)363 SR_PRIV int sr_bt_config_rfcomm(struct sr_bt_desc *desc, size_t channel)
364 {
365 	if (!desc)
366 		return -1;
367 
368 	desc->rfcomm_channel = channel;
369 
370 	return 0;
371 }
372 
sr_bt_config_notify(struct sr_bt_desc * desc,uint16_t read_handle,uint16_t write_handle,uint16_t cccd_handle,uint16_t cccd_value)373 SR_PRIV int sr_bt_config_notify(struct sr_bt_desc *desc,
374 	uint16_t read_handle, uint16_t write_handle,
375 	uint16_t cccd_handle, uint16_t cccd_value)
376 {
377 
378 	if (!desc)
379 		return -1;
380 
381 	desc->read_handle = read_handle;
382 	desc->write_handle = write_handle;
383 	desc->cccd_handle = cccd_handle;
384 	desc->cccd_value = cccd_value;
385 
386 	return 0;
387 }
388 
sr_bt_desc_open(struct sr_bt_desc * desc,int * id_ref)389 static int sr_bt_desc_open(struct sr_bt_desc *desc, int *id_ref)
390 {
391 	int id, sock;
392 	bdaddr_t mac;
393 
394 	if (!desc)
395 		return -1;
396 	sr_dbg("BLE open");
397 
398 	if (desc->local_addr[0]) {
399 		id = hci_devid(desc->local_addr);
400 	} else if (desc->remote_addr[0]) {
401 		str2ba(desc->remote_addr, &mac);
402 		id = hci_get_route(&mac);
403 	} else {
404 		id = hci_get_route(NULL);
405 	}
406 	if (id < 0) {
407 		sr_err("devid failed");
408 		return -1;
409 	}
410 	desc->devid = id;
411 	if (id_ref)
412 		*id_ref = id;
413 
414 	sock = hci_open_dev(id);
415 	if (sock < 0) {
416 		perror("open HCI socket");
417 		return -1;
418 	}
419 	desc->fd = sock;
420 
421 	return sock;
422 }
423 
sr_bt_desc_close(struct sr_bt_desc * desc)424 static void sr_bt_desc_close(struct sr_bt_desc *desc)
425 {
426 	if (!desc)
427 		return;
428 
429 	sr_dbg("BLE close");
430 	if (desc->fd >= 0) {
431 		hci_close_dev(desc->fd);
432 		desc->fd = -1;
433 	}
434 	desc->devid = -1;
435 }
436 
437 /* }}} descriptor */
438 /* {{{ scan */
439 
440 #define EIR_NAME_COMPLETE	9
441 
sr_bt_scan_prep(struct sr_bt_desc * desc)442 static int sr_bt_scan_prep(struct sr_bt_desc *desc)
443 {
444 	int rc;
445 	uint8_t type, owntype, filter;
446 	uint16_t ival, window;
447 	int timeout;
448 	uint8_t enable, dup;
449 	socklen_t slen;
450 	struct hci_filter scan_filter;
451 
452 	if (!desc)
453 		return -1;
454 
455 	/* TODO Replace magic values with symbolic identifiers. */
456 	type = 0x01;	/* LE public? */
457 	ival = htobs(0x0010);
458 	window = htobs(0x0010);
459 	owntype = 0x00;	/* any? */
460 	filter = 0x00;
461 	timeout = 1000;
462 	rc = hci_le_set_scan_parameters(desc->fd,
463 		type, ival, window, owntype, filter, timeout);
464 	if (rc < 0) {
465 		perror("set LE scan params");
466 		return -1;
467 	}
468 
469 	enable = 1;
470 	dup = 1;
471 	timeout = 1000;
472 	rc = hci_le_set_scan_enable(desc->fd, enable, dup, timeout);
473 	if (rc < 0) {
474 		perror("set LE scan enable");
475 		return -1;
476 	}
477 
478 	/* Save the current filter. For later restoration. */
479 	slen = sizeof(desc->orig_filter);
480 	rc = getsockopt(desc->fd, SOL_HCI, HCI_FILTER,
481 		&desc->orig_filter, &slen);
482 	if (rc < 0) {
483 		perror("getsockopt(HCI_FILTER)");
484 		return -1;
485 	}
486 
487 	hci_filter_clear(&scan_filter);
488 	hci_filter_set_ptype(HCI_EVENT_PKT, &scan_filter);
489 	hci_filter_set_event(EVT_LE_META_EVENT, &scan_filter);
490 	rc = setsockopt(desc->fd, SOL_HCI, HCI_FILTER,
491 		&scan_filter, sizeof(scan_filter));
492 	if (rc < 0) {
493 		perror("setsockopt(HCI_FILTER)");
494 		return -1;
495 	}
496 
497 	return 0;
498 }
499 
sr_bt_scan_post(struct sr_bt_desc * desc)500 static int sr_bt_scan_post(struct sr_bt_desc *desc)
501 {
502 	int rc;
503 	uint8_t enable, dup;
504 	int timeout;
505 
506 	if (!desc)
507 		return -1;
508 
509 	/* Restore previous HCI filter. */
510 	rc = setsockopt(desc->fd, SOL_HCI, HCI_FILTER,
511 		&desc->orig_filter, sizeof(desc->orig_filter));
512 	if (rc < 0) {
513 		perror("setsockopt(HCI_FILTER)");
514 		return -1;
515 	}
516 
517 	enable = 0;
518 	dup = 1;
519 	timeout = 1000;
520 	rc = hci_le_set_scan_enable(desc->fd, enable, dup, timeout);
521 	if (rc < 0)
522 		return -1;
523 
524 	return 0;
525 }
526 
sr_bt_scan_proc(struct sr_bt_desc * desc,sr_bt_scan_cb scan_cb,void * cb_data,uint8_t * data,size_t dlen,le_advertising_info * info)527 static int sr_bt_scan_proc(struct sr_bt_desc *desc,
528 	sr_bt_scan_cb scan_cb, void *cb_data,
529 	uint8_t *data, size_t dlen, le_advertising_info *info)
530 {
531 	uint8_t type;
532 	char addr[20];
533 	const char *name;
534 
535 	(void)desc;
536 
537 	type = data[0];
538 	if (type == EIR_NAME_COMPLETE) {
539 		ba2str(&info->bdaddr, addr);
540 		name = g_strndup((const char *)&data[1], dlen - 1);
541 		if (scan_cb)
542 			scan_cb(cb_data, addr, name);
543 		free((void *)name);
544 		return 0;
545 	}
546 
547 	/* Unknown or unsupported type, ignore silently. */
548 	return 0;
549 }
550 
sr_bt_scan_le(struct sr_bt_desc * desc,int duration)551 SR_PRIV int sr_bt_scan_le(struct sr_bt_desc *desc, int duration)
552 {
553 	int rc;
554 	time_t deadline;
555 	uint8_t buf[HCI_MAX_EVENT_SIZE];
556 	ssize_t rdlen, rdpos;
557 	evt_le_meta_event *meta;
558 	le_advertising_info *info;
559 	uint8_t *dataptr;
560 	size_t datalen;
561 
562 	if (!desc)
563 		return -1;
564 	sr_dbg("BLE scan (LE)");
565 
566 	rc = sr_bt_desc_open(desc, NULL);
567 	if (rc < 0)
568 		return -1;
569 
570 	rc = sr_bt_scan_prep(desc);
571 	if (rc < 0)
572 		return -1;
573 
574 	deadline = time(NULL);
575 	deadline += duration;
576 	while (time(NULL) <= deadline) {
577 
578 		if (sr_bt_check_socket_usable(desc) < 0)
579 			break;
580 		rdlen = sr_bt_read(desc, buf, sizeof(buf));
581 		if (rdlen < 0)
582 			break;
583 		if (!rdlen) {
584 			g_usleep(50000);
585 			continue;
586 		}
587 		if (rdlen < 1 + HCI_EVENT_HDR_SIZE)
588 			continue;
589 		meta = (void *)&buf[1 + HCI_EVENT_HDR_SIZE];
590 		rdlen -= 1 + HCI_EVENT_HDR_SIZE;
591 		if (meta->subevent != EVT_LE_ADVERTISING_REPORT)
592 			continue;
593 		info = (void *)&meta->data[1];
594 		sr_spew("evt: type %d, len %d", info->evt_type, info->length);
595 		if (!info->length)
596 			continue;
597 
598 		rdpos = 0;
599 		while (rdpos < rdlen) {
600 			datalen = info->data[rdpos];
601 			dataptr = &info->data[1 + rdpos];
602 			if (rdpos + 1 + datalen > info->length)
603 				break;
604 			rdpos += 1 + datalen;
605 			rc = sr_bt_scan_proc(desc,
606 				desc->scan_cb, desc->scan_cb_data,
607 				dataptr, datalen, info);
608 			if (rc < 0)
609 				break;
610 		}
611 	}
612 
613 	rc = sr_bt_scan_post(desc);
614 	if (rc < 0)
615 		return -1;
616 
617 	sr_bt_desc_close(desc);
618 
619 	return 0;
620 }
621 
sr_bt_scan_bt(struct sr_bt_desc * desc,int duration)622 SR_PRIV int sr_bt_scan_bt(struct sr_bt_desc *desc, int duration)
623 {
624 	int dev_id, sock, rsp_max;
625 	long flags;
626 	inquiry_info *info;
627 	int inq_rc;
628 	size_t rsp_count, idx;
629 	char addr[20];
630 	char name[256];
631 
632 	if (!desc)
633 		return -1;
634 	sr_dbg("BLE scan (BT)");
635 
636 	sock = sr_bt_desc_open(desc, &dev_id);
637 	if (sock < 0)
638 		return -1;
639 
640 	rsp_max = 255;
641 	info = g_malloc0(rsp_max * sizeof(*info));
642 	flags = 0 /* | IREQ_CACHE_FLUSH */;
643 	inq_rc = hci_inquiry(dev_id, duration, rsp_max, NULL, &info, flags);
644 	if (inq_rc < 0)
645 		perror("hci_inquiry");
646 	rsp_count = inq_rc;
647 
648 	for (idx = 0; idx < rsp_count; idx++) {
649 		memset(addr, 0, sizeof(addr));
650 		ba2str(&info[idx].bdaddr, addr);
651 		memset(name, 0, sizeof(name));
652 		if (hci_read_remote_name(sock, &info[idx].bdaddr, sizeof(name), name, 0) < 0)
653 			snprintf(name, sizeof(name), "[unknown]");
654 		if (desc->scan_cb)
655 			desc->scan_cb(desc->scan_cb_data, addr, name);
656 	}
657 	g_free(info);
658 
659 	sr_bt_desc_close(desc);
660 
661 	return 0;
662 }
663 
664 /* }}} scan */
665 /* {{{ connect/disconnect */
666 
sr_bt_connect_ble(struct sr_bt_desc * desc)667 SR_PRIV int sr_bt_connect_ble(struct sr_bt_desc *desc)
668 {
669 	struct sockaddr_l2 sl2;
670 	bdaddr_t mac;
671 	int s, ret;
672 	gint64 deadline;
673 
674 	if (!desc)
675 		return -1;
676 	if (!desc->remote_addr[0])
677 		return -1;
678 	sr_dbg("BLE connect, remote addr %s", desc->remote_addr);
679 
680 	s = socket(AF_BLUETOOTH, SOCK_SEQPACKET, 0);
681 	if (s < 0) {
682 		perror("socket create");
683 		return s;
684 	}
685 	desc->fd = s;
686 
687 	memset(&sl2, 0, sizeof(sl2));
688 	sl2.l2_family = AF_BLUETOOTH;
689 	sl2.l2_psm = 0;
690 	if (desc->local_addr[0])
691 		str2ba(desc->local_addr, &mac);
692 	else
693 		mac = *BDADDR_ANY;
694 	memcpy(&sl2.l2_bdaddr, &mac, sizeof(sl2.l2_bdaddr));
695 	sl2.l2_cid = L2CAP_FC_CONNLESS;
696 	sl2.l2_bdaddr_type = BDADDR_LE_PUBLIC;
697 	ret = bind(s, (void *)&sl2, sizeof(sl2));
698 	if (ret < 0) {
699 		perror("bind");
700 		return ret;
701 	}
702 
703 	if (0) {
704 		struct bt_security buf = {
705 			.level = BT_SECURITY_LOW,
706 			.key_size = 0,
707 		};
708 		ret = setsockopt(s, SOL_BLUETOOTH, BT_SECURITY, &buf, sizeof(buf));
709 		if (ret < 0) {
710 			perror("setsockopt");
711 			return ret;
712 		}
713 	}
714 
715 	deadline = g_get_monotonic_time();
716 	deadline += CONNECT_BLE_TIMEOUT * 1000 * 1000;
717 	str2ba(desc->remote_addr, &mac);
718 	memcpy(&sl2.l2_bdaddr, &mac, sizeof(sl2.l2_bdaddr));
719 	sl2.l2_bdaddr_type = BDADDR_LE_PUBLIC;
720 	ret = connect(s, (void *)&sl2, sizeof(sl2));
721 	/*
722 	 * Cope with "in progress" condition. Keep polling the status
723 	 * until connect() completes, then get the error by means of
724 	 * getsockopt(). See the connect(2) manpage for details.
725 	 */
726 	if (ret < 0 && errno == EINPROGRESS) {
727 		struct pollfd fds[1];
728 		uint32_t soerror;
729 		socklen_t solen;
730 
731 		/* TODO
732 		 * We seem to get here ("connect in progress") even when
733 		 * the specified peer is not around at all. Which results
734 		 * in extended periods of time where nothing happens, and
735 		 * an application timeout seems to be required.
736 		 */
737 		sr_spew("in progress ...");
738 
739 		do {
740 			memset(fds, 0, sizeof(fds));
741 			fds[0].fd = s;
742 			fds[0].events = POLLOUT;
743 			ret = poll(fds, ARRAY_SIZE(fds), -1);
744 			if (ret < 0) {
745 				perror("poll(OUT)");
746 				return ret;
747 			}
748 			if (!ret)
749 				continue;
750 			if (!(fds[0].revents & POLLOUT))
751 				continue;
752 			if (g_get_monotonic_time() >= deadline) {
753 				sr_warn("Connect attempt timed out");
754 				return SR_ERR_IO;
755 			}
756 		} while (1);
757 		memset(fds, 0, sizeof(fds));
758 		fds[0].fd = s;
759 		fds[0].events = POLLNVAL;
760 		ret = poll(fds, 1, 0);
761 		if (ret < 0) {
762 			perror("poll(INVAL)");
763 			return ret;
764 		}
765 		if (ret) {
766 			/* socket fd is invalid(?) */
767 			desc->fd = -1;
768 			close(s);
769 			return -1;
770 		}
771 		solen = sizeof(soerror);
772 		ret = getsockopt(s, SOL_SOCKET, SO_ERROR, &soerror, &solen);
773 		if (ret < 0) {
774 			perror("getsockopt(SO_ERROR)");
775 			return ret;
776 		}
777 		if (soerror) {
778 			/* connect(2) failed, SO_ERROR has the error code. */
779 			errno = soerror;
780 			perror("connect(PROGRESS)");
781 			return soerror;
782 		}
783 
784 		/*
785 		 * TODO Get the receive MTU here?
786 		 * getsockopt(SOL_BLUETOOTH, BT_RCVMTU, u16);
787 		 */
788 	}
789 	if (ret < 0) {
790 		perror("connect");
791 		return ret;
792 	}
793 
794 	return 0;
795 }
796 
sr_bt_connect_rfcomm(struct sr_bt_desc * desc)797 SR_PRIV int sr_bt_connect_rfcomm(struct sr_bt_desc *desc)
798 {
799 	struct sockaddr_rc addr;
800 	int fd, rc;
801 
802 	if (!desc)
803 		return -1;
804 	if (!desc->remote_addr[0])
805 		return -1;
806 	sr_dbg("RFCOMM connect, remote addr %s, channel %zu",
807 		desc->remote_addr, desc->rfcomm_channel);
808 
809 	if (!desc->rfcomm_channel)
810 		desc->rfcomm_channel = 1;
811 
812 	fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
813 	if (fd < 0) {
814 		perror("socket");
815 		return -1;
816 	}
817 	desc->fd = fd;
818 
819 	memset(&addr, 0, sizeof(addr));
820 	addr.rc_family = AF_BLUETOOTH;
821 	str2ba(desc->remote_addr, &addr.rc_bdaddr);
822 	addr.rc_channel = desc->rfcomm_channel;
823 	rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
824 	if (rc < 0) {
825 		perror("connect");
826 		return -2;
827 	}
828 	sr_spew("connected");
829 
830 	return 0;
831 }
832 
sr_bt_disconnect(struct sr_bt_desc * desc)833 SR_PRIV void sr_bt_disconnect(struct sr_bt_desc *desc)
834 {
835 	sr_dbg("BLE disconnect");
836 
837 	if (!desc)
838 		return;
839 	sr_bt_desc_close(desc);
840 }
841 
sr_bt_check_socket_usable(struct sr_bt_desc * desc)842 static int sr_bt_check_socket_usable(struct sr_bt_desc *desc)
843 {
844 	struct pollfd fds[1];
845 	int ret;
846 
847 	if (!desc)
848 		return -1;
849 	if (desc->fd < 0)
850 		return -1;
851 
852 	memset(fds, 0, sizeof(fds));
853 	fds[0].fd = desc->fd;
854 	fds[0].events = POLLERR | POLLHUP;
855 	ret = poll(fds, ARRAY_SIZE(fds), 0);
856 	if (ret < 0)
857 		return ret;
858 	if (!ret)
859 		return 0;
860 	if (fds[0].revents & POLLHUP)
861 		return -1;
862 	if (fds[0].revents & POLLERR)
863 		return -2;
864 	if (fds[0].revents & POLLNVAL)
865 		return -3;
866 
867 	return 0;
868 }
869 
870 /* }}} connect/disconnect */
871 /* {{{ indication/notification */
872 
sr_bt_start_notify(struct sr_bt_desc * desc)873 SR_PRIV int sr_bt_start_notify(struct sr_bt_desc *desc)
874 {
875 	uint8_t buf[sizeof(desc->cccd_value)];
876 	ssize_t wrlen;
877 
878 	if (!desc)
879 		return -1;
880 	sr_dbg("BLE start notify");
881 
882 	if (sr_bt_check_socket_usable(desc) < 0)
883 		return -2;
884 
885 	bt_put_le16(desc->cccd_value, buf);
886 	wrlen = sr_bt_char_write_req(desc, desc->cccd_handle, buf, sizeof(buf));
887 	if (wrlen != sizeof(buf))
888 		return -2;
889 
890 	return 0;
891 }
892 
sr_bt_check_notify(struct sr_bt_desc * desc)893 SR_PRIV int sr_bt_check_notify(struct sr_bt_desc *desc)
894 {
895 	uint8_t buf[1024];
896 	ssize_t rdlen;
897 	uint8_t packet_type;
898 	uint16_t packet_handle;
899 	uint8_t *packet_data;
900 	size_t packet_dlen;
901 
902 	if (!desc)
903 		return -1;
904 
905 	if (sr_bt_check_socket_usable(desc) < 0)
906 		return -2;
907 
908 	/* Get another message from the Bluetooth socket. */
909 	rdlen = sr_bt_read(desc, buf, sizeof(buf));
910 	if (rdlen < 0)
911 		return -2;
912 	if (!rdlen)
913 		return 0;
914 
915 	/* Get header fields and references to the payload data. */
916 	packet_type = 0x00;
917 	packet_handle = 0x0000;
918 	packet_data = NULL;
919 	packet_dlen = 0;
920 	if (rdlen >= 1)
921 		packet_type = buf[0];
922 	if (rdlen >= 3) {
923 		packet_handle = bt_get_le16(&buf[1]);
924 		packet_data = &buf[3];
925 		packet_dlen = rdlen - 3;
926 	}
927 
928 	/* Dispatch according to the message type. */
929 	switch (packet_type) {
930 	case BLE_ATT_ERROR_RESP:
931 		sr_spew("read() len %zd, type 0x%02x (%s)", rdlen, buf[0], "error response");
932 		/* EMPTY */
933 		break;
934 	case BLE_ATT_WRITE_RESP:
935 		sr_spew("read() len %zd, type 0x%02x (%s)", rdlen, buf[0], "write response");
936 		/* EMPTY */
937 		break;
938 	case BLE_ATT_HANDLE_INDICATION:
939 		sr_spew("read() len %zd, type 0x%02x (%s)", rdlen, buf[0], "handle indication");
940 		sr_bt_write_type(desc, BLE_ATT_HANDLE_CONFIRMATION);
941 		if (packet_handle != desc->read_handle)
942 			return -4;
943 		if (!packet_data)
944 			return -4;
945 		if (!desc->data_cb)
946 			return 0;
947 		return desc->data_cb(desc->data_cb_data, packet_data, packet_dlen);
948 	case BLE_ATT_HANDLE_NOTIFICATION:
949 		sr_spew("read() len %zd, type 0x%02x (%s)", rdlen, buf[0], "handle notification");
950 		if (packet_handle != desc->read_handle)
951 			return -4;
952 		if (!packet_data)
953 			return -4;
954 		if (!desc->data_cb)
955 			return 0;
956 		return desc->data_cb(desc->data_cb_data, packet_data, packet_dlen);
957 	default:
958 		sr_spew("unsupported type 0x%02x", packet_type);
959 		return -3;
960 	}
961 
962 	return 0;
963 }
964 
965 /* }}} indication/notification */
966 /* {{{ read/write */
967 
sr_bt_write(struct sr_bt_desc * desc,const void * data,size_t len)968 SR_PRIV ssize_t sr_bt_write(struct sr_bt_desc *desc,
969 	const void *data, size_t len)
970 {
971 	if (!desc)
972 		return -1;
973 	if (desc->fd < 0)
974 		return -1;
975 
976 	if (sr_bt_check_socket_usable(desc) < 0)
977 		return -2;
978 
979 	/* Send TX data to the writable characteristics for BLE UART services. */
980 	if (desc->write_handle)
981 		return sr_bt_char_write_req(desc, desc->write_handle, data, len);
982 
983 	/* Send raw TX data to the RFCOMM socket for BT Classic channels. */
984 	return write(desc->fd, data, len);
985 }
986 
sr_bt_write_type(struct sr_bt_desc * desc,uint8_t type)987 static ssize_t sr_bt_write_type(struct sr_bt_desc *desc, uint8_t type)
988 {
989 	ssize_t wrlen;
990 
991 	if (!desc)
992 		return -1;
993 	if (desc->fd < 0)
994 		return -1;
995 
996 	if (sr_bt_check_socket_usable(desc) < 0)
997 		return -2;
998 
999 	wrlen = write(desc->fd, &type, sizeof(type));
1000 	if (wrlen < 0)
1001 		return wrlen;
1002 	if (wrlen < (ssize_t)sizeof(type))
1003 		return -1;
1004 
1005 	return 0;
1006 }
1007 
1008 #if WITH_WRITE_TYPE_HANDLE
sr_bt_write_type_handle(struct sr_bt_desc * desc,uint8_t type,uint16_t handle)1009 static ssize_t sr_bt_write_type_handle(struct sr_bt_desc *desc,
1010 	uint8_t type, uint16_t handle)
1011 {
1012 	return sr_bt_write_type_handle_bytes(desc, type, handle, NULL, 0);
1013 }
1014 #endif
1015 
sr_bt_write_type_handle_bytes(struct sr_bt_desc * desc,uint8_t type,uint16_t handle,const uint8_t * data,size_t len)1016 static ssize_t sr_bt_write_type_handle_bytes(struct sr_bt_desc *desc,
1017 	uint8_t type, uint16_t handle, const uint8_t *data, size_t len)
1018 {
1019 	uint8_t header[sizeof(uint8_t) + sizeof(uint16_t)];
1020 	struct iovec iov[2] = {
1021 		{ .iov_base = header, .iov_len = sizeof(header), },
1022 		{ .iov_base = (void *)data, .iov_len = len, },
1023 	};
1024 	ssize_t wrlen;
1025 
1026 	if (!desc)
1027 		return -1;
1028 	if (desc->fd < 0)
1029 		return -1;
1030 
1031 	if (sr_bt_check_socket_usable(desc) < 0)
1032 		return -2;
1033 
1034 	header[0] = type;
1035 	bt_put_le16(handle, &header[1]);
1036 
1037 	if (data && len)
1038 		wrlen = writev(desc->fd, iov, ARRAY_SIZE(iov));
1039 	else
1040 		wrlen = write(desc->fd, header, sizeof(header));
1041 
1042 	if (wrlen < 0)
1043 		return wrlen;
1044 	if (wrlen < (ssize_t)sizeof(header))
1045 		return -1;
1046 	wrlen -= sizeof(header);
1047 
1048 	return wrlen;
1049 }
1050 
1051 /* Returns negative upon error, or returns the number of _payload_ bytes written. */
sr_bt_char_write_req(struct sr_bt_desc * desc,uint16_t handle,const void * data,size_t len)1052 static ssize_t sr_bt_char_write_req(struct sr_bt_desc *desc,
1053 	uint16_t handle, const void *data, size_t len)
1054 {
1055 	return sr_bt_write_type_handle_bytes(desc, BLE_ATT_WRITE_REQ,
1056 		handle, data, len);
1057 }
1058 
sr_bt_read(struct sr_bt_desc * desc,void * data,size_t len)1059 SR_PRIV ssize_t sr_bt_read(struct sr_bt_desc *desc, void *data, size_t len)
1060 {
1061 	struct pollfd fds[1];
1062 	int ret;
1063 	ssize_t rdlen;
1064 
1065 	if (!desc)
1066 		return -1;
1067 	if (desc->fd < 0)
1068 		return -1;
1069 
1070 	if (sr_bt_check_socket_usable(desc) < 0)
1071 		return -2;
1072 
1073 	memset(fds, 0, sizeof(fds));
1074 	fds[0].fd = desc->fd;
1075 	fds[0].events = POLLIN;
1076 	ret = poll(fds, ARRAY_SIZE(fds), 0);
1077 	if (ret < 0)
1078 		return ret;
1079 	if (!ret)
1080 		return 0;
1081 	if (!(fds[0].revents & POLLIN))
1082 		return 0;
1083 
1084 	rdlen = read(desc->fd, data, len);
1085 
1086 	return rdlen;
1087 }
1088 
1089 /* }}} indication/notification */
1090 
1091 #endif
1092