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