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