15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Filename: hci_h4.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: Contains HCI transport send/receive functions 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "bt_h4" 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <utils/Log.h> 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <stdlib.h> 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h> 325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_hci_bdroid.h" 335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hci.h" 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "userial.h" 355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "utils.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Constants & Macros 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef HCI_DBG 425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_DBG FALSE 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (HCI_DBG == TRUE) 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCIDBG(param, ...) {LOGD(param, ## __VA_ARGS__);} 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCIDBG(param, ...) {} 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Preamble length for HCI Commands: 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2-bytes for opcode and 1 byte for length 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_CMD_PREAMBLE_SIZE 3 555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Preamble length for HCI Events: 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1-byte for opcode and 1 byte for length 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_EVT_PREAMBLE_SIZE 2 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Preamble length for SCO Data: 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2-byte for Handle and 1 byte for length 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_SCO_PREAMBLE_SIZE 3 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Preamble length for ACL Data: 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2-byte for Handle and 2 byte for length 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_ACL_PREAMBLE_SIZE 4 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Table of HCI preamble sizes for the different HCI message types */ 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const uint8_t hci_preamble_table[] = 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCI_CMD_PREAMBLE_SIZE, 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCI_ACL_PREAMBLE_SIZE, 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCI_SCO_PREAMBLE_SIZE, 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCI_EVT_PREAMBLE_SIZE 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* HCI H4 message type definitions */ 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define H4_TYPE_COMMAND 1 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define H4_TYPE_ACL_DATA 2 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define H4_TYPE_SCO_DATA 3 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define H4_TYPE_EVENT 4 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const uint16_t msg_evt_table[] = 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MSG_HC_TO_STACK_HCI_ERR, /* H4_TYPE_COMMAND */ 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MSG_HC_TO_STACK_HCI_ACL, /* H4_TYPE_ACL_DATA */ 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MSG_HC_TO_STACK_HCI_SCO, /* H4_TYPE_SCO_DATA */ 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project MSG_HC_TO_STACK_HCI_EVT /* H4_TYPE_EVENT */ 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define ACL_RX_PKT_START 2 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define ACL_RX_PKT_CONTINUE 1 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define L2CAP_HEADER_SIZE 4 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Maximum numbers of allowed internal 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** outstanding command packets at any time 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*/ 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define INT_CMD_PKT_MAX_COUNT 8 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define INT_CMD_PKT_IDX_MASK 0x07 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_COMMAND_COMPLETE_EVT 0x0E 1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_COMMAND_STATUS_EVT 0x0F 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_READ_BUFFER_SIZE 0x1005 1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define HCI_LE_READ_BUFFER_SIZE 0x2002 1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Local type definitions 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* H4 Rx States */ 1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef enum { 1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project H4_RX_MSGTYPE_ST, 1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project H4_RX_LEN_ST, 1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project H4_RX_DATA_ST, 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project H4_RX_IGNORE_ST 1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tHCI_H4_RCV_STATE; 1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Callback function for the returned event of internal issued command */ 1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef void (*tINT_CMD_CBACK)(void *p_mem); 1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t opcode; /* OPCODE of outstanding internal commands */ 1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tINT_CMD_CBACK cback; /* Callback function when return of internal 1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * command is received */ 1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tINT_CMD_Q; 1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Control block for HCISU_H4 */ 1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_rcv_msg; /* Buffer to hold current rx HCI message */ 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t rcv_len; /* Size of current incoming message */ 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t rcv_msg_type; /* Current incoming message type */ 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tHCI_H4_RCV_STATE rcv_state; /* Receive state of current rx message */ 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t hc_acl_data_size; /* Controller's max ACL data length */ 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t hc_ble_acl_data_size; /* Controller's max BLE ACL data length */ 1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BUFFER_Q acl_rx_q; /* Queue of base buffers for fragmented ACL pkts */ 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t preload_count; /* Count numbers of preload bytes */ 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t preload_buffer[6]; /* HCI_ACL_PREAMBLE_SIZE + 2 */ 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int int_cmd_rsp_pending; /* Num of internal cmds pending for ack */ 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t int_cmd_rd_idx; /* Read index of int_cmd_opcode queue */ 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t int_cmd_wrt_idx; /* Write index of int_cmd_opcode queue */ 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tINT_CMD_Q int_cmd[INT_CMD_PKT_MAX_COUNT]; /* FIFO queue */ 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} tHCI_H4_CB; 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Externs 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern BUFFER_Q tx_q; 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsnoop_init(void); 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsnoop_close(void); 1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsnoop_cleanup (void); 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid btsnoop_capture(HC_BT_HDR *p_buf, uint8_t is_rcvd); 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint8_t hci_h4_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \ 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tINT_CMD_CBACK p_cback); 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_wake_assert(void); 1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_tx_done(uint8_t is_tx_done); 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Variables 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Num of allowed outstanding HCI CMD packets */ 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvolatile int num_hci_cmd_pkts = 1; 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static variables 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic tHCI_H4_CB h4_cb; 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static functions 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function get_acl_data_length_cback 1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Callback function for HCI_READ_BUFFER_SIZE and 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** HCI_LE_READ_BUFFER_SIZE commands if they were sent because 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** of internal request. 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid get_acl_data_length_cback(void *p_mem) 1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p, status; 1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t opcode, len=0; 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_buf = (HC_BT_HDR *) p_mem; 1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *)(p_buf + 1) + 3; 1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16(opcode, p) 2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project status = *p++; 2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (status == 0) /* Success */ 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16(len, p) 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (opcode == HCI_READ_BUFFER_SIZE) 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (status == 0) 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.hc_acl_data_size = len; 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* reuse the rx buffer for sending HCI_LE_READ_BUFFER_SIZE command */ 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = 0; 2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = 0; 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = 3; 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *) (p_buf + 1); 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM(p, HCI_LE_READ_BUFFER_SIZE); 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p = 0; 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((status = hci_h4_send_int_cmd(HCI_LE_READ_BUFFER_SIZE, p_buf, \ 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project get_acl_data_length_cback)) == FALSE) 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1)); 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_SUCCESS); 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (opcode == HCI_LE_READ_BUFFER_SIZE) 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (status == 0) 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.hc_ble_acl_data_size = (len) ? len : h4_cb.hc_acl_data_size; 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1)); 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("vendor lib postload completed"); 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_SUCCESS); 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function internal_event_intercept 2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called to parse received HCI event and 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - update the Num_HCI_Command_Packets 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - intercept the event if it is the result of an early 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** issued internal command. 2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE : if the event had been intercepted for internal process 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** FALSE : send this event to core stack 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint8_t internal_event_intercept(void) 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p; 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t event_code; 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t opcode, len; 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tHCI_H4_CB *p_cb = &h4_cb; 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *)(p_cb->p_rcv_msg + 1); 2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project event_code = *p++; 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project len = *p++; 2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (event_code == HCI_COMMAND_COMPLETE_EVT) 2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_hci_cmd_pkts = *p++; 2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->int_cmd_rsp_pending > 0) 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16(opcode, p) 2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (opcode == p_cb->int_cmd[p_cb->int_cmd_rd_idx].opcode) 2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCIDBG( \ 2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "Intercept CommandCompleteEvent for internal command (0x%04X)",\ 2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project opcode); 2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->int_cmd[p_cb->int_cmd_rd_idx].cback != NULL) 2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->int_cmd[p_cb->int_cmd_rd_idx].cback(p_cb->p_rcv_msg); 2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Missing cback function! 2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // Release the p_rcv_msg buffer. 2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_cb->p_rcv_msg, \ 2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (char *) (p_cb->p_rcv_msg + 1)); 2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->int_cmd_rd_idx = ((p_cb->int_cmd_rd_idx+1) & \ 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project INT_CMD_PKT_IDX_MASK); 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->int_cmd_rsp_pending--; 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (event_code == HCI_COMMAND_STATUS_EVT) 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_hci_cmd_pkts = *(++p); 3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function acl_rx_frame_buffer_alloc 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called from the HCI transport when the 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** first 4 or 6 bytes of an HCI ACL packet have been received: 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - Allocate a new buffer if it is a start pakcet of L2CAP 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** message. 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** - Return the buffer address of the starting L2CAP message 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** frame if the packet is the next segment of a fragmented 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** L2CAP message. 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns the address of the receive buffer H4 RX should use 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** (CR419: Modified to return NULL in case of error.) 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** NOTE This assumes that the L2CAP MTU size is less than the size 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** of an HCI ACL buffer, so the maximum L2CAP message will fit 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** into one buffer. 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic HC_BT_HDR *acl_rx_frame_buffer_alloc (void) 3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p; 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t handle; 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t hci_len; 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t total_len; 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t pkt_type; 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_return_buf = NULL; 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tHCI_H4_CB *p_cb = &h4_cb; 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = p_cb->preload_buffer; 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (handle, p); 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (hci_len, p); 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (total_len, p); 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pkt_type = (uint8_t)(((handle) >> 12) & 0x0003); 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project handle = (uint16_t)((handle) & 0x0FFF); 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->acl_rx_q.count) 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t save_handle; 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_hdr = p_cb->acl_rx_q.p_first; 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_hdr != NULL) 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *)(p_hdr + 1); 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (save_handle, p); 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project save_handle = (uint16_t)((save_handle) & 0x0FFF); 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (save_handle == handle) 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf = p_hdr; 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_hdr = utils_getnext(p_hdr); 3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (pkt_type == ACL_RX_PKT_START) /*** START PACKET ***/ 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Might have read 2 bytes for the L2CAP payload length */ 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len = (hci_len) ? (hci_len - 2) : 0; 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Start of packet. If we were in the middle of receiving */ 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* a packet on the same ACL handle, the original packet is incomplete. 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Drop it. */ 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_return_buf) 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW("H4 - dropping incomplete ACL frame"); 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_remove_from_queue(&(p_cb->acl_rx_q), p_return_buf); 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_return_buf, \ 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (char *) (p_return_buf + 1)); 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf = NULL; 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Allocate a buffer for message */ 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int len = total_len + HCI_ACL_PREAMBLE_SIZE + L2CAP_HEADER_SIZE + \ 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HC_HDR_SIZE; 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc(len); 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_return_buf) 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Initialize buffer with preloaded data */ 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf->offset = 0; 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf->layer_specific = 0; 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf->event = MSG_HC_TO_STACK_HCI_ACL; 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_return_buf->len = p_cb->preload_count; 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy((uint8_t *)(p_return_buf + 1), p_cb->preload_buffer, \ 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->preload_count); 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (hci_len && ((total_len + L2CAP_HEADER_SIZE) > hci_len)) 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Will expect to see fragmented ACL packets */ 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Keep the base buffer address in the watching queue */ 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_enqueue(&(p_cb->acl_rx_q), p_return_buf); 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else /*** CONTINUATION PACKET ***/ 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len = hci_len; 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_return_buf) 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Packet continuation and found the original rx buffer */ 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p_f = p = (uint8_t *)(p_return_buf + 1) + 2; 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (total_len, p); 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Update HCI header of first segment (base buffer) with new len */ 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project total_len += hci_len; 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p_f, total_len); 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (p_return_buf); 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function acl_rx_frame_end_chk 4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description This function is called from the HCI transport when the last 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** byte of an HCI ACL packet has been received. It checks if 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** the L2CAP message is complete, i.e. no more continuation 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** packets are expected. 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE if message complete, FALSE if continuation expected 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic uint8_t acl_rx_frame_end_chk (void) 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p; 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t handle, hci_len, l2cap_len; 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_buf; 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tHCI_H4_CB *p_cb = &h4_cb; 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t frame_end=TRUE; 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = p_cb->p_rcv_msg; 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *)(p_buf + 1); 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (handle, p); 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (hci_len, p); 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (l2cap_len, p); 4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (hci_len > 0) 4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (l2cap_len > (p_buf->len-(HCI_ACL_PREAMBLE_SIZE+L2CAP_HEADER_SIZE)) ) 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If the L2CAP length has not been reached, tell H4 not to send 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * this buffer to stack */ 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project frame_end = FALSE; 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * The current buffer coulb be in the watching list. 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Remove it from the list if it is in. 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->acl_rx_q.count) 4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_remove_from_queue(&(p_cb->acl_rx_q), p_buf); 4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /**** 4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ** Print snoop trace 4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ****/ 4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf->offset) 4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* CONTINUATION PACKET */ 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* save original p_buf->len content */ 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t tmp_u16 = p_buf->len; 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* borrow HCI_ACL_PREAMBLE_SIZE bytes from the payload section */ 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *)(p_buf + 1) + p_buf->offset - HCI_ACL_PREAMBLE_SIZE; 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* save contents */ 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy(p_cb->preload_buffer, p, HCI_ACL_PREAMBLE_SIZE); 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set packet boundary flags to "continuation packet" */ 4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project handle = (handle & 0xCFFF) | 0x1000; 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* write handl & length info */ 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, handle); 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, (p_buf->len - p_buf->offset)); 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* roll pointer back */ 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = p - HCI_ACL_PREAMBLE_SIZE; 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* adjust `p_buf->offset` & `p_buf->len` 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * before calling btsnoop_capture() */ 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = p_buf->offset - HCI_ACL_PREAMBLE_SIZE; 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = p_buf->len - p_buf->offset; 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_capture(p_buf, TRUE); 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* restore contents */ 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy(p, p_cb->preload_buffer, HCI_ACL_PREAMBLE_SIZE); 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* restore p_buf->len */ 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = tmp_u16; 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* START PACKET */ 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_capture(p_buf, TRUE); 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (frame_end == TRUE) 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = 0; 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = p_buf->len; /* save current buffer-end position */ 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return frame_end; 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** HCI H4 INTERFACE FUNCTIONS 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_init 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Initialize H4 module 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid hci_h4_init(void) 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCIDBG("hci_h4_init"); 5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(&h4_cb, 0, sizeof(tHCI_H4_CB)); 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_queue_init(&(h4_cb.acl_rx_q)); 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Per HCI spec., always starts with 1 */ 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_hci_cmd_pkts = 1; 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Give an initial values of Host Controller's ACL data packet length 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Will update with an internal HCI(_LE)_Read_Buffer_Size request 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.hc_acl_data_size = 1021; 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.hc_ble_acl_data_size = 27; 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_init(); 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_cleanup 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Clean H4 module 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid hci_h4_cleanup(void) 5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCIDBG("hci_h4_cleanup"); 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_close(); 5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_cleanup(); 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_send_msg 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Determine message type, set HCI H4 packet indicator, and 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** send message through USERIAL driver 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid hci_h4_send_msg(HC_BT_HDR *p_msg) 5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t type = 0; 5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t handle; 5975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t bytes_to_send, lay_spec; 5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t event = p_msg->event & MSG_EVT_MASK; 6005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t sub_event = p_msg->event & MSG_SUB_EVT_MASK; 6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t acl_pkt_size = 0, acl_data_size = 0; 6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t bytes_sent; 6035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* wake up BT device if its in sleep mode */ 6055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lpm_wake_assert(); 6065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (event == MSG_STACK_TO_HC_HCI_ACL) 6085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project type = H4_TYPE_ACL_DATA; 6095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (event == MSG_STACK_TO_HC_HCI_SCO) 6105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project type = H4_TYPE_SCO_DATA; 6115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if (event == MSG_STACK_TO_HC_HCI_CMD) 6125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project type = H4_TYPE_COMMAND; 6135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (sub_event == LOCAL_BR_EDR_CONTROLLER_ID) 6155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project acl_data_size = h4_cb.hc_acl_data_size; 6175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project acl_pkt_size = h4_cb.hc_acl_data_size + HCI_ACL_PREAMBLE_SIZE; 6185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project acl_data_size = h4_cb.hc_ble_acl_data_size; 6225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project acl_pkt_size = h4_cb.hc_ble_acl_data_size + HCI_ACL_PREAMBLE_SIZE; 6235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if sending ACL data that needs fragmenting */ 6265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((event == MSG_STACK_TO_HC_HCI_ACL) && (p_msg->len > acl_pkt_size)) 6275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Get the handle from the packet */ 6295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16 (handle, p); 6305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Set packet boundary flags to "continuation packet" */ 6325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project handle = (handle & 0xCFFF) | 0x1000; 6335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Do all the first chunks */ 6355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (p_msg->len > acl_pkt_size) 6365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* remember layer_specific because uart borrow 6385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project one byte from layer_specific for packet type */ 6395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lay_spec = p_msg->layer_specific; 6405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1; 6425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p = type; 6435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_to_send = acl_pkt_size + 1; /* packet_size + message type */ 6445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_sent = userial_write(event,(uint8_t *) p,bytes_to_send); 6465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* generate snoop trace message */ 6485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_capture(p_msg, FALSE); 6495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_msg->layer_specific = lay_spec; 6515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Adjust offset and length for what we just sent */ 6525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_msg->offset += acl_data_size; 6535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_msg->len -= acl_data_size; 6545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((uint8_t *)(p_msg + 1)) + p_msg->offset; 6565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, handle); 6585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_msg->len > acl_pkt_size) 6605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, acl_data_size); 6625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 6645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM (p, p_msg->len - HCI_ACL_PREAMBLE_SIZE); 6665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we were only to send partial buffer, stop when done. */ 6695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Send the buffer back to L2CAP to send the rest of it later */ 6705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_msg->layer_specific) 6715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (--p_msg->layer_specific == 0) 6735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_msg->event = MSG_HC_TO_STACK_L2C_SEG_XMIT; 6755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 6775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 6785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->tx_result((TRANSAC) p_msg, \ 6795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (char *) (p_msg + 1), \ 6805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HC_TX_FRAGMENT); 6815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 6845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 6885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* remember layer_specific because uart borrow 6915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project one byte from layer_specific for packet type */ 6925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lay_spec = p_msg->layer_specific; 6935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Put the HCI Transport packet type 1 byte before the message */ 6955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = ((uint8_t *)(p_msg + 1)) + p_msg->offset - 1; 6965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p = type; 6975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_to_send = p_msg->len + 1; /* message_size + message type */ 6985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 6995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_sent = userial_write(event,(uint8_t *) p, bytes_to_send); 7005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_msg->layer_specific = lay_spec; 7025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (event == MSG_STACK_TO_HC_HCI_CMD) 7045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project num_hci_cmd_pkts--; 7065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If this is an internal Cmd packet, the layer_specific field would 7085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * have stored with the opcode of HCI command. 7095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Retrieve the opcode from the Cmd packet. 7105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 7115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p++; 7125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project STREAM_TO_UINT16(lay_spec, p); 7135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* generate snoop trace message */ 7165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_capture(p_msg, FALSE); 7175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 7195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((event == MSG_STACK_TO_HC_HCI_CMD) && \ 7215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (h4_cb.int_cmd_rsp_pending > 0) && \ 7225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (p_msg->layer_specific == lay_spec)) 7235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* dealloc buffer of internal command */ 7255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_msg, (char *) (p_msg + 1)); 7265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 7285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->tx_result((TRANSAC) p_msg, (char *) (p_msg + 1), \ 7305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BT_HC_TX_SUCCESS); 7315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lpm_tx_done(TRUE); 7355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 7375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 7385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 7415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 7425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_receive_msg 7435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 7445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Construct HCI EVENT/ACL packets and send them to stack once 7455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** complete packet has been received. 7465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 7475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns Number of read bytes 7485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 7495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 7505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint16_t hci_h4_receive_msg(void) 7515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 7525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t bytes_read = 0; 7535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t byte; 7545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint16_t msg_len, len; 7555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t msg_received; 7565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tHCI_H4_CB *p_cb=&h4_cb; 7575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while (TRUE) 7595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Read one byte to see if there is anything waiting to be read */ 7615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (userial_read(0 /*dummy*/, &byte, 1) == 0) 7625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 7645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_read++; 7675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_received = FALSE; 7685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch (p_cb->rcv_state) 7705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case H4_RX_MSGTYPE_ST: 7725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Start of new message */ 7735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((byte < H4_TYPE_ACL_DATA) || (byte > H4_TYPE_EVENT)) 7745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Unknown HCI message type */ 7765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Drop this byte */ 7775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("[h4] Unknown HCI message type drop this byte 0x%x", byte); 7785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 7795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 7805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Initialize rx parameters */ 7825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_msg_type = byte; 7835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len = hci_preamble_table[byte-1]; 7845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(p_cb->preload_buffer, 0 , 6); 7855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->preload_count = 0; 7865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project // p_cb->p_rcv_msg = NULL; 7875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_LEN_ST; /* Next, wait for length to come */ 7885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 7895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case H4_RX_LEN_ST: 7915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Receiving preamble */ 7925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->preload_buffer[p_cb->preload_count++] = byte; 7935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len--; 7945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 7955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if we received entire preamble yet */ 7965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_len == 0) 7975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 7985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_msg_type == H4_TYPE_ACL_DATA) 7995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* ACL data lengths are 16-bits */ 8015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_len = p_cb->preload_buffer[3]; 8025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_len = (msg_len << 8) + p_cb->preload_buffer[2]; 8035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (msg_len && (p_cb->preload_count == 4)) 8055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if this is a start packet */ 8075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project byte = ((p_cb->preload_buffer[1] >> 4) & 0x03); 8085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (byte == ACL_RX_PKT_START) 8105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* 8125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * A start packet & with non-zero data payload length. 8135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * We want to read 2 more bytes to get L2CAP payload 8145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * length. 8155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 8165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len = 2; 8175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 8195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* 8235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Check for segmented packets. If this is a continuation 8245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * packet, then we will continue appending data to the 8255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * original rcv buffer. 8265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */ 8275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg = acl_rx_frame_buffer_alloc(); 8285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Received entire preamble. 8325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Length is in the last received byte */ 8335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_len = byte; 8345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len = msg_len; 8355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Allocate a buffer for message */ 8375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 8385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project len = msg_len + p_cb->preload_count + BT_HC_HDR_SIZE; 8405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg = \ 8415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (HC_BT_HDR *) bt_hc_cbacks->alloc(len); 8425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->p_rcv_msg) 8455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Initialize buffer with preloaded data */ 8475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->offset = 0; 8485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->layer_specific = 0; 8495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->event = \ 8505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_evt_table[p_cb->rcv_msg_type-1]; 8515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->len = p_cb->preload_count; 8525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy((uint8_t *)(p_cb->p_rcv_msg + 1), \ 8535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->preload_buffer, p_cb->preload_count); 8545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->p_rcv_msg == NULL) 8585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Unable to acquire message buffer. */ 8605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE( \ 8615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "H4: Unable to acquire buffer for incoming HCI message." \ 8625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ); 8635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (msg_len == 0) 8655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Wait for next message */ 8675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_MSGTYPE_ST; 8685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Ignore rest of the packet */ 8725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_IGNORE_ST; 8735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 8765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Message length is valid */ 8795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (msg_len) 8805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Read rest of message */ 8825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_DATA_ST; 8835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 8855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 8865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Message has no additional parameters. 8875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * (Entire message has been received) */ 8885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_msg_type == H4_TYPE_ACL_DATA) 8895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project acl_rx_frame_end_chk(); /* to print snoop trace */ 8905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_received = TRUE; 8925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Next, wait for next message */ 8945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_MSGTYPE_ST; 8955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 8975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 8985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 8995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case H4_RX_DATA_ST: 9005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *((uint8_t *)(p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->len++) = byte; 9015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len--; 9025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_len > 0) 9045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Read in the rest of the message */ 9065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project len = userial_read(0 /*dummy*/, \ 9075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ((uint8_t *)(p_cb->p_rcv_msg+1) + p_cb->p_rcv_msg->len), \ 9085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len); 9095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->len += len; 9105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len -= len; 9115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bytes_read += len; 9125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if we read in entire message yet */ 9155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_len == 0) 9165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Received entire packet. */ 9185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check for segmented l2cap packets */ 9195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((p_cb->rcv_msg_type == H4_TYPE_ACL_DATA) && 9205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project !acl_rx_frame_end_chk()) 9215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Not the end of packet yet. */ 9235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Next, wait for next message */ 9245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_MSGTYPE_ST; 9255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 9275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project msg_received = TRUE; 9295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Next, wait for next message */ 9305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_MSGTYPE_ST; 9315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 9345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case H4_RX_IGNORE_ST: 9375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Ignore reset of packet */ 9385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_len--; 9395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Check if we read in entire message yet */ 9415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->rcv_len == 0) 9425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Next, wait for next message */ 9445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->rcv_state = H4_RX_MSGTYPE_ST; 9455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 9475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* If we received entire message, then send it to the task */ 9515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (msg_received) 9525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t intercepted = FALSE; 9545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* generate snoop trace message */ 9565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* ACL packet tracing had done in acl_rx_frame_end_chk() */ 9575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->p_rcv_msg->event != MSG_HC_TO_STACK_HCI_ACL) 9585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsnoop_capture(p_cb->p_rcv_msg, TRUE); 9595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb->p_rcv_msg->event == MSG_HC_TO_STACK_HCI_EVT) 9615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project intercepted = internal_event_intercept(); 9625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((bt_hc_cbacks) && (intercepted == FALSE)) 9645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->data_ind((TRANSAC) p_cb->p_rcv_msg, \ 9665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project (char *) (p_cb->p_rcv_msg + 1), \ 9675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg->len + BT_HC_HDR_SIZE); 9685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_cb->p_rcv_msg = NULL; 9705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return (bytes_read); 9745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 9755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 9785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_send_int_cmd 9805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Place the internal commands (issued internally by vendor lib) 9825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** in the tx_q. 9835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns TRUE/FALSE 9855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 9865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 9875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectuint8_t hci_h4_send_int_cmd(uint16_t opcode, HC_BT_HDR *p_buf, \ 9885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project tINT_CMD_CBACK p_cback) 9895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 9905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (h4_cb.int_cmd_rsp_pending > INT_CMD_PKT_MAX_COUNT) 9915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 9925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE( \ 9935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project "Allow only %d outstanding internal commands at a time [Reject 0x%04X]"\ 9945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project , INT_CMD_PKT_MAX_COUNT, opcode); 9955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 9965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 9975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 9985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.int_cmd_rsp_pending++; 9995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.int_cmd[h4_cb.int_cmd_wrt_idx].opcode = opcode; 10005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.int_cmd[h4_cb.int_cmd_wrt_idx].cback = p_cback; 10015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project h4_cb.int_cmd_wrt_idx = ((h4_cb.int_cmd_wrt_idx+1) & INT_CMD_PKT_IDX_MASK); 10025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* stamp signature to indicate an internal command */ 10045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = opcode; 10055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_enqueue(&tx_q, (void *) p_buf); 10075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bthc_signal_event(HC_EVENT_TX); 10085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 10105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 10145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function hci_h4_get_acl_data_length 10165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Issue HCI_READ_BUFFER_SIZE command to retrieve Controller's 10185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** ACL data length setting 10195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns None 10215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 10225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 10235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid hci_h4_get_acl_data_length(void) 10245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HC_BT_HDR *p_buf = NULL; 10265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint8_t *p, ret; 10275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 10295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf = (HC_BT_HDR *) bt_hc_cbacks->alloc(BT_HC_HDR_SIZE + \ 10315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project HCI_CMD_PREAMBLE_SIZE); 10325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_buf) 10355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->event = MSG_STACK_TO_HC_HCI_CMD; 10375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->offset = 0; 10385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->layer_specific = 0; 10395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_buf->len = HCI_CMD_PREAMBLE_SIZE; 10405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p = (uint8_t *) (p_buf + 1); 10425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project UINT16_TO_STREAM(p, HCI_READ_BUFFER_SIZE); 10435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *p = 0; 10445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if ((ret = hci_h4_send_int_cmd(HCI_READ_BUFFER_SIZE, p_buf, \ 10465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project get_acl_data_length_cback)) == FALSE) 10475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->dealloc((TRANSAC) p_buf, (char *) (p_buf + 1)); 10495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 10515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 10525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (bt_hc_cbacks) 10555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 10565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("vendor lib postload aborted"); 10575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks->postload_cb(NULL, BT_HC_POSTLOAD_FAIL); 10585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 10595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 10605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 10635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** HCI H4 Services interface table 10645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 10655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 10665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectconst tHCI_IF hci_h4_func_table = 10675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 10685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_init, 10695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_cleanup, 10705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_send_msg, 10715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_send_int_cmd, 10725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_get_acl_data_length, 10735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project hci_h4_receive_msg 10745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 10755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1076