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