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