1 /******************************************************************************
2 *
3 * Copyright 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /*******************************************************************************
20 *
21 * Filename: btif_pan.c
22 *
23 * Description: PAN Profile Bluetooth Interface
24 *
25 *
26 ******************************************************************************/
27
28 #define LOG_TAG "bt_btif_pan"
29
30 #include "btif/include/btif_pan.h"
31
32 #include <arpa/inet.h>
33 #include <base/functional/bind.h>
34 #include <base/location.h>
35 #include <bluetooth/log.h>
36 #include <fcntl.h>
37 #include <linux/if_ether.h>
38 #include <linux/if_tun.h>
39 #include <net/if.h>
40 #include <poll.h>
41 #include <string.h>
42 #include <sys/ioctl.h>
43 #include <sys/socket.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46
47 #include <cerrno>
48 #include <cstddef>
49 #include <cstdint>
50 #include <cstdlib>
51 #include <cstring>
52 #include <string>
53
54 #include "bta/include/bta_pan_api.h"
55 #include "btif/include/btif_common.h"
56 #include "btif/include/btif_pan_internal.h"
57 #include "btif/include/btif_sock_thread.h"
58 #include "hardware/bluetooth.h"
59 #include "hci/controller_interface.h"
60 #include "include/hardware/bt_pan.h"
61 #include "internal_include/bt_target.h"
62 #include "main/shim/entry.h"
63 #include "main/shim/helpers.h"
64 #include "osi/include/allocator.h"
65 #include "osi/include/compat.h"
66 #include "osi/include/osi.h"
67 #include "stack/include/bt_hdr.h"
68 #include "stack/include/main_thread.h"
69 #include "stack/include/pan_api.h"
70 #include "types/raw_address.h"
71
72 #ifdef __ANDROID__
73 #include <android/sysprop/BluetoothProperties.sysprop.h>
74 #endif
75
76 #define FORWARD_IGNORE 1
77 #define FORWARD_SUCCESS 0
78 #define FORWARD_FAILURE (-1)
79 #define FORWARD_CONGEST (-2)
80
81 #define asrt(s) \
82 do { \
83 if (!(s)) \
84 log::error("btif_pan: ## assert {} failed ##", #s); \
85 } while (0)
86
87 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
88
89 using namespace bluetooth;
90
91 btpan_cb_t btpan_cb;
92
93 static bool jni_initialized;
94 static bool stack_initialized;
95
96 static bt_status_t btpan_jni_init(const btpan_callbacks_t* callbacks);
97 static void btpan_jni_cleanup();
98 static bt_status_t btpan_connect(const RawAddress* bd_addr, int local_role, int remote_role);
99 static bt_status_t btpan_disconnect(const RawAddress* bd_addr);
100 static bt_status_t btpan_enable(int local_role);
101 static int btpan_get_local_role(void);
102
103 static void btpan_tap_fd_signaled(int fd, int type, int flags, uint32_t user_id);
104 static void btpan_cleanup_conn(btpan_conn_t* conn);
105 static void bta_pan_callback(tBTA_PAN_EVT event, tBTA_PAN* p_data);
106 static void btu_exec_tap_fd_read(const int fd);
107
108 static btpan_interface_t pan_if = {sizeof(pan_if), btpan_jni_init, nullptr,
109 btpan_get_local_role, btpan_connect, btpan_disconnect,
110 btpan_jni_cleanup};
111
btif_pan_get_interface()112 const btpan_interface_t* btif_pan_get_interface() { return &pan_if; }
113
114 /*******************************************************************************
115 **
116 ** Function btif_pan_init
117 **
118 ** Description initializes the pan interface
119 **
120 ** Returns bt_status_t
121 **
122 ******************************************************************************/
btif_pan_init()123 void btif_pan_init() {
124 log::verbose("jni_initialized = {}, btpan_cb.enabled:{}", jni_initialized, btpan_cb.enabled);
125 stack_initialized = true;
126
127 if (jni_initialized && !btpan_cb.enabled) {
128 log::verbose("Enabling PAN....");
129 memset(&btpan_cb, 0, sizeof(btpan_cb));
130 btpan_cb.tap_fd = INVALID_FD;
131 btpan_cb.flow = 1;
132 for (int i = 0; i < MAX_PAN_CONNS; i++) {
133 btpan_cleanup_conn(&btpan_cb.conns[i]);
134 }
135 BTA_PanEnable(bta_pan_callback);
136 btpan_cb.enabled = 1;
137
138 int role = BTPAN_ROLE_NONE;
139 #ifdef __ANDROID__
140 if (android::sysprop::BluetoothProperties::isProfilePanNapEnabled().value_or(false)) {
141 role |= BTPAN_ROLE_PANNAP;
142 }
143 #endif
144 role |= BTPAN_ROLE_PANU;
145 btpan_enable(role);
146 }
147 }
148
pan_disable()149 static void pan_disable() {
150 if (btpan_cb.enabled) {
151 btpan_cb.enabled = 0;
152 BTA_PanDisable();
153 if (btpan_cb.tap_fd != INVALID_FD) {
154 btpan_tap_close(btpan_cb.tap_fd);
155 btpan_cb.tap_fd = INVALID_FD;
156 }
157 }
158 }
159
btif_pan_cleanup()160 void btif_pan_cleanup() {
161 if (!stack_initialized) {
162 return;
163 }
164
165 // Bluetooth is shutting down, invalidate all BTA PAN handles
166 for (int i = 0; i < MAX_PAN_CONNS; i++) {
167 btpan_cleanup_conn(&btpan_cb.conns[i]);
168 }
169
170 pan_disable();
171 stack_initialized = false;
172 }
173
174 static btpan_callbacks_t callback;
btpan_jni_init(const btpan_callbacks_t * callbacks)175 static bt_status_t btpan_jni_init(const btpan_callbacks_t* callbacks) {
176 log::verbose("stack_initialized = {}, btpan_cb.enabled:{}", stack_initialized, btpan_cb.enabled);
177 callback = *callbacks;
178 jni_initialized = true;
179 if (stack_initialized && !btpan_cb.enabled) {
180 btif_pan_init();
181 }
182 return BT_STATUS_SUCCESS;
183 }
184
btpan_jni_cleanup()185 static void btpan_jni_cleanup() {
186 pan_disable();
187 jni_initialized = false;
188 }
189
bta_role_to_btpan(tBTA_PAN_ROLE bta_pan_role)190 static inline int bta_role_to_btpan(tBTA_PAN_ROLE bta_pan_role) {
191 int btpan_role = 0;
192 if (bta_pan_role & PAN_ROLE_NAP_SERVER) {
193 btpan_role |= BTPAN_ROLE_PANNAP;
194 }
195 if (bta_pan_role & PAN_ROLE_CLIENT) {
196 btpan_role |= BTPAN_ROLE_PANU;
197 }
198 return btpan_role;
199 }
200
btpan_role_to_bta(int btpan_role)201 static inline tBTA_PAN_ROLE btpan_role_to_bta(int btpan_role) {
202 tBTA_PAN_ROLE bta_pan_role = PAN_ROLE_INACTIVE;
203 if (btpan_role & BTPAN_ROLE_PANNAP) {
204 bta_pan_role |= PAN_ROLE_NAP_SERVER;
205 }
206 if (btpan_role & BTPAN_ROLE_PANU) {
207 bta_pan_role |= PAN_ROLE_CLIENT;
208 }
209 return bta_pan_role;
210 }
211
212 static tBTA_PAN_ROLE btpan_dev_local_role;
213 static tBTA_PAN_ROLE_INFO bta_panu_info = {std::string(PANU_SERVICE_NAME), 0};
214 static tBTA_PAN_ROLE_INFO bta_pan_nap_info = {std::string(PAN_NAP_SERVICE_NAME), 1};
215
btpan_enable(int local_role)216 static bt_status_t btpan_enable(int local_role) {
217 const tBTA_PAN_ROLE bta_pan_role = btpan_role_to_bta(local_role);
218 BTA_PanSetRole(bta_pan_role, bta_panu_info, bta_pan_nap_info);
219 btpan_dev_local_role = local_role;
220 return BT_STATUS_SUCCESS;
221 }
222
btpan_get_local_role()223 static int btpan_get_local_role() { return static_cast<int>(btpan_dev_local_role); }
224
btpan_connect(const RawAddress * bd_addr,int local_role,int remote_role)225 static bt_status_t btpan_connect(const RawAddress* bd_addr, int local_role, int remote_role) {
226 tBTA_PAN_ROLE bta_local_role = btpan_role_to_bta(local_role);
227 tBTA_PAN_ROLE bta_remote_role = btpan_role_to_bta(remote_role);
228 btpan_new_conn(-1, *bd_addr, bta_local_role, bta_remote_role);
229 BTA_PanOpen(*bd_addr, bta_local_role, bta_remote_role);
230 return BT_STATUS_SUCCESS;
231 }
232
233 constexpr uint16_t BTIF_PAN_CB_DISCONNECTING = 0x8401;
btif_in_pan_generic_evt(uint16_t event,char * p_param)234 static void btif_in_pan_generic_evt(uint16_t event, char* p_param) {
235 log::verbose("event={}", event);
236 switch (event) {
237 case BTIF_PAN_CB_DISCONNECTING: {
238 RawAddress* bd_addr = (RawAddress*)p_param;
239 btpan_conn_t* conn = btpan_find_conn_addr(*bd_addr);
240 int btpan_conn_local_role;
241 int btpan_remote_role;
242 asrt(conn != NULL);
243 if (conn) {
244 btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
245 btpan_remote_role = bta_role_to_btpan(conn->remote_role);
246 callback.connection_state_cb(BTPAN_STATE_DISCONNECTING, BT_STATUS_SUCCESS, &conn->peer,
247 btpan_conn_local_role, btpan_remote_role);
248 }
249 } break;
250 default: {
251 log::warn("Unknown event 0x{:x}", event);
252 } break;
253 }
254 }
255
btpan_disconnect(const RawAddress * bd_addr)256 static bt_status_t btpan_disconnect(const RawAddress* bd_addr) {
257 btpan_conn_t* conn = btpan_find_conn_addr(*bd_addr);
258 if (conn && conn->handle >= 0) {
259 /* Inform the application that the disconnect has been initiated
260 * successfully */
261 btif_transfer_context(btif_in_pan_generic_evt, BTIF_PAN_CB_DISCONNECTING, (char*)bd_addr,
262 sizeof(RawAddress), NULL);
263 BTA_PanClose(conn->handle);
264 return BT_STATUS_SUCCESS;
265 }
266 return BT_STATUS_DEVICE_NOT_FOUND;
267 }
268
269 static int pan_pth = -1;
create_tap_read_thread(int tap_fd)270 void create_tap_read_thread(int tap_fd) {
271 if (pan_pth < 0) {
272 pan_pth = btsock_thread_create(btpan_tap_fd_signaled, NULL);
273 }
274 if (pan_pth >= 0) {
275 btsock_thread_add_fd(pan_pth, tap_fd, 0, SOCK_THREAD_FD_RD, 0);
276 }
277 }
278
destroy_tap_read_thread(void)279 void destroy_tap_read_thread(void) {
280 if (pan_pth >= 0) {
281 btsock_thread_exit(pan_pth);
282 pan_pth = -1;
283 }
284 }
285
tap_if_up(const char * devname,const RawAddress & addr)286 static int tap_if_up(const char* devname, const RawAddress& addr) {
287 struct ifreq ifr;
288 int sk, err;
289
290 sk = socket(AF_INET, SOCK_DGRAM, 0);
291 if (sk < 0) {
292 return -1;
293 }
294
295 // set mac addr
296 memset(&ifr, 0, sizeof(ifr));
297 osi_strlcpy(ifr.ifr_name, devname, IFNAMSIZ);
298 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
299 if (err < 0) {
300 log::error("Could not get network hardware for interface:{}, errno:{}", devname,
301 strerror(errno));
302 close(sk);
303 return -1;
304 }
305
306 osi_strlcpy(ifr.ifr_name, devname, IFNAMSIZ);
307 memcpy(ifr.ifr_hwaddr.sa_data, addr.address, 6);
308
309 /* The IEEE has specified that the most significant bit of the most
310 * significant byte is used to
311 * determine a multicast address. If its a 1, that means multicast, 0 means
312 * unicast.
313 * Kernel returns an error if we try to set a multicast address for the
314 * tun-tap ethernet interface.
315 * Mask this bit to avoid any issue with auto generated address.
316 */
317 if (ifr.ifr_hwaddr.sa_data[0] & 0x01) {
318 log::warn("Not a unicast MAC address, force multicast bit flipping");
319 ifr.ifr_hwaddr.sa_data[0] &= ~0x01;
320 }
321
322 err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr);
323
324 if (err < 0) {
325 log::error("Could not set bt address for interface:{}, errno:{}", devname, strerror(errno));
326 close(sk);
327 return -1;
328 }
329
330 // bring it up
331 memset(&ifr, 0, sizeof(ifr));
332 osi_strlcpy(ifr.ifr_name, devname, IF_NAMESIZE);
333
334 ifr.ifr_flags |= IFF_UP;
335 ifr.ifr_flags |= IFF_MULTICAST;
336
337 err = ioctl(sk, SIOCSIFFLAGS, (caddr_t)&ifr);
338
339 if (err < 0) {
340 log::error("Could not bring up network interface:{}, errno:{}", devname, errno);
341 close(sk);
342 return -1;
343 }
344 close(sk);
345 log::verbose("network interface: {} is up", devname);
346 return 0;
347 }
348
tap_if_down(const char * devname)349 static int tap_if_down(const char* devname) {
350 struct ifreq ifr;
351 int sk;
352
353 sk = socket(AF_INET, SOCK_DGRAM, 0);
354 if (sk < 0) {
355 return -1;
356 }
357
358 memset(&ifr, 0, sizeof(ifr));
359 osi_strlcpy(ifr.ifr_name, devname, IF_NAMESIZE);
360
361 ifr.ifr_flags &= ~IFF_UP;
362
363 ioctl(sk, SIOCSIFFLAGS, (caddr_t)&ifr);
364
365 close(sk);
366
367 return 0;
368 }
369
btpan_set_flow_control(bool enable)370 void btpan_set_flow_control(bool enable) {
371 if (btpan_cb.tap_fd == -1) {
372 return;
373 }
374
375 btpan_cb.flow = enable;
376 if (enable) {
377 btsock_thread_add_fd(pan_pth, btpan_cb.tap_fd, 0, SOCK_THREAD_FD_RD, 0);
378 do_in_main_thread(base::BindOnce(btu_exec_tap_fd_read, btpan_cb.tap_fd));
379 }
380 }
381
btpan_tap_open()382 int btpan_tap_open() {
383 struct ifreq ifr;
384 int fd, err;
385 const char* clonedev = "/dev/tun";
386
387 /* open the clone device */
388
389 fd = open(clonedev, O_RDWR);
390 if (fd < 0) {
391 log::verbose("could not open {}, err:{}", clonedev, errno);
392 return fd;
393 }
394
395 memset(&ifr, 0, sizeof(ifr));
396 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
397
398 osi_strlcpy(ifr.ifr_name, TAP_IF_NAME, IFNAMSIZ);
399
400 /* try to create the device */
401 err = ioctl(fd, TUNSETIFF, (void*)&ifr);
402 if (err < 0) {
403 log::verbose("ioctl error:{}, errno:{}", err, strerror(errno));
404 close(fd);
405 return err;
406 }
407 if (tap_if_up(TAP_IF_NAME,
408 bluetooth::ToRawAddress(bluetooth::shim::GetController()->GetMacAddress())) == 0) {
409 int flags = fcntl(fd, F_GETFL, 0);
410 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
411 return fd;
412 }
413 log::error("can not bring up tap interface:{}", TAP_IF_NAME);
414 close(fd);
415 return INVALID_FD;
416 }
417
btpan_tap_send(int tap_fd,const RawAddress & src,const RawAddress & dst,uint16_t proto,const char * buf,uint16_t len,bool,bool)418 int btpan_tap_send(int tap_fd, const RawAddress& src, const RawAddress& dst, uint16_t proto,
419 const char* buf, uint16_t len, bool /* ext */, bool /* forward */) {
420 if (tap_fd != INVALID_FD) {
421 tETH_HDR eth_hdr;
422 eth_hdr.h_dest = dst;
423 eth_hdr.h_src = src;
424 eth_hdr.h_proto = htons(proto);
425 char packet[TAP_MAX_PKT_WRITE_LEN + sizeof(tETH_HDR)];
426 memcpy(packet, ð_hdr, sizeof(tETH_HDR));
427 if (len > TAP_MAX_PKT_WRITE_LEN) {
428 log::error("btpan_tap_send eth packet size:{} is exceeded limit!", len);
429 return -1;
430 }
431 memcpy(packet + sizeof(tETH_HDR), buf, len);
432
433 /* Send data to network interface */
434 ssize_t ret;
435 OSI_NO_INTR(ret = write(tap_fd, packet, len + sizeof(tETH_HDR)));
436 log::verbose("ret:{}", ret);
437 return (int)ret;
438 }
439 return -1;
440 }
441
btpan_tap_close(int fd)442 int btpan_tap_close(int fd) {
443 if (tap_if_down(TAP_IF_NAME) == 0) {
444 close(fd);
445 }
446 if (pan_pth >= 0) {
447 btsock_thread_wakeup(pan_pth);
448 }
449 return 0;
450 }
451
btpan_find_conn_handle(uint16_t handle)452 btpan_conn_t* btpan_find_conn_handle(uint16_t handle) {
453 for (int i = 0; i < MAX_PAN_CONNS; i++) {
454 if (btpan_cb.conns[i].handle == handle) {
455 return &btpan_cb.conns[i];
456 }
457 }
458 return NULL;
459 }
460
btpan_find_conn_addr(const RawAddress & addr)461 btpan_conn_t* btpan_find_conn_addr(const RawAddress& addr) {
462 for (int i = 0; i < MAX_PAN_CONNS; i++) {
463 if (btpan_cb.conns[i].peer == addr) {
464 return &btpan_cb.conns[i];
465 }
466 }
467 return NULL;
468 }
469
btpan_open_conn(btpan_conn_t * conn,tBTA_PAN * p_data)470 static void btpan_open_conn(btpan_conn_t* conn, tBTA_PAN* p_data) {
471 log::verbose("btpan_open_conn: local_role:{}, peer_role: {}, handle:{}, conn: {}",
472 p_data->open.local_role, p_data->open.peer_role, p_data->open.handle,
473 std::format_ptr(conn));
474
475 if (conn == NULL) {
476 conn = btpan_new_conn(p_data->open.handle, p_data->open.bd_addr, p_data->open.local_role,
477 p_data->open.peer_role);
478 }
479 if (conn) {
480 log::verbose(
481 "btpan_open_conn:tap_fd:{}, open_count:{}, conn->handle:{} should = "
482 "handle:{}, local_role:{}, remote_role:{}",
483 btpan_cb.tap_fd, btpan_cb.open_count, conn->handle, p_data->open.handle,
484 conn->local_role, conn->remote_role);
485
486 btpan_cb.open_count++;
487 conn->handle = p_data->open.handle;
488 if (btpan_cb.tap_fd < 0) {
489 btpan_cb.tap_fd = btpan_tap_open();
490 if (btpan_cb.tap_fd >= 0) {
491 create_tap_read_thread(btpan_cb.tap_fd);
492 }
493 }
494
495 if (btpan_cb.tap_fd >= 0) {
496 btpan_cb.flow = 1;
497 conn->state = PAN_STATE_OPEN;
498 }
499 }
500 }
501
btpan_close_conn(btpan_conn_t * conn)502 static void btpan_close_conn(btpan_conn_t* conn) {
503 log::verbose("btpan_close_conn: {}", std::format_ptr(conn));
504
505 if (conn && conn->state == PAN_STATE_OPEN) {
506 log::verbose("btpan_close_conn: PAN_STATE_OPEN");
507
508 conn->state = PAN_STATE_CLOSE;
509 btpan_cb.open_count--;
510
511 if (btpan_cb.open_count == 0) {
512 destroy_tap_read_thread();
513 if (btpan_cb.tap_fd != INVALID_FD) {
514 btpan_tap_close(btpan_cb.tap_fd);
515 btpan_cb.tap_fd = INVALID_FD;
516 }
517 }
518 }
519 }
520
btpan_cleanup_conn(btpan_conn_t * conn)521 static void btpan_cleanup_conn(btpan_conn_t* conn) {
522 if (conn) {
523 conn->handle = -1;
524 conn->state = -1;
525 memset(&conn->peer, 0, sizeof(conn->peer));
526 memset(&conn->eth_addr, 0, sizeof(conn->eth_addr));
527 conn->local_role = conn->remote_role = 0;
528 }
529 }
530
btpan_new_conn(int handle,const RawAddress & addr,tBTA_PAN_ROLE local_role,tBTA_PAN_ROLE remote_role)531 btpan_conn_t* btpan_new_conn(int handle, const RawAddress& addr, tBTA_PAN_ROLE local_role,
532 tBTA_PAN_ROLE remote_role) {
533 for (int i = 0; i < MAX_PAN_CONNS; i++) {
534 if (btpan_cb.conns[i].handle == -1) {
535 log::debug("Allocated new pan connection handle:{} local_role:{} remote_role:{}", handle,
536 local_role, remote_role);
537 btpan_cb.conns[i].handle = handle;
538 btpan_cb.conns[i].peer = addr;
539 btpan_cb.conns[i].local_role = local_role;
540 btpan_cb.conns[i].remote_role = remote_role;
541 return &btpan_cb.conns[i];
542 }
543 }
544 log::warn("Unable to create new pan connection max:{}", MAX_PAN_CONNS);
545 return nullptr;
546 }
547
should_forward(tETH_HDR * hdr)548 static inline bool should_forward(tETH_HDR* hdr) {
549 uint16_t proto = ntohs(hdr->h_proto);
550 if (proto == ETH_P_IP || proto == ETH_P_ARP || proto == ETH_P_IPV6) {
551 return true;
552 }
553 log::verbose("unknown proto:{:x}", proto);
554 return false;
555 }
556
forward_bnep(tETH_HDR * eth_hdr,BT_HDR * hdr)557 static int forward_bnep(tETH_HDR* eth_hdr, BT_HDR* hdr) {
558 int broadcast = eth_hdr->h_dest.address[0] & 1;
559
560 // Find the right connection to send this frame over.
561 for (int i = 0; i < MAX_PAN_CONNS; i++) {
562 uint16_t handle = btpan_cb.conns[i].handle;
563 if (handle != (uint16_t)-1 && (broadcast || btpan_cb.conns[i].eth_addr == eth_hdr->h_dest ||
564 btpan_cb.conns[i].peer == eth_hdr->h_dest)) {
565 int result = PAN_WriteBuf(handle, eth_hdr->h_dest, eth_hdr->h_src, ntohs(eth_hdr->h_proto),
566 hdr, 0);
567 switch (result) {
568 case PAN_Q_SIZE_EXCEEDED:
569 return FORWARD_CONGEST;
570 case PAN_SUCCESS:
571 return FORWARD_SUCCESS;
572 default:
573 return FORWARD_FAILURE;
574 }
575 }
576 }
577 osi_free(hdr);
578 return FORWARD_IGNORE;
579 }
580
bta_pan_callback_transfer(uint16_t event,char * p_param)581 static void bta_pan_callback_transfer(uint16_t event, char* p_param) {
582 tBTA_PAN* p_data = (tBTA_PAN*)p_param;
583
584 switch (event) {
585 case BTA_PAN_ENABLE_EVT:
586 log::verbose("BTA_PAN_ENABLE_EVT");
587 break;
588 case BTA_PAN_SET_ROLE_EVT: {
589 int btpan_role = bta_role_to_btpan(p_data->set_role.role);
590 bt_status_t status = (p_data->set_role.status) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
591 btpan_control_state_t state = btpan_role == 0 ? BTPAN_STATE_DISABLED : BTPAN_STATE_ENABLED;
592 callback.control_state_cb(state, btpan_role, status, TAP_IF_NAME);
593 break;
594 }
595 case BTA_PAN_OPENING_EVT: {
596 btpan_conn_t* conn;
597 log::verbose("BTA_PAN_OPENING_EVT handle {}, addr: {}", p_data->opening.handle,
598 p_data->opening.bd_addr);
599 conn = btpan_find_conn_addr(p_data->opening.bd_addr);
600
601 asrt(conn != NULL);
602 if (conn) {
603 conn->handle = p_data->opening.handle;
604 int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
605 int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
606 callback.connection_state_cb(BTPAN_STATE_CONNECTING, BT_STATUS_SUCCESS,
607 &p_data->opening.bd_addr, btpan_conn_local_role,
608 btpan_remote_role);
609 } else {
610 log::error("connection not found");
611 }
612 break;
613 }
614 case BTA_PAN_OPEN_EVT: {
615 btpan_connection_state_t state;
616 bt_status_t status;
617 btpan_conn_t* conn = btpan_find_conn_handle(p_data->open.handle);
618
619 log::verbose("pan connection open status: {}", p_data->open.status);
620 if (p_data->open.status) {
621 state = BTPAN_STATE_CONNECTED;
622 status = BT_STATUS_SUCCESS;
623 btpan_open_conn(conn, p_data);
624 } else {
625 state = BTPAN_STATE_DISCONNECTED;
626 status = BT_STATUS_FAIL;
627 btpan_cleanup_conn(conn);
628 }
629 /* debug("BTA_PAN_OPEN_EVT handle:%d, conn:%p", p_data->open.handle,
630 * conn); */
631 /* debug("conn bta local_role:%d, bta remote role:%d", conn->local_role,
632 * conn->remote_role); */
633 int btpan_conn_local_role = bta_role_to_btpan(p_data->open.local_role);
634 int btpan_remote_role = bta_role_to_btpan(p_data->open.peer_role);
635 callback.connection_state_cb(state, status, &p_data->open.bd_addr, btpan_conn_local_role,
636 btpan_remote_role);
637 break;
638 }
639 case BTA_PAN_CLOSE_EVT: {
640 log::info("event = BTA_PAN_CLOSE_EVT handle {}", p_data->close.handle);
641 btpan_conn_t* conn = btpan_find_conn_handle(p_data->close.handle);
642 btpan_close_conn(conn);
643
644 if (conn && conn->handle >= 0) {
645 int btpan_conn_local_role = bta_role_to_btpan(conn->local_role);
646 int btpan_remote_role = bta_role_to_btpan(conn->remote_role);
647 callback.connection_state_cb(BTPAN_STATE_DISCONNECTED, (bt_status_t)0, &conn->peer,
648 btpan_conn_local_role, btpan_remote_role);
649 btpan_cleanup_conn(conn);
650 } else {
651 log::error("pan handle not found ({})", p_data->close.handle);
652 }
653 break;
654 }
655 default:
656 log::warn("Unknown pan event {}", event);
657 break;
658 }
659 }
660
bta_pan_callback(tBTA_PAN_EVT event,tBTA_PAN * p_data)661 static void bta_pan_callback(tBTA_PAN_EVT event, tBTA_PAN* p_data) {
662 btif_transfer_context(bta_pan_callback_transfer, event, (char*)p_data, sizeof(tBTA_PAN), NULL);
663 }
664
665 #define IS_EXCEPTION(e) ((e) & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL))
btu_exec_tap_fd_read(int fd)666 static void btu_exec_tap_fd_read(int fd) {
667 struct pollfd ufd;
668
669 if (fd == INVALID_FD || fd != btpan_cb.tap_fd) {
670 return;
671 }
672
673 // Don't occupy BTU context too long, avoid buffer overruns and
674 // give other profiles a chance to run by limiting the amount of memory
675 // PAN can use.
676 for (int i = 0; i < PAN_BUF_MAX && btif_is_enabled() && btpan_cb.flow; i++) {
677 BT_HDR* buffer = (BT_HDR*)osi_malloc(PAN_BUF_SIZE);
678 buffer->offset = PAN_MINIMUM_OFFSET;
679 buffer->len = PAN_BUF_SIZE - sizeof(BT_HDR) - buffer->offset;
680
681 uint8_t* packet = (uint8_t*)buffer + sizeof(BT_HDR) + buffer->offset;
682
683 // If we don't have an undelivered packet left over, pull one from the TAP
684 // driver.
685 // We save it in the congest_packet right away in case we can't deliver it
686 // in this
687 // attempt.
688 if (!btpan_cb.congest_packet_size) {
689 ssize_t ret;
690 OSI_NO_INTR(ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet)));
691 switch (ret) {
692 case -1:
693 log::error("unable to read from driver: {}", strerror(errno));
694 osi_free(buffer);
695 // add fd back to monitor thread to try it again later
696 btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0);
697 return;
698 case 0:
699 log::warn("end of file reached.");
700 osi_free(buffer);
701 // add fd back to monitor thread to process the exception
702 btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0);
703 return;
704 default:
705 btpan_cb.congest_packet_size = ret;
706 break;
707 }
708 }
709
710 memcpy(packet, btpan_cb.congest_packet, MIN(btpan_cb.congest_packet_size, buffer->len));
711 buffer->len = MIN(btpan_cb.congest_packet_size, buffer->len);
712
713 if (buffer->len > sizeof(tETH_HDR) && should_forward((tETH_HDR*)packet)) {
714 // Extract the ethernet header from the buffer since the PAN_WriteBuf
715 // inside
716 // forward_bnep can't handle two pointers that point inside the same GKI
717 // buffer.
718 tETH_HDR hdr;
719 memcpy(&hdr, packet, sizeof(tETH_HDR));
720
721 // Skip the ethernet header.
722 buffer->len -= sizeof(tETH_HDR);
723 buffer->offset += sizeof(tETH_HDR);
724 if (forward_bnep(&hdr, buffer) != FORWARD_CONGEST) {
725 btpan_cb.congest_packet_size = 0;
726 }
727 } else {
728 log::warn("dropping packet of length {}", buffer->len);
729 btpan_cb.congest_packet_size = 0;
730 osi_free(buffer);
731 }
732
733 // Bail out of the loop if reading from the TAP fd would block.
734 ufd.fd = fd;
735 ufd.events = POLLIN;
736 ufd.revents = 0;
737
738 int ret;
739 OSI_NO_INTR(ret = poll(&ufd, 1, 0));
740 if (ret <= 0 || IS_EXCEPTION(ufd.revents)) {
741 break;
742 }
743 }
744
745 if (btpan_cb.flow) {
746 // add fd back to monitor thread when the flow is on
747 btsock_thread_add_fd(pan_pth, fd, 0, SOCK_THREAD_FD_RD, 0);
748 }
749 }
750
btif_pan_close_all_conns()751 static void btif_pan_close_all_conns() {
752 if (!stack_initialized) {
753 return;
754 }
755
756 for (int i = 0; i < MAX_PAN_CONNS; ++i) {
757 if (btpan_cb.conns[i].handle != -1) {
758 BTA_PanClose(btpan_cb.conns[i].handle);
759 }
760 }
761 }
762
btpan_tap_fd_signaled(int fd,int,int flags,uint32_t)763 static void btpan_tap_fd_signaled(int fd, int /*type*/, int flags, uint32_t /*user_id*/) {
764 log::assert_that(btpan_cb.tap_fd == INVALID_FD || btpan_cb.tap_fd == fd,
765 "assert failed: btpan_cb.tap_fd == INVALID_FD || btpan_cb.tap_fd == fd");
766
767 if (btpan_cb.tap_fd != fd) {
768 log::warn("Signaled on mismatched fds exp:{} act:{}", btpan_cb.tap_fd, fd);
769 return;
770 }
771
772 if (flags & SOCK_THREAD_FD_EXCEPTION) {
773 btpan_cb.tap_fd = INVALID_FD;
774 btpan_tap_close(fd);
775 btif_pan_close_all_conns();
776 } else if (flags & SOCK_THREAD_FD_RD) {
777 do_in_main_thread(base::BindOnce(btu_exec_tap_fd_read, fd));
778 }
779 }
780