Home | History | Annotate | Download | only in src
      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