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