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