• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *******************************************************************************/
get_acl_data_length_cback(void * p_mem)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 *******************************************************************************/
internal_event_intercept(void)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 *******************************************************************************/
acl_rx_frame_buffer_alloc(void)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 *******************************************************************************/
acl_rx_frame_end_chk(void)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 *******************************************************************************/
hci_mct_init(void)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 *******************************************************************************/
hci_mct_cleanup(void)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 *******************************************************************************/
hci_mct_send_msg(HC_BT_HDR * p_msg)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 *******************************************************************************/
hci_mct_receive_evt_msg(void)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 *******************************************************************************/
hci_mct_receive_acl_msg(void)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 *******************************************************************************/
hci_mct_send_int_cmd(uint16_t opcode,HC_BT_HDR * p_buf,tINT_CMD_CBACK p_cback)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 *******************************************************************************/
hci_mct_get_acl_data_length(void)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