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