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: hci_mct.c 22 * 23 * Description: Contains HCI transport send/receive functions 24 * for Multi-Channels Transport 25 * 26 ******************************************************************************/ 27 28 #define LOG_TAG "bt_mct" 29 30 #include <utils/Log.h> 31 #include <stdlib.h> 32 #include <fcntl.h> 33 34 #include "bt_hci_bdroid.h" 35 #include "btsnoop.h" 36 #include "hci.h" 37 #include "userial.h" 38 #include "utils.h" 39 #include "vendor.h" 40 41 /****************************************************************************** 42 ** Constants & Macros 43 ******************************************************************************/ 44 45 #ifndef HCI_DBG 46 #define HCI_DBG FALSE 47 #endif 48 49 #if (HCI_DBG == TRUE) 50 #define HCIDBG(param, ...) {LOGD(param, ## __VA_ARGS__);} 51 #else 52 #define HCIDBG(param, ...) {} 53 #endif 54 55 /* Preamble length for HCI Commands: 56 ** 2-bytes for opcode and 1 byte for length 57 */ 58 #define HCI_CMD_PREAMBLE_SIZE 3 59 60 /* Preamble length for HCI Events: 61 ** 1-byte for opcode and 1 byte for length 62 */ 63 #define HCI_EVT_PREAMBLE_SIZE 2 64 65 /* Preamble length for SCO Data: 66 ** 2-byte for Handle and 1 byte for length 67 */ 68 #define HCI_SCO_PREAMBLE_SIZE 3 69 70 /* Preamble length for ACL Data: 71 ** 2-byte for Handle and 2 byte for length 72 */ 73 #define HCI_ACL_PREAMBLE_SIZE 4 74 75 #define ACL_RX_PKT_START 2 76 #define ACL_RX_PKT_CONTINUE 1 77 #define L2CAP_HEADER_SIZE 4 78 79 /* Maximum numbers of allowed internal 80 ** outstanding command packets at any time 81 */ 82 #define INT_CMD_PKT_MAX_COUNT 8 83 #define INT_CMD_PKT_IDX_MASK 0x07 84 85 #define HCI_COMMAND_COMPLETE_EVT 0x0E 86 #define HCI_COMMAND_STATUS_EVT 0x0F 87 #define HCI_READ_BUFFER_SIZE 0x1005 88 #define HCI_LE_READ_BUFFER_SIZE 0x2002 89 90 /****************************************************************************** 91 ** Local type definitions 92 ******************************************************************************/ 93 94 /* MCT Rx States */ 95 typedef enum { 96 MCT_RX_NEWMSG_ST, 97 MCT_RX_LEN_ST, 98 MCT_RX_DATA_ST, 99 MCT_RX_IGNORE_ST 100 } tHCI_MCT_RCV_STATE; 101 102 /* Callback function for the returned event of internal issued command */ 103 typedef void (*tINT_CMD_CBACK)(void *p_mem); 104 105 typedef struct 106 { 107 uint16_t opcode; /* OPCODE of outstanding internal commands */ 108 tINT_CMD_CBACK cback; /* Callback function when return of internal 109 * command is received */ 110 } tINT_CMD_Q; 111 112 typedef struct 113 { 114 HC_BT_HDR *p_rcv_msg; /* Buffer to hold current rx HCI message */ 115 uint16_t rcv_len; /* Size of current incoming message */ 116 tHCI_MCT_RCV_STATE rcv_state; /* Receive state of current rx message */ 117 uint8_t preload_count; /* Count numbers of preload bytes */ 118 uint8_t preload_buffer[6]; /* HCI_ACL_PREAMBLE_SIZE + 2 */ 119 } tHCI_RCV_CB; 120 121 /* Control block for HCISU_MCT */ 122 typedef struct 123 { 124 tHCI_RCV_CB rcv_evt; 125 tHCI_RCV_CB rcv_acl; 126 uint16_t hc_acl_data_size; /* Controller's max ACL data length */ 127 uint16_t hc_ble_acl_data_size; /* Controller's max BLE ACL data length */ 128 BUFFER_Q acl_rx_q; /* Queue of base buffers for fragmented ACL pkts */ 129 int int_cmd_rsp_pending; /* Num of internal cmds pending for ack */ 130 uint8_t int_cmd_rd_idx; /* Read index of int_cmd_opcode queue */ 131 uint8_t int_cmd_wrt_idx; /* Write index of int_cmd_opcode queue */ 132 tINT_CMD_Q int_cmd[INT_CMD_PKT_MAX_COUNT]; /* FIFO queue */ 133 } tHCI_MCT_CB; 134 135 /****************************************************************************** 136 ** Externs 137 ******************************************************************************/ 138 139 uint8_t hci_mct_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \ 140 tINT_CMD_CBACK p_cback); 141 void lpm_wake_assert(void); 142 void lpm_tx_done(uint8_t is_tx_done); 143 144 /****************************************************************************** 145 ** Variables 146 ******************************************************************************/ 147 148 /* Num of allowed outstanding HCI CMD packets */ 149 volatile int num_hci_cmd_pkts = 1; 150 151 /****************************************************************************** 152 ** Static variables 153 ******************************************************************************/ 154 155 static tHCI_MCT_CB mct_cb; 156 157 /****************************************************************************** 158 ** Static functions 159 ******************************************************************************/ 160 161 /******************************************************************************* 162 ** 163 ** Function get_acl_data_length_cback 164 ** 165 ** Description Callback function for HCI_READ_BUFFER_SIZE and 166 ** HCI_LE_READ_BUFFER_SIZE commands if they were sent because 167 ** of internal request. 168 ** 169 ** Returns None 170 ** 171 *******************************************************************************/ 172 void get_acl_data_length_cback(void *p_mem) 173 { 174 uint8_t *p, status; 175 uint16_t opcode, len=0; 176 HC_BT_HDR *p_buf = (HC_BT_HDR *) p_mem; 177 178 p = (uint8_t *)(p_buf + 1) + 3; 179 STREAM_TO_UINT16(opcode, p) 180 status = *p++; 181 if (status == 0) /* Success */ 182 STREAM_TO_UINT16(len, p) 183 184 if (opcode == HCI_READ_BUFFER_SIZE) 185 { 186 if (status == 0) 187 mct_cb.hc_acl_data_size = len; 188 189 /* reuse the rx buffer for sending HCI_LE_READ_BUFFER_SIZE command */ 190 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 191 p_buf->offset = 0; 192 p_buf->layer_specific = 0; 193 p_buf->len = 3; 194 195 p = (uint8_t *) (p_buf + 1); 196 UINT16_TO_STREAM(p, HCI_LE_READ_BUFFER_SIZE); 197 *p = 0; 198 199 if ((status = hci_mct_send_int_cmd(HCI_LE_READ_BUFFER_SIZE, p_buf, \ 200 get_acl_data_length_cback)) == FALSE) 201 { 202 bt_hc_cbacks->dealloc(p_buf); 203 bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_SUCCESS); 204 } 205 } 206 else if (opcode == HCI_LE_READ_BUFFER_SIZE) 207 { 208 if (status == 0) 209 mct_cb.hc_ble_acl_data_size = (len) ? len : mct_cb.hc_acl_data_size; 210 211 if (bt_hc_cbacks) 212 { 213 bt_hc_cbacks->dealloc(p_buf); 214 ALOGE("hci lib postload completed"); 215 bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_SUCCESS); 216 } 217 } 218 } 219 220 221 /******************************************************************************* 222 ** 223 ** Function internal_event_intercept 224 ** 225 ** Description This function is called to parse received HCI event and 226 ** - update the Num_HCI_Command_Packets 227 ** - intercept the event if it is the result of an early 228 ** issued internal command. 229 ** 230 ** Returns TRUE : if the event had been intercepted for internal process 231 ** FALSE : send this event to core stack 232 ** 233 *******************************************************************************/ 234 uint8_t internal_event_intercept(void) 235 { 236 uint8_t *p; 237 uint8_t event_code; 238 uint16_t opcode, len; 239 tHCI_MCT_CB *p_cb = &mct_cb; 240 241 p = (uint8_t *)(p_cb->rcv_evt.p_rcv_msg + 1); 242 243 event_code = *p++; 244 len = *p++; 245 246 if (event_code == HCI_COMMAND_COMPLETE_EVT) 247 { 248 utils_lock(); 249 num_hci_cmd_pkts = *p++; 250 utils_unlock(); 251 252 // Signal TX event so the worker thread can check if it has anything 253 // to send 254 bthc_tx(NULL); 255 256 if (p_cb->int_cmd_rsp_pending > 0) 257 { 258 STREAM_TO_UINT16(opcode, p) 259 260 if (opcode == p_cb->int_cmd[p_cb->int_cmd_rd_idx].opcode) 261 { 262 HCIDBG( \ 263 "Intercept CommandCompleteEvent for internal command (0x%04X)",\ 264 opcode); 265 if (p_cb->int_cmd[p_cb->int_cmd_rd_idx].cback != NULL) 266 { 267 p_cb->int_cmd[p_cb->int_cmd_rd_idx].cback(p_cb->rcv_evt.p_rcv_msg); 268 } 269 else 270 { 271 // Missing cback function! 272 // Release the p_rcv_msg buffer. 273 if (bt_hc_cbacks) 274 { 275 bt_hc_cbacks->dealloc(p_cb->rcv_evt.p_rcv_msg); 276 } 277 } 278 p_cb->int_cmd_rd_idx = ((p_cb->int_cmd_rd_idx+1) & \ 279 INT_CMD_PKT_IDX_MASK); 280 p_cb->int_cmd_rsp_pending--; 281 return TRUE; 282 } 283 } 284 } 285 else if (event_code == HCI_COMMAND_STATUS_EVT) 286 { 287 utils_lock(); 288 num_hci_cmd_pkts = *(++p); 289 utils_unlock(); 290 291 // Signal TX event so the worker thread can check if it has anything 292 // to send 293 bthc_tx(NULL); 294 } 295 296 return FALSE; 297 } 298 299 /******************************************************************************* 300 ** 301 ** Function acl_rx_frame_buffer_alloc 302 ** 303 ** Description This function is called from the HCI transport when the 304 ** first 4 or 6 bytes of an HCI ACL packet have been received: 305 ** - Allocate a new buffer if it is a start pakcet of L2CAP 306 ** message. 307 ** - Return the buffer address of the starting L2CAP message 308 ** frame if the packet is the next segment of a fragmented 309 ** L2CAP message. 310 ** 311 ** Returns the address of the receive buffer caller should use 312 ** (CR419: Modified to return NULL in case of error.) 313 ** 314 ** NOTE This assumes that the L2CAP MTU size is less than the size 315 ** of an HCI ACL buffer, so the maximum L2CAP message will fit 316 ** into one buffer. 317 ** 318 *******************************************************************************/ 319 static HC_BT_HDR *acl_rx_frame_buffer_alloc (void) 320 { 321 uint8_t *p; 322 uint16_t handle; 323 uint16_t hci_len; 324 uint16_t total_len; 325 uint8_t pkt_type; 326 HC_BT_HDR *p_return_buf = NULL; 327 tHCI_MCT_CB *p_cb = &mct_cb; 328 329 330 p = p_cb->rcv_acl.preload_buffer; 331 332 STREAM_TO_UINT16 (handle, p); 333 STREAM_TO_UINT16 (hci_len, p); 334 STREAM_TO_UINT16 (total_len, p); 335 336 pkt_type = (uint8_t)(((handle) >> 12) & 0x0003); 337 handle = (uint16_t)((handle) & 0x0FFF); 338 339 if (p_cb->acl_rx_q.count) 340 { 341 uint16_t save_handle; 342 HC_BT_HDR *p_hdr = p_cb->acl_rx_q.p_first; 343 344 while (p_hdr != NULL) 345 { 346 p = (uint8_t *)(p_hdr + 1); 347 STREAM_TO_UINT16 (save_handle, p); 348 save_handle = (uint16_t)((save_handle) & 0x0FFF); 349 if (save_handle == handle) 350 { 351 p_return_buf = p_hdr; 352 break; 353 } 354 p_hdr = utils_getnext(p_hdr); 355 } 356 } 357 358 if (pkt_type == ACL_RX_PKT_START) /*** START PACKET ***/ 359 { 360 /* Might have read 2 bytes for the L2CAP payload length */ 361 p_cb->rcv_acl.rcv_len = (hci_len) ? (hci_len - 2) : 0; 362 363 /* Start of packet. If we were in the middle of receiving */ 364 /* a packet on the same ACL handle, the original packet is incomplete. 365 * Drop it. */ 366 if (p_return_buf) 367 { 368 ALOGW("dropping incomplete ACL frame"); 369 370 utils_remove_from_queue(&(p_cb->acl_rx_q), p_return_buf); 371 372 if (bt_hc_cbacks) 373 { 374 bt_hc_cbacks->dealloc(p_return_buf); 375 } 376 p_return_buf = NULL; 377 } 378 379 /* Allocate a buffer for message */ 380 if (bt_hc_cbacks) 381 { 382 int len = total_len + HCI_ACL_PREAMBLE_SIZE + L2CAP_HEADER_SIZE + \ 383 BT_HC_HDR_SIZE; 384 p_return_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc(len); 385 } 386 387 if (p_return_buf) 388 { 389 /* Initialize buffer with preloaded data */ 390 p_return_buf->offset = 0; 391 p_return_buf->layer_specific = 0; 392 p_return_buf->event = MSG_HC_TO_STACK_HCI_ACL; 393 p_return_buf->len = p_cb->rcv_acl.preload_count; 394 memcpy((uint8_t *)(p_return_buf + 1), p_cb->rcv_acl.preload_buffer, \ 395 p_cb->rcv_acl.preload_count); 396 397 if (hci_len && ((total_len + L2CAP_HEADER_SIZE) > hci_len)) 398 { 399 /* Will expect to see fragmented ACL packets */ 400 /* Keep the base buffer address in the watching queue */ 401 utils_enqueue(&(p_cb->acl_rx_q), p_return_buf); 402 } 403 } 404 } 405 else /*** CONTINUATION PACKET ***/ 406 { 407 p_cb->rcv_acl.rcv_len = hci_len; 408 409 if (p_return_buf) 410 { 411 /* Packet continuation and found the original rx buffer */ 412 uint8_t *p_f = p = (uint8_t *)(p_return_buf + 1) + 2; 413 414 STREAM_TO_UINT16 (total_len, p); 415 416 /* Update HCI header of first segment (base buffer) with new len */ 417 total_len += hci_len; 418 UINT16_TO_STREAM (p_f, total_len); 419 } 420 } 421 422 return (p_return_buf); 423 } 424 425 /******************************************************************************* 426 ** 427 ** Function acl_rx_frame_end_chk 428 ** 429 ** Description This function is called from the HCI transport when the last 430 ** byte of an HCI ACL packet has been received. It checks if 431 ** the L2CAP message is complete, i.e. no more continuation 432 ** packets are expected. 433 ** 434 ** Returns TRUE if message complete, FALSE if continuation expected 435 ** 436 *******************************************************************************/ 437 static uint8_t acl_rx_frame_end_chk (void) 438 { 439 uint8_t *p; 440 uint16_t handle, hci_len, l2cap_len; 441 HC_BT_HDR *p_buf; 442 tHCI_MCT_CB *p_cb = &mct_cb; 443 uint8_t frame_end=TRUE; 444 445 p_buf = p_cb->rcv_acl.p_rcv_msg; 446 p = (uint8_t *)(p_buf + 1); 447 448 STREAM_TO_UINT16 (handle, p); 449 STREAM_TO_UINT16 (hci_len, p); 450 STREAM_TO_UINT16 (l2cap_len, p); 451 452 if (hci_len > 0) 453 { 454 if (l2cap_len > (p_buf->len-(HCI_ACL_PREAMBLE_SIZE+L2CAP_HEADER_SIZE)) ) 455 { 456 /* If the L2CAP length has not been reached, tell caller not to send 457 * this buffer to stack */ 458 frame_end = FALSE; 459 } 460 else 461 { 462 /* 463 * The current buffer coulb be in the watching list. 464 * Remove it from the list if it is in. 465 */ 466 if (p_cb->acl_rx_q.count) 467 utils_remove_from_queue(&(p_cb->acl_rx_q), p_buf); 468 } 469 } 470 471 /**** 472 ** Print snoop trace 473 ****/ 474 if (p_buf->offset) 475 { 476 /* CONTINUATION PACKET */ 477 478 /* save original p_buf->len content */ 479 uint16_t tmp_u16 = p_buf->len; 480 481 /* borrow HCI_ACL_PREAMBLE_SIZE bytes from the payload section */ 482 p = (uint8_t *)(p_buf + 1) + p_buf->offset - HCI_ACL_PREAMBLE_SIZE; 483 484 /* save contents */ 485 memcpy(p_cb->rcv_acl.preload_buffer, p, HCI_ACL_PREAMBLE_SIZE); 486 487 /* Set packet boundary flags to "continuation packet" */ 488 handle = (handle & 0xCFFF) | 0x1000; 489 490 /* write handl & length info */ 491 UINT16_TO_STREAM (p, handle); 492 UINT16_TO_STREAM (p, (p_buf->len - p_buf->offset)); 493 494 /* roll pointer back */ 495 p = p - HCI_ACL_PREAMBLE_SIZE; 496 497 /* adjust `p_buf->offset` & `p_buf->len` 498 * before calling btsnoop_capture() */ 499 p_buf->offset = p_buf->offset - HCI_ACL_PREAMBLE_SIZE; 500 p_buf->len = p_buf->len - p_buf->offset; 501 502 btsnoop_capture(p_buf, true); 503 504 /* restore contents */ 505 memcpy(p, p_cb->rcv_acl.preload_buffer, HCI_ACL_PREAMBLE_SIZE); 506 507 /* restore p_buf->len */ 508 p_buf->len = tmp_u16; 509 } 510 else 511 { 512 /* START PACKET */ 513 btsnoop_capture(p_buf, true); 514 } 515 516 if (frame_end == TRUE) 517 p_buf->offset = 0; 518 else 519 p_buf->offset = p_buf->len; /* save current buffer-end position */ 520 521 return frame_end; 522 } 523 524 /***************************************************************************** 525 ** HCI MCT INTERFACE FUNCTIONS 526 *****************************************************************************/ 527 528 /******************************************************************************* 529 ** 530 ** Function hci_mct_init 531 ** 532 ** Description Initialize MCT module 533 ** 534 ** Returns None 535 ** 536 *******************************************************************************/ 537 void hci_mct_init(void) 538 { 539 HCIDBG("hci_mct_init"); 540 541 memset(&mct_cb, 0, sizeof(tHCI_MCT_CB)); 542 utils_queue_init(&(mct_cb.acl_rx_q)); 543 544 /* Per HCI spec., always starts with 1 */ 545 num_hci_cmd_pkts = 1; 546 547 /* Give an initial values of Host Controller's ACL data packet length 548 * Will update with an internal HCI(_LE)_Read_Buffer_Size request 549 */ 550 mct_cb.hc_acl_data_size = 1021; 551 mct_cb.hc_ble_acl_data_size = 27; 552 } 553 554 /******************************************************************************* 555 ** 556 ** Function hci_mct_cleanup 557 ** 558 ** Description Clean MCT module 559 ** 560 ** Returns None 561 ** 562 *******************************************************************************/ 563 void hci_mct_cleanup(void) 564 { 565 HCIDBG("hci_mct_cleanup"); 566 } 567 568 /******************************************************************************* 569 ** 570 ** Function hci_mct_send_msg 571 ** 572 ** Description Determine message type, then send message through according 573 ** channel 574 ** 575 ** Returns None 576 ** 577 *******************************************************************************/ 578 void hci_mct_send_msg(HC_BT_HDR *p_msg) 579 { 580 uint16_t handle; 581 uint16_t lay_spec; 582 uint8_t *p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 583 uint16_t event = p_msg->event & MSG_EVT_MASK; 584 uint16_t sub_event = p_msg->event & MSG_SUB_EVT_MASK; 585 uint16_t acl_pkt_size = 0, acl_data_size = 0; 586 587 /* wake up BT device if its in sleep mode */ 588 lpm_wake_assert(); 589 590 if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID) 591 { 592 acl_data_size = mct_cb.hc_acl_data_size; 593 acl_pkt_size = mct_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE; 594 } 595 else 596 { 597 acl_data_size = mct_cb.hc_ble_acl_data_size; 598 acl_pkt_size = mct_cb.hc_ble_acl_data_size + HCI_ACL_PREAMBLE_SIZE; 599 } 600 601 /* Check if sending ACL data that needs fragmenting */ 602 if ((event == MSG_STACK_TO_HC_HCI_ACL) && (p_msg->len > acl_pkt_size)) 603 { 604 /* Get the handle from the packet */ 605 STREAM_TO_UINT16 (handle, p); 606 607 /* Set packet boundary flags to "continuation packet" */ 608 handle = (handle & 0xCFFF) | 0x1000; 609 610 /* Do all the first chunks */ 611 while (p_msg->len > acl_pkt_size) 612 { 613 p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 614 615 userial_write(event, (uint8_t *) p, acl_pkt_size); 616 617 /* generate snoop trace message */ 618 btsnoop_capture(p_msg, false); 619 620 /* Adjust offset and length for what we just sent */ 621 p_msg->offset += acl_data_size; 622 p_msg->len -= acl_data_size; 623 624 p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 625 626 UINT16_TO_STREAM (p, handle); 627 628 if (p_msg->len > acl_pkt_size) 629 { 630 UINT16_TO_STREAM (p, acl_data_size); 631 } 632 else 633 { 634 UINT16_TO_STREAM (p, p_msg->len - HCI_ACL_PREAMBLE_SIZE); 635 } 636 637 /* If we were only to send partial buffer, stop when done. */ 638 /* Send the buffer back to L2CAP to send the rest of it later */ 639 if (p_msg->layer_specific) 640 { 641 if (--p_msg->layer_specific == 0) 642 { 643 p_msg->event = MSG_HC_TO_STACK_L2C_SEG_XMIT; 644 645 if (bt_hc_cbacks) 646 { 647 bt_hc_cbacks->tx_result((TRANSAC) p_msg, \ 648 (char *) (p_msg + 1), \ 649 BT_HC_TX_FRAGMENT); 650 } 651 652 return; 653 } 654 } 655 } 656 } 657 658 p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 659 660 if (event == MSG_STACK_TO_HC_HCI_CMD) 661 { 662 uint8_t *p_tmp = p; 663 664 utils_lock(); 665 num_hci_cmd_pkts--; 666 utils_unlock(); 667 668 /* If this is an internal Cmd packet, the layer_specific field would 669 * have stored with the opcode of HCI command. 670 * Retrieve the opcode from the Cmd packet. 671 */ 672 p_tmp++; 673 STREAM_TO_UINT16(lay_spec, p_tmp); 674 } 675 676 userial_write(event, (uint8_t *) p, p_msg->len); 677 678 679 /* generate snoop trace message */ 680 btsnoop_capture(p_msg, false); 681 682 if (bt_hc_cbacks) 683 { 684 if ((event == MSG_STACK_TO_HC_HCI_CMD) && \ 685 (mct_cb.int_cmd_rsp_pending > 0) && \ 686 (p_msg->layer_specific == lay_spec)) 687 { 688 /* dealloc buffer of internal command */ 689 bt_hc_cbacks->dealloc(p_msg); 690 } 691 else 692 { 693 bt_hc_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), \ 694 BT_HC_TX_SUCCESS); 695 } 696 } 697 698 lpm_tx_done(TRUE); 699 700 return; 701 } 702 703 704 /******************************************************************************* 705 ** 706 ** Function hci_mct_receive_evt_msg 707 ** 708 ** Description Construct HCI EVENT packet 709 ** 710 ** Returns Number of read bytes 711 ** 712 *******************************************************************************/ 713 uint16_t hci_mct_receive_evt_msg(void) 714 { 715 uint16_t bytes_read = 0; 716 uint8_t byte; 717 uint16_t msg_len, len; 718 uint8_t msg_received; 719 tHCI_RCV_CB *p_cb=&mct_cb.rcv_evt; 720 uint8_t continue_fetch_looping = TRUE; 721 722 while (continue_fetch_looping) 723 { 724 /* Read one byte to see if there is anything waiting to be read */ 725 if (userial_read(MSG_HC_TO_STACK_HCI_EVT, &byte, 1) == 0) 726 { 727 break; 728 } 729 730 bytes_read++; 731 msg_received = FALSE; 732 733 switch (p_cb->rcv_state) 734 { 735 case MCT_RX_NEWMSG_ST: 736 /* Start of new message */ 737 /* Initialize rx parameters */ 738 memset(p_cb->preload_buffer, 0 , 6); 739 p_cb->preload_buffer[0] = byte; 740 p_cb->preload_count = 1; 741 p_cb->rcv_len = HCI_EVT_PREAMBLE_SIZE - 1; 742 // p_cb->p_rcv_msg = NULL; 743 p_cb->rcv_state = MCT_RX_LEN_ST; /* Next, wait for length to come */ 744 break; 745 746 case MCT_RX_LEN_ST: 747 /* Receiving preamble */ 748 p_cb->preload_buffer[p_cb->preload_count++] = byte; 749 p_cb->rcv_len--; 750 751 /* Check if we received entire preamble yet */ 752 if (p_cb->rcv_len == 0) 753 { 754 /* Received entire preamble. 755 * Length is in the last received byte */ 756 msg_len = byte; 757 p_cb->rcv_len = msg_len; 758 759 /* Allocate a buffer for message */ 760 if (bt_hc_cbacks) 761 { 762 len = msg_len + p_cb->preload_count + BT_HC_HDR_SIZE; 763 p_cb->p_rcv_msg = \ 764 (HC_BT_HDR *) bt_hc_cbacks->alloc(len); 765 } 766 767 if (p_cb->p_rcv_msg) 768 { 769 /* Initialize buffer with preloaded data */ 770 p_cb->p_rcv_msg->offset = 0; 771 p_cb->p_rcv_msg->layer_specific = 0; 772 p_cb->p_rcv_msg->event = MSG_HC_TO_STACK_HCI_EVT; 773 p_cb->p_rcv_msg->len = p_cb->preload_count; 774 memcpy((uint8_t *)(p_cb->p_rcv_msg + 1), \ 775 p_cb->preload_buffer, p_cb->preload_count); 776 } 777 else 778 { 779 /* Unable to acquire message buffer. */ 780 ALOGE( \ 781 "Unable to acquire buffer for incoming HCI message." \ 782 ); 783 784 if (msg_len == 0) 785 { 786 /* Wait for next message */ 787 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 788 continue_fetch_looping = FALSE; 789 } 790 else 791 { 792 /* Ignore rest of the packet */ 793 p_cb->rcv_state = MCT_RX_IGNORE_ST; 794 } 795 796 break; 797 } 798 799 /* Message length is valid */ 800 if (msg_len) 801 { 802 /* Read rest of message */ 803 p_cb->rcv_state = MCT_RX_DATA_ST; 804 } 805 else 806 { 807 /* Message has no additional parameters. 808 * (Entire message has been received) */ 809 msg_received = TRUE; 810 811 /* Next, wait for next message */ 812 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 813 continue_fetch_looping = FALSE; 814 } 815 } 816 break; 817 818 case MCT_RX_DATA_ST: 819 *((uint8_t *)(p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->len++) = byte; 820 p_cb->rcv_len--; 821 822 if (p_cb->rcv_len > 0) 823 { 824 /* Read in the rest of the message */ 825 len = userial_read(MSG_HC_TO_STACK_HCI_EVT, \ 826 ((uint8_t *)(p_cb->p_rcv_msg+1) + p_cb->p_rcv_msg->len), \ 827 p_cb->rcv_len); 828 p_cb->p_rcv_msg->len += len; 829 p_cb->rcv_len -= len; 830 bytes_read += len; 831 } 832 833 /* Check if we read in entire message yet */ 834 if (p_cb->rcv_len == 0) 835 { 836 /* Received entire packet. */ 837 msg_received = TRUE; 838 /* Next, wait for next message */ 839 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 840 continue_fetch_looping = FALSE; 841 } 842 break; 843 844 845 case MCT_RX_IGNORE_ST: 846 /* Ignore reset of packet */ 847 p_cb->rcv_len--; 848 849 /* Check if we read in entire message yet */ 850 if (p_cb->rcv_len == 0) 851 { 852 /* Next, wait for next message */ 853 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 854 continue_fetch_looping = FALSE; 855 } 856 break; 857 } 858 859 860 /* If we received entire message, then send it to the task */ 861 if (msg_received) 862 { 863 uint8_t intercepted = FALSE; 864 865 /* generate snoop trace message */ 866 btsnoop_capture(p_cb->p_rcv_msg, true); 867 868 intercepted = internal_event_intercept(); 869 870 if ((bt_hc_cbacks) && (intercepted == FALSE)) 871 { 872 bt_hc_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, \ 873 (char *) (p_cb->p_rcv_msg + 1), \ 874 p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE); 875 } 876 p_cb->p_rcv_msg = NULL; 877 } 878 } 879 880 return (bytes_read); 881 } 882 883 884 /******************************************************************************* 885 ** 886 ** Function hci_mct_receive_acl_msg 887 ** 888 ** Description Construct HCI ACL packet 889 ** 890 ** Returns Number of read bytes 891 ** 892 *******************************************************************************/ 893 uint16_t hci_mct_receive_acl_msg(void) 894 { 895 uint16_t bytes_read = 0; 896 uint8_t byte; 897 uint16_t msg_len, len; 898 uint8_t msg_received; 899 tHCI_RCV_CB *p_cb=&mct_cb.rcv_acl; 900 uint8_t continue_fetch_looping = TRUE; 901 902 while (continue_fetch_looping) 903 { 904 /* Read one byte to see if there is anything waiting to be read */ 905 if (userial_read(MSG_HC_TO_STACK_HCI_ACL, &byte, 1) == 0) 906 { 907 break; 908 } 909 910 bytes_read++; 911 msg_received = FALSE; 912 913 switch (p_cb->rcv_state) 914 { 915 case MCT_RX_NEWMSG_ST: 916 /* Start of new message */ 917 /* Initialize rx parameters */ 918 memset(p_cb->preload_buffer, 0 , 6); 919 p_cb->preload_buffer[0] = byte; 920 p_cb->preload_count = 1; 921 p_cb->rcv_len = HCI_ACL_PREAMBLE_SIZE - 1; 922 // p_cb->p_rcv_msg = NULL; 923 p_cb->rcv_state = MCT_RX_LEN_ST; /* Next, wait for length to come */ 924 break; 925 926 case MCT_RX_LEN_ST: 927 /* Receiving preamble */ 928 p_cb->preload_buffer[p_cb->preload_count++] = byte; 929 p_cb->rcv_len--; 930 931 /* Check if we received entire preamble yet */ 932 if (p_cb->rcv_len == 0) 933 { 934 /* ACL data lengths are 16-bits */ 935 msg_len = p_cb->preload_buffer[3]; 936 msg_len = (msg_len << 8) + p_cb->preload_buffer[2]; 937 938 if (msg_len && (p_cb->preload_count == 4)) 939 { 940 /* Check if this is a start packet */ 941 byte = ((p_cb->preload_buffer[1] >> 4) & 0x03); 942 943 if (byte == ACL_RX_PKT_START) 944 { 945 /* 946 * A start packet & with non-zero data payload length. 947 * We want to read 2 more bytes to get L2CAP payload 948 * length. 949 */ 950 p_cb->rcv_len = 2; 951 952 break; 953 } 954 } 955 956 /* 957 * Check for segmented packets. If this is a continuation 958 * packet, then we will continue appending data to the 959 * original rcv buffer. 960 */ 961 p_cb->p_rcv_msg = acl_rx_frame_buffer_alloc(); 962 963 if (p_cb->p_rcv_msg == NULL) 964 { 965 /* Unable to acquire message buffer. */ 966 ALOGE( \ 967 "Unable to acquire buffer for incoming HCI message." \ 968 ); 969 970 if (msg_len == 0) 971 { 972 /* Wait for next message */ 973 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 974 continue_fetch_looping = FALSE; 975 } 976 else 977 { 978 /* Ignore rest of the packet */ 979 p_cb->rcv_state = MCT_RX_IGNORE_ST; 980 } 981 982 break; 983 } 984 985 /* Message length is valid */ 986 if (msg_len) 987 { 988 /* Read rest of message */ 989 p_cb->rcv_state = MCT_RX_DATA_ST; 990 } 991 else 992 { 993 /* Message has no additional parameters. 994 * (Entire message has been received) */ 995 acl_rx_frame_end_chk(); /* to print snoop trace */ 996 997 msg_received = TRUE; 998 999 /* Next, wait for next message */ 1000 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 1001 continue_fetch_looping = FALSE; 1002 } 1003 } 1004 break; 1005 1006 case MCT_RX_DATA_ST: 1007 *((uint8_t *)(p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->len++) = byte; 1008 p_cb->rcv_len--; 1009 1010 if (p_cb->rcv_len > 0) 1011 { 1012 /* Read in the rest of the message */ 1013 len = userial_read(MSG_HC_TO_STACK_HCI_ACL, \ 1014 ((uint8_t *)(p_cb->p_rcv_msg+1) + p_cb->p_rcv_msg->len), \ 1015 p_cb->rcv_len); 1016 p_cb->p_rcv_msg->len += len; 1017 p_cb->rcv_len -= len; 1018 bytes_read += len; 1019 } 1020 1021 /* Check if we read in entire message yet */ 1022 if (p_cb->rcv_len == 0) 1023 { 1024 /* Received entire packet. */ 1025 /* Check for segmented l2cap packets */ 1026 if (acl_rx_frame_end_chk()) 1027 { 1028 msg_received = TRUE; 1029 } 1030 1031 /* Next, wait for next message */ 1032 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 1033 continue_fetch_looping = FALSE; 1034 } 1035 break; 1036 1037 1038 case MCT_RX_IGNORE_ST: 1039 /* Ignore reset of packet */ 1040 p_cb->rcv_len--; 1041 1042 /* Check if we read in entire message yet */ 1043 if (p_cb->rcv_len == 0) 1044 { 1045 /* Next, wait for next message */ 1046 p_cb->rcv_state = MCT_RX_NEWMSG_ST; 1047 continue_fetch_looping = FALSE; 1048 } 1049 break; 1050 } 1051 1052 1053 /* If we received entire message, then send it to the task */ 1054 if (msg_received) 1055 { 1056 if (bt_hc_cbacks) 1057 { 1058 bt_hc_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, \ 1059 (char *) (p_cb->p_rcv_msg + 1), \ 1060 p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE); 1061 } 1062 p_cb->p_rcv_msg = NULL; 1063 } 1064 } 1065 1066 return (bytes_read); 1067 } 1068 1069 /******************************************************************************* 1070 ** 1071 ** Function hci_mct_send_int_cmd 1072 ** 1073 ** Description Place the internal commands (issued internally by hci or 1074 ** vendor lib) in the tx_q. 1075 ** 1076 ** Returns TRUE/FALSE 1077 ** 1078 *******************************************************************************/ 1079 uint8_t hci_mct_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \ 1080 tINT_CMD_CBACK p_cback) 1081 { 1082 if (mct_cb.int_cmd_rsp_pending > INT_CMD_PKT_MAX_COUNT) 1083 { 1084 ALOGE( \ 1085 "Allow only %d outstanding internal commands at a time [Reject 0x%04X]"\ 1086 , INT_CMD_PKT_MAX_COUNT, opcode); 1087 return FALSE; 1088 } 1089 1090 mct_cb.int_cmd_rsp_pending++; 1091 mct_cb.int_cmd[mct_cb.int_cmd_wrt_idx].opcode = opcode; 1092 mct_cb.int_cmd[mct_cb.int_cmd_wrt_idx].cback = p_cback; 1093 mct_cb.int_cmd_wrt_idx = ((mct_cb.int_cmd_wrt_idx+1) & INT_CMD_PKT_IDX_MASK); 1094 1095 /* stamp signature to indicate an internal command */ 1096 p_buf->layer_specific = opcode; 1097 1098 bthc_tx(p_buf); 1099 return TRUE; 1100 } 1101 1102 1103 /******************************************************************************* 1104 ** 1105 ** Function hci_mct_get_acl_data_length 1106 ** 1107 ** Description Issue HCI_READ_BUFFER_SIZE command to retrieve Controller's 1108 ** ACL data length setting 1109 ** 1110 ** Returns None 1111 ** 1112 *******************************************************************************/ 1113 void hci_mct_get_acl_data_length(void) 1114 { 1115 HC_BT_HDR *p_buf = NULL; 1116 uint8_t *p, ret; 1117 1118 if (bt_hc_cbacks) 1119 { 1120 p_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc(BT_HC_HDR_SIZE + \ 1121 HCI_CMD_PREAMBLE_SIZE); 1122 } 1123 1124 if (p_buf) 1125 { 1126 p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 1127 p_buf->offset = 0; 1128 p_buf->layer_specific = 0; 1129 p_buf->len = HCI_CMD_PREAMBLE_SIZE; 1130 1131 p = (uint8_t *) (p_buf + 1); 1132 UINT16_TO_STREAM(p, HCI_READ_BUFFER_SIZE); 1133 *p = 0; 1134 1135 if ((ret = hci_mct_send_int_cmd(HCI_READ_BUFFER_SIZE, p_buf, \ 1136 get_acl_data_length_cback)) == FALSE) 1137 { 1138 bt_hc_cbacks->dealloc(p_buf); 1139 } 1140 else 1141 return; 1142 } 1143 1144 if (bt_hc_cbacks) 1145 { 1146 ALOGE("hci lib postload aborted"); 1147 bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_FAIL); 1148 } 1149 } 1150 1151 1152 /****************************************************************************** 1153 ** HCI MCT Services interface table 1154 ******************************************************************************/ 1155 1156 const tHCI_IF hci_mct_func_table = 1157 { 1158 hci_mct_init, 1159 hci_mct_cleanup, 1160 hci_mct_send_msg, 1161 hci_mct_send_int_cmd, 1162 hci_mct_get_acl_data_length, 1163 hci_mct_receive_evt_msg, 1164 hci_mct_receive_acl_msg 1165 }; 1166 1167 1168