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