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