1 /****************************************************************************** 2 * 3 * Copyright (C) 2004-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 * This file contains the pan action functions for the state machine. 22 * 23 ******************************************************************************/ 24 25 #include "bt_target.h" 26 27 #if (PAN_INCLUDED == TRUE) 28 29 #include <string.h> 30 31 #include <cutils/log.h> 32 33 #include "bt_common.h" 34 #include "bta_api.h" 35 #include "bta_pan_api.h" 36 #include "bta_pan_co.h" 37 #include "bta_pan_int.h" 38 #include "bta_sys.h" 39 #include "osi/include/osi.h" 40 #include "pan_api.h" 41 #include "utl.h" 42 43 /* RX and TX data flow mask */ 44 #define BTA_PAN_RX_MASK 0x0F 45 #define BTA_PAN_TX_MASK 0xF0 46 47 /******************************************************************************* 48 * 49 * Function bta_pan_pm_conn_busy 50 * 51 * Description set pan pm connection busy state 52 * 53 * Params p_scb: state machine control block of pan connection 54 * 55 * Returns void 56 * 57 ******************************************************************************/ 58 static void bta_pan_pm_conn_busy(tBTA_PAN_SCB* p_scb) { 59 if ((p_scb != NULL) && (p_scb->state != BTA_PAN_IDLE_ST)) 60 bta_sys_busy(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr); 61 } 62 63 /******************************************************************************* 64 * 65 * Function bta_pan_pm_conn_idle 66 * 67 * Description set pan pm connection idle state 68 * 69 * Params p_scb: state machine control block of pan connection 70 * 71 * Returns void 72 * 73 ******************************************************************************/ 74 static void bta_pan_pm_conn_idle(tBTA_PAN_SCB* p_scb) { 75 if ((p_scb != NULL) && (p_scb->state != BTA_PAN_IDLE_ST)) 76 bta_sys_idle(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr); 77 } 78 79 /******************************************************************************* 80 * 81 * Function bta_pan_conn_state_cback 82 * 83 * Description Connection state callback from Pan profile 84 * 85 * 86 * Returns void 87 * 88 ******************************************************************************/ 89 static void bta_pan_conn_state_cback(uint16_t handle, const RawAddress& bd_addr, 90 tPAN_RESULT state, bool is_role_change, 91 uint8_t src_role, uint8_t dst_role) { 92 tBTA_PAN_SCB* p_scb; 93 tBTA_PAN_CONN* p_buf = (tBTA_PAN_CONN*)osi_malloc(sizeof(tBTA_PAN_CONN)); 94 95 if ((state == PAN_SUCCESS) && !is_role_change) { 96 p_buf->hdr.event = BTA_PAN_CONN_OPEN_EVT; 97 p_scb = bta_pan_scb_by_handle(handle); 98 if (p_scb == NULL) { 99 /* allocate an scb */ 100 p_scb = bta_pan_scb_alloc(); 101 } 102 /* we have exceeded maximum number of connections */ 103 if (!p_scb) { 104 PAN_Disconnect(handle); 105 return; 106 } 107 108 p_scb->handle = handle; 109 p_scb->local_role = src_role; 110 p_scb->peer_role = dst_role; 111 p_scb->pan_flow_enable = true; 112 p_scb->bd_addr = bd_addr; 113 p_scb->data_queue = fixed_queue_new(SIZE_MAX); 114 115 if (src_role == PAN_ROLE_CLIENT) 116 p_scb->app_id = bta_pan_cb.app_id[0]; 117 else if (src_role == PAN_ROLE_GN_SERVER) 118 p_scb->app_id = bta_pan_cb.app_id[1]; 119 else if (src_role == PAN_ROLE_NAP_SERVER) 120 p_scb->app_id = bta_pan_cb.app_id[2]; 121 } else if ((state != PAN_SUCCESS) && !is_role_change) { 122 p_buf->hdr.event = BTA_PAN_CONN_CLOSE_EVT; 123 } else { 124 return; 125 } 126 127 p_buf->result = state; 128 p_buf->hdr.layer_specific = handle; 129 130 bta_sys_sendmsg(p_buf); 131 } 132 133 /******************************************************************************* 134 * 135 * Function bta_pan_data_flow_cb 136 * 137 * Description Data flow status callback from PAN 138 * 139 * 140 * Returns void 141 * 142 ******************************************************************************/ 143 static void bta_pan_data_flow_cb(uint16_t handle, tPAN_RESULT result) { 144 tBTA_PAN_SCB* p_scb; 145 146 p_scb = bta_pan_scb_by_handle(handle); 147 if (p_scb == NULL) return; 148 149 if (result == PAN_TX_FLOW_ON) { 150 BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 151 p_buf->layer_specific = handle; 152 p_buf->event = BTA_PAN_BNEP_FLOW_ENABLE_EVT; 153 bta_sys_sendmsg(p_buf); 154 bta_pan_co_rx_flow(handle, p_scb->app_id, true); 155 } else if (result == PAN_TX_FLOW_OFF) { 156 p_scb->pan_flow_enable = false; 157 bta_pan_co_rx_flow(handle, p_scb->app_id, false); 158 } 159 } 160 161 /******************************************************************************* 162 * 163 * Function bta_pan_data_buf_ind_cback 164 * 165 * Description data indication callback from pan profile 166 * 167 * 168 * Returns void 169 * 170 ******************************************************************************/ 171 static void bta_pan_data_buf_ind_cback(uint16_t handle, const RawAddress& src, 172 const RawAddress& dst, uint16_t protocol, 173 BT_HDR* p_buf, bool ext, bool forward) { 174 tBTA_PAN_SCB* p_scb; 175 BT_HDR* p_new_buf; 176 177 if (sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset) { 178 /* offset smaller than data structure in front of actual data */ 179 if (sizeof(BT_HDR) + sizeof(tBTA_PAN_DATA_PARAMS) + p_buf->len > 180 PAN_BUF_SIZE) { 181 android_errorWriteLog(0x534e4554, "63146237"); 182 APPL_TRACE_ERROR("%s: received buffer length too large: %d", __func__, 183 p_buf->len); 184 osi_free(p_buf); 185 return; 186 } 187 p_new_buf = (BT_HDR*)osi_malloc(PAN_BUF_SIZE); 188 memcpy((uint8_t*)(p_new_buf + 1) + sizeof(tBTA_PAN_DATA_PARAMS), 189 (uint8_t*)(p_buf + 1) + p_buf->offset, p_buf->len); 190 p_new_buf->len = p_buf->len; 191 p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS); 192 osi_free(p_buf); 193 } else { 194 p_new_buf = p_buf; 195 } 196 /* copy params into the space before the data */ 197 ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->src = src; 198 ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->dst = dst; 199 ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->protocol = protocol; 200 ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->ext = ext; 201 ((tBTA_PAN_DATA_PARAMS*)p_new_buf)->forward = forward; 202 203 p_scb = bta_pan_scb_by_handle(handle); 204 if (p_scb == NULL) { 205 osi_free(p_new_buf); 206 return; 207 } 208 209 fixed_queue_enqueue(p_scb->data_queue, p_new_buf); 210 BT_HDR* p_event = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 211 p_event->layer_specific = handle; 212 p_event->event = BTA_PAN_RX_FROM_BNEP_READY_EVT; 213 bta_sys_sendmsg(p_event); 214 } 215 216 /******************************************************************************* 217 * 218 * Function bta_pan_pfilt_ind_cback 219 * 220 * Description 221 * 222 * 223 * Returns void 224 * 225 ******************************************************************************/ 226 static void bta_pan_pfilt_ind_cback(uint16_t handle, bool indication, 227 tBNEP_RESULT result, uint16_t num_filters, 228 uint8_t* p_filters) { 229 bta_pan_co_pfilt_ind( 230 handle, indication, 231 (tBTA_PAN_STATUS)((result == BNEP_SUCCESS) ? BTA_PAN_SUCCESS 232 : BTA_PAN_FAIL), 233 num_filters, p_filters); 234 } 235 236 /******************************************************************************* 237 * 238 * Function bta_pan_mfilt_ind_cback 239 * 240 * Description 241 * 242 * 243 * Returns void 244 * 245 ******************************************************************************/ 246 static void bta_pan_mfilt_ind_cback(uint16_t handle, bool indication, 247 tBNEP_RESULT result, uint16_t num_mfilters, 248 uint8_t* p_mfilters) { 249 bta_pan_co_mfilt_ind( 250 handle, indication, 251 (tBTA_PAN_STATUS)((result == BNEP_SUCCESS) ? BTA_PAN_SUCCESS 252 : BTA_PAN_FAIL), 253 num_mfilters, p_mfilters); 254 } 255 256 /******************************************************************************* 257 * 258 * Function bta_pan_has_multiple_connections 259 * 260 * Description Check whether there are multiple GN/NAP connections to 261 * different devices 262 * 263 * 264 * Returns bool 265 * 266 ******************************************************************************/ 267 static bool bta_pan_has_multiple_connections(uint8_t app_id) { 268 tBTA_PAN_SCB* p_scb = NULL; 269 bool found = false; 270 RawAddress bd_addr; 271 272 for (uint8_t index = 0; index < BTA_PAN_NUM_CONN; index++) { 273 p_scb = &bta_pan_cb.scb[index]; 274 if (p_scb->in_use == true && app_id == p_scb->app_id) { 275 /* save temp bd_addr */ 276 bd_addr = p_scb->bd_addr; 277 found = true; 278 break; 279 } 280 } 281 282 /* If cannot find a match then there is no connection at all */ 283 if (found == false) return false; 284 285 /* Find whether there is another connection with different device other than 286 PANU. 287 Could be same service or different service */ 288 for (uint8_t index = 0; index < BTA_PAN_NUM_CONN; index++) { 289 p_scb = &bta_pan_cb.scb[index]; 290 if (p_scb->in_use == true && p_scb->app_id != bta_pan_cb.app_id[0] && 291 bd_addr != p_scb->bd_addr) { 292 return true; 293 } 294 } 295 return false; 296 } 297 298 /******************************************************************************* 299 * 300 * Function bta_pan_enable 301 * 302 * Description 303 * 304 * 305 * 306 * Returns void 307 * 308 ******************************************************************************/ 309 void bta_pan_enable(tBTA_PAN_DATA* p_data) { 310 tPAN_REGISTER reg_data; 311 uint16_t initial_discoverability; 312 uint16_t initial_connectability; 313 uint16_t d_window; 314 uint16_t d_interval; 315 uint16_t c_window; 316 uint16_t c_interval; 317 318 bta_pan_cb.p_cback = p_data->api_enable.p_cback; 319 320 reg_data.pan_conn_state_cb = bta_pan_conn_state_cback; 321 reg_data.pan_bridge_req_cb = NULL; 322 reg_data.pan_data_buf_ind_cb = bta_pan_data_buf_ind_cback; 323 reg_data.pan_data_ind_cb = NULL; 324 reg_data.pan_pfilt_ind_cb = bta_pan_pfilt_ind_cback; 325 reg_data.pan_mfilt_ind_cb = bta_pan_mfilt_ind_cback; 326 reg_data.pan_tx_data_flow_cb = bta_pan_data_flow_cb; 327 328 /* read connectability and discoverability settings. 329 Pan profile changes the settings. We have to change it back to 330 be consistent with other bta subsystems */ 331 initial_connectability = BTM_ReadConnectability(&c_window, &c_interval); 332 initial_discoverability = BTM_ReadDiscoverability(&d_window, &d_interval); 333 334 PAN_Register(®_data); 335 336 /* set it back to original value */ 337 BTM_SetDiscoverability(initial_discoverability, d_window, d_interval); 338 BTM_SetConnectability(initial_connectability, c_window, c_interval); 339 340 bta_pan_cb.flow_mask = bta_pan_co_init(&bta_pan_cb.q_level); 341 bta_pan_cb.p_cback(BTA_PAN_ENABLE_EVT, NULL); 342 } 343 344 /******************************************************************************* 345 * 346 * Function bta_pan_set_role 347 * 348 * Description 349 * 350 * Returns void 351 * 352 ******************************************************************************/ 353 void bta_pan_set_role(tBTA_PAN_DATA* p_data) { 354 tPAN_RESULT status; 355 tBTA_PAN bta_pan; 356 uint8_t sec[3]; 357 358 bta_pan_cb.app_id[0] = p_data->api_set_role.user_app_id; 359 bta_pan_cb.app_id[1] = p_data->api_set_role.gn_app_id; 360 bta_pan_cb.app_id[2] = p_data->api_set_role.nap_app_id; 361 362 sec[0] = p_data->api_set_role.user_sec_mask; 363 sec[1] = p_data->api_set_role.gn_sec_mask; 364 sec[2] = p_data->api_set_role.nap_sec_mask; 365 366 /* set security correctly in api and here */ 367 status = PAN_SetRole( 368 p_data->api_set_role.role, sec, p_data->api_set_role.user_name, 369 p_data->api_set_role.gn_name, p_data->api_set_role.nap_name); 370 371 bta_pan.set_role.role = p_data->api_set_role.role; 372 if (status == PAN_SUCCESS) { 373 if (p_data->api_set_role.role & PAN_ROLE_NAP_SERVER) 374 bta_sys_add_uuid(UUID_SERVCLASS_NAP); 375 else 376 bta_sys_remove_uuid(UUID_SERVCLASS_NAP); 377 378 if (p_data->api_set_role.role & PAN_ROLE_GN_SERVER) 379 bta_sys_add_uuid(UUID_SERVCLASS_GN); 380 else 381 bta_sys_remove_uuid(UUID_SERVCLASS_GN); 382 383 if (p_data->api_set_role.role & PAN_ROLE_CLIENT) 384 bta_sys_add_uuid(UUID_SERVCLASS_PANU); 385 else 386 bta_sys_remove_uuid(UUID_SERVCLASS_PANU); 387 388 bta_pan.set_role.status = BTA_PAN_SUCCESS; 389 } 390 /* if status is not success clear everything */ 391 else { 392 PAN_SetRole(0, 0, NULL, NULL, NULL); 393 bta_sys_remove_uuid(UUID_SERVCLASS_NAP); 394 bta_sys_remove_uuid(UUID_SERVCLASS_GN); 395 bta_sys_remove_uuid(UUID_SERVCLASS_PANU); 396 bta_pan.set_role.status = BTA_PAN_FAIL; 397 } 398 bta_pan_cb.p_cback(BTA_PAN_SET_ROLE_EVT, &bta_pan); 399 } 400 401 /******************************************************************************* 402 * 403 * Function bta_pan_disable 404 * 405 * Description 406 * 407 * 408 * 409 * Returns void 410 * 411 ******************************************************************************/ 412 void bta_pan_disable(void) { 413 BT_HDR* p_buf; 414 tBTA_PAN_SCB* p_scb = &bta_pan_cb.scb[0]; 415 uint8_t i; 416 417 /* close all connections */ 418 PAN_SetRole(0, NULL, NULL, NULL, NULL); 419 420 #if (BTA_EIR_CANNED_UUID_LIST != TRUE) 421 bta_sys_remove_uuid(UUID_SERVCLASS_NAP); 422 bta_sys_remove_uuid(UUID_SERVCLASS_GN); 423 bta_sys_remove_uuid(UUID_SERVCLASS_PANU); 424 #endif // BTA_EIR_CANNED_UUID_LIST 425 /* free all queued up data buffers */ 426 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++) { 427 if (p_scb->in_use) { 428 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_scb->data_queue)) != 429 NULL) 430 osi_free(p_buf); 431 432 bta_pan_co_close(p_scb->handle, p_scb->app_id); 433 } 434 } 435 436 PAN_Deregister(); 437 } 438 439 /******************************************************************************* 440 * 441 * Function bta_pan_open 442 * 443 * Description 444 * 445 * Returns void 446 * 447 ******************************************************************************/ 448 void bta_pan_open(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 449 tPAN_RESULT status; 450 tBTA_PAN bta_pan; 451 452 status = PAN_Connect(p_data->api_open.bd_addr, p_data->api_open.local_role, 453 p_data->api_open.peer_role, &p_scb->handle); 454 APPL_TRACE_DEBUG("%s pan connect status: %d", __func__, status); 455 456 if (status == PAN_SUCCESS) { 457 p_scb->bd_addr = p_data->api_open.bd_addr; 458 p_scb->local_role = p_data->api_open.local_role; 459 p_scb->peer_role = p_data->api_open.peer_role; 460 bta_pan.opening.bd_addr = p_data->api_open.bd_addr; 461 bta_pan.opening.handle = p_scb->handle; 462 bta_pan_cb.p_cback(BTA_PAN_OPENING_EVT, &bta_pan); 463 464 } else { 465 bta_pan_scb_dealloc(p_scb); 466 bta_pan.open.bd_addr = p_data->api_open.bd_addr; 467 bta_pan.open.status = BTA_PAN_FAIL; 468 bta_pan.open.local_role = p_data->api_open.local_role; 469 bta_pan.open.peer_role = p_data->api_open.peer_role; 470 bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, &bta_pan); 471 } 472 } 473 474 /******************************************************************************* 475 * 476 * Function bta_pan_close 477 * 478 * Description 479 * 480 * 481 * 482 * Returns void 483 * 484 ******************************************************************************/ 485 void bta_pan_api_close(tBTA_PAN_SCB* p_scb, UNUSED_ATTR tBTA_PAN_DATA* p_data) { 486 tBTA_PAN_CONN* p_buf = (tBTA_PAN_CONN*)osi_malloc(sizeof(tBTA_PAN_CONN)); 487 488 PAN_Disconnect(p_scb->handle); 489 490 /* 491 * Send an event to BTA so that application will get the connection 492 * close event. 493 */ 494 p_buf->hdr.event = BTA_PAN_CONN_CLOSE_EVT; 495 p_buf->hdr.layer_specific = p_scb->handle; 496 497 bta_sys_sendmsg(p_buf); 498 } 499 500 /******************************************************************************* 501 * 502 * Function bta_pan_conn_open 503 * 504 * Description process connection open event 505 * 506 * Returns void 507 * 508 ******************************************************************************/ 509 void bta_pan_conn_open(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 510 tBTA_PAN bta_pan; 511 512 APPL_TRACE_DEBUG("%s pan connection result: %d", __func__, 513 p_data->conn.result); 514 515 bta_pan.open.bd_addr = p_scb->bd_addr; 516 bta_pan.open.handle = p_scb->handle; 517 bta_pan.open.local_role = p_scb->local_role; 518 bta_pan.open.peer_role = p_scb->peer_role; 519 520 if (p_data->conn.result == PAN_SUCCESS) { 521 bta_pan.open.status = BTA_PAN_SUCCESS; 522 p_scb->pan_flow_enable = true; 523 p_scb->app_flow_enable = true; 524 bta_sys_conn_open(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr); 525 } else { 526 bta_pan_scb_dealloc(p_scb); 527 bta_pan.open.status = BTA_PAN_FAIL; 528 } 529 530 p_scb->pan_flow_enable = true; 531 p_scb->app_flow_enable = true; 532 533 /* If app_id is NAP/GN, check whether there are multiple connections. 534 If there are, provide a special app_id to dm to enforce master role only. 535 */ 536 if ((p_scb->app_id == bta_pan_cb.app_id[1] || 537 p_scb->app_id == bta_pan_cb.app_id[2]) && 538 bta_pan_has_multiple_connections(p_scb->app_id)) { 539 p_scb->app_id = BTA_APP_ID_PAN_MULTI; 540 } 541 542 bta_sys_conn_open(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr); 543 bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, &bta_pan); 544 } 545 546 /******************************************************************************* 547 * 548 * Function bta_pan_conn_close 549 * 550 * Description process connection close event 551 * 552 * 553 * 554 * Returns void 555 * 556 ******************************************************************************/ 557 void bta_pan_conn_close(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 558 tBTA_PAN bta_pan; 559 BT_HDR* p_buf; 560 561 bta_pan.close.handle = p_data->hdr.layer_specific; 562 563 bta_sys_conn_close(BTA_ID_PAN, p_scb->app_id, p_scb->bd_addr); 564 565 /* free all queued up data buffers */ 566 while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_scb->data_queue)) != NULL) 567 osi_free(p_buf); 568 569 bta_pan_scb_dealloc(p_scb); 570 571 bta_pan_cb.p_cback(BTA_PAN_CLOSE_EVT, &bta_pan); 572 } 573 574 /******************************************************************************* 575 * 576 * Function bta_pan_rx_path 577 * 578 * Description Handle data on the RX path (data sent from the phone to 579 * BTA). 580 * 581 * 582 * Returns void 583 * 584 ******************************************************************************/ 585 void bta_pan_rx_path(tBTA_PAN_SCB* p_scb, UNUSED_ATTR tBTA_PAN_DATA* p_data) { 586 /* if data path configured for rx pull */ 587 if ((bta_pan_cb.flow_mask & BTA_PAN_RX_MASK) == BTA_PAN_RX_PULL) { 588 /* if we can accept data */ 589 if (p_scb->pan_flow_enable == true) { 590 /* call application callout function for rx path */ 591 bta_pan_co_rx_path(p_scb->handle, p_scb->app_id); 592 } 593 } 594 /* else data path configured for rx push */ 595 else { 596 } 597 } 598 599 /******************************************************************************* 600 * 601 * Function bta_pan_tx_path 602 * 603 * Description Handle the TX data path (data sent from BTA to the phone). 604 * 605 * 606 * Returns void 607 * 608 ******************************************************************************/ 609 void bta_pan_tx_path(tBTA_PAN_SCB* p_scb, UNUSED_ATTR tBTA_PAN_DATA* p_data) { 610 /* if data path configured for tx pull */ 611 if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PULL) { 612 bta_pan_pm_conn_busy(p_scb); 613 /* call application callout function for tx path */ 614 bta_pan_co_tx_path(p_scb->handle, p_scb->app_id); 615 616 /* free data that exceeds queue level */ 617 while (fixed_queue_length(p_scb->data_queue) > bta_pan_cb.q_level) 618 osi_free(fixed_queue_try_dequeue(p_scb->data_queue)); 619 bta_pan_pm_conn_idle(p_scb); 620 } 621 /* if configured for zero copy push */ 622 else if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PUSH_BUF) { 623 /* if app can accept data */ 624 if (p_scb->app_flow_enable == true) { 625 BT_HDR* p_buf; 626 627 /* read data from the queue */ 628 p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_scb->data_queue); 629 if (p_buf != NULL) { 630 /* send data to application */ 631 bta_pan_co_tx_writebuf(p_scb->handle, p_scb->app_id, 632 ((tBTA_PAN_DATA_PARAMS*)p_buf)->src, 633 ((tBTA_PAN_DATA_PARAMS*)p_buf)->dst, 634 ((tBTA_PAN_DATA_PARAMS*)p_buf)->protocol, p_buf, 635 ((tBTA_PAN_DATA_PARAMS*)p_buf)->ext, 636 ((tBTA_PAN_DATA_PARAMS*)p_buf)->forward); 637 } 638 /* free data that exceeds queue level */ 639 while (fixed_queue_length(p_scb->data_queue) > bta_pan_cb.q_level) 640 osi_free(fixed_queue_try_dequeue(p_scb->data_queue)); 641 642 /* if there is more data to be passed to 643 upper layer */ 644 if (!fixed_queue_is_empty(p_scb->data_queue)) { 645 p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR)); 646 p_buf->layer_specific = p_scb->handle; 647 p_buf->event = BTA_PAN_RX_FROM_BNEP_READY_EVT; 648 bta_sys_sendmsg(p_buf); 649 } 650 } 651 } 652 } 653 654 /******************************************************************************* 655 * 656 * Function bta_pan_tx_flow 657 * 658 * Description Set the application flow control state. 659 * 660 * 661 * Returns void 662 * 663 ******************************************************************************/ 664 void bta_pan_tx_flow(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 665 p_scb->app_flow_enable = p_data->ci_tx_flow.enable; 666 } 667 668 /******************************************************************************* 669 * 670 * Function bta_pan_write_buf 671 * 672 * Description Handle a bta_pan_ci_rx_writebuf() and send data to PAN. 673 * 674 * 675 * Returns void 676 * 677 ******************************************************************************/ 678 void bta_pan_write_buf(tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 679 if ((bta_pan_cb.flow_mask & BTA_PAN_RX_MASK) == BTA_PAN_RX_PUSH_BUF) { 680 bta_pan_pm_conn_busy(p_scb); 681 682 PAN_WriteBuf(p_scb->handle, ((tBTA_PAN_DATA_PARAMS*)p_data)->dst, 683 ((tBTA_PAN_DATA_PARAMS*)p_data)->src, 684 ((tBTA_PAN_DATA_PARAMS*)p_data)->protocol, (BT_HDR*)p_data, 685 ((tBTA_PAN_DATA_PARAMS*)p_data)->ext); 686 bta_pan_pm_conn_idle(p_scb); 687 } 688 } 689 690 /******************************************************************************* 691 * 692 * Function bta_pan_free_buf 693 * 694 * Description Frees the data buffer during closing state 695 * 696 * 697 * Returns void 698 * 699 ******************************************************************************/ 700 void bta_pan_free_buf(UNUSED_ATTR tBTA_PAN_SCB* p_scb, tBTA_PAN_DATA* p_data) { 701 osi_free(p_data); 702 } 703 704 #endif /* PAN_INCLUDED */ 705