119e95205Sopenharmony_ci/* 219e95205Sopenharmony_ci * Copyright (C) 2021-2022 Huawei Device Co., Ltd. 319e95205Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 419e95205Sopenharmony_ci * you may not use this file except in compliance with the License. 519e95205Sopenharmony_ci * You may obtain a copy of the License at 619e95205Sopenharmony_ci * 719e95205Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 819e95205Sopenharmony_ci * 919e95205Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1019e95205Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1119e95205Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1219e95205Sopenharmony_ci * See the License for the specific language governing permissions and 1319e95205Sopenharmony_ci * limitations under the License. 1419e95205Sopenharmony_ci */ 1519e95205Sopenharmony_ci 1619e95205Sopenharmony_ci#include "hci.h" 1719e95205Sopenharmony_ci 1819e95205Sopenharmony_ci#include "btm/btm_thread.h" 1919e95205Sopenharmony_ci#include "btstack.h" 2019e95205Sopenharmony_ci#include "log.h" 2119e95205Sopenharmony_ci#include "packet.h" 2219e95205Sopenharmony_ci#include "platform/include/allocator.h" 2319e95205Sopenharmony_ci#include "platform/include/event.h" 2419e95205Sopenharmony_ci#include "platform/include/module.h" 2519e95205Sopenharmony_ci#include "platform/include/queue.h" 2619e95205Sopenharmony_ci#include "platform/include/reactor.h" 2719e95205Sopenharmony_ci#include "platform/include/semaphore.h" 2819e95205Sopenharmony_ci#include "platform/include/thread.h" 2919e95205Sopenharmony_ci 3019e95205Sopenharmony_ci#include "alarm.h" 3119e95205Sopenharmony_ci#include "acl/hci_acl.h" 3219e95205Sopenharmony_ci#include "cmd/hci_cmd.h" 3319e95205Sopenharmony_ci#include "evt/hci_evt.h" 3419e95205Sopenharmony_ci#include "hdi_wrapper.h" 3519e95205Sopenharmony_ci#include "hci_def.h" 3619e95205Sopenharmony_ci#include "hci_failure.h" 3719e95205Sopenharmony_ci#include "hci_internal.h" 3819e95205Sopenharmony_ci#include "hci_vendor_if.h" 3919e95205Sopenharmony_ci 4019e95205Sopenharmony_ci#include <unistd.h> 4119e95205Sopenharmony_ci#include <sys/wait.h> 4219e95205Sopenharmony_ci#include "securec.h" 4319e95205Sopenharmony_ci 4419e95205Sopenharmony_ci#define HCI_TX_QUEUE_SIZE INT32_MAX 4519e95205Sopenharmony_ci#define HCI_RX_QUEUE_SIZE INT32_MAX 4619e95205Sopenharmony_ci#define HCI_WAIT_HDI_INIT_TIME 5000 4719e95205Sopenharmony_ci 4819e95205Sopenharmony_cistatic BtHciCallbacks g_hdiCallacks; 4919e95205Sopenharmony_ci 5019e95205Sopenharmony_cistatic Queue *g_hciTxQueue = NULL; 5119e95205Sopenharmony_cistatic Queue *g_hciRxQueue = NULL; 5219e95205Sopenharmony_ci 5319e95205Sopenharmony_cistatic ReactorItem *g_hciTxReactorItem = NULL; 5419e95205Sopenharmony_cistatic ReactorItem *g_hciRxReactorItem = NULL; 5519e95205Sopenharmony_ci 5619e95205Sopenharmony_cistatic Semaphore *g_waitHdiInit; 5719e95205Sopenharmony_cistatic BtInitStatus g_hdiInitStatus = UNKNOWN; 5819e95205Sopenharmony_cistatic Alarm *g_waitHdiInitAlarm = NULL; 5919e95205Sopenharmony_ci 6019e95205Sopenharmony_cistatic HDILib *g_hdiLib = NULL; 6119e95205Sopenharmony_ci 6219e95205Sopenharmony_cistatic bool g_transmissionCapture = false; 6319e95205Sopenharmony_cistatic void (*g_transmissionCallback)(uint8_t type, const uint8_t *data, uint16_t length) = NULL; 6419e95205Sopenharmony_ci 6519e95205Sopenharmony_cistatic Thread *g_hciTxThread = NULL; 6619e95205Sopenharmony_ci 6719e95205Sopenharmony_ci// Function Declare 6819e95205Sopenharmony_cistatic void HciSendPacketCallback(void *param); 6919e95205Sopenharmony_cistatic void HciRecvPacketCallback(void *param); 7019e95205Sopenharmony_ci 7119e95205Sopenharmony_cistatic void HciFreePacket(void *packet) 7219e95205Sopenharmony_ci{ 7319e95205Sopenharmony_ci HciPacket *hciPacket = packet; 7419e95205Sopenharmony_ci if (hciPacket != NULL) { 7519e95205Sopenharmony_ci PacketFree(hciPacket->packet); 7619e95205Sopenharmony_ci } 7719e95205Sopenharmony_ci MEM_MALLOC.free(packet); 7819e95205Sopenharmony_ci} 7919e95205Sopenharmony_ci 8019e95205Sopenharmony_cistatic void HciOnHDIInitedTimerTimeout(void *param) 8119e95205Sopenharmony_ci{ 8219e95205Sopenharmony_ci pid_t pid = getpid(); 8319e95205Sopenharmony_ci LOG_DEBUG("%{public}s pid:%{public}d", __FUNCTION__, pid); 8419e95205Sopenharmony_ci if (kill(pid, SIGTERM) == -1) { 8519e95205Sopenharmony_ci if (ESRCH == errno) { 8619e95205Sopenharmony_ci LOG_INFO("kill [%{public}d] success, pid no exist", pid); 8719e95205Sopenharmony_ci } 8819e95205Sopenharmony_ci LOG_ERROR("kill [%{public}d] failed", pid); 8919e95205Sopenharmony_ci } 9019e95205Sopenharmony_ci} 9119e95205Sopenharmony_ci 9219e95205Sopenharmony_cistatic int HciInitQueue() 9319e95205Sopenharmony_ci{ 9419e95205Sopenharmony_ci int result = BT_SUCCESS; 9519e95205Sopenharmony_ci 9619e95205Sopenharmony_ci do { 9719e95205Sopenharmony_ci g_hciTxQueue = QueueCreate(HCI_TX_QUEUE_SIZE); 9819e95205Sopenharmony_ci if (g_hciTxQueue != NULL) { 9919e95205Sopenharmony_ci Reactor *reactor = ThreadGetReactor(g_hciTxThread); 10019e95205Sopenharmony_ci g_hciTxReactorItem = 10119e95205Sopenharmony_ci ReactorRegister(reactor, QueueGetDequeueFd(g_hciTxQueue), NULL, HciSendPacketCallback, NULL); 10219e95205Sopenharmony_ci } else { 10319e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 10419e95205Sopenharmony_ci break; 10519e95205Sopenharmony_ci } 10619e95205Sopenharmony_ci g_hciRxQueue = QueueCreate(HCI_RX_QUEUE_SIZE); 10719e95205Sopenharmony_ci if (g_hciRxQueue != NULL) { 10819e95205Sopenharmony_ci Reactor *reactor = ThreadGetReactor(BTM_GetProcessingThread()); 10919e95205Sopenharmony_ci g_hciRxReactorItem = 11019e95205Sopenharmony_ci ReactorRegister(reactor, QueueGetDequeueFd(g_hciRxQueue), NULL, HciRecvPacketCallback, NULL); 11119e95205Sopenharmony_ci } else { 11219e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 11319e95205Sopenharmony_ci break; 11419e95205Sopenharmony_ci } 11519e95205Sopenharmony_ci } while (0); 11619e95205Sopenharmony_ci 11719e95205Sopenharmony_ci return result; 11819e95205Sopenharmony_ci} 11919e95205Sopenharmony_ci 12019e95205Sopenharmony_ciNO_SANITIZE("cfi") static int HciInitHal() 12119e95205Sopenharmony_ci{ 12219e95205Sopenharmony_ci int result = BT_SUCCESS; 12319e95205Sopenharmony_ci 12419e95205Sopenharmony_ci g_waitHdiInit = SemaphoreCreate(0); 12519e95205Sopenharmony_ci int ret = g_hdiLib->hdiInit(&g_hdiCallacks); 12619e95205Sopenharmony_ci if (ret == SUCCESS) { 12719e95205Sopenharmony_ci g_waitHdiInitAlarm = AlarmCreate(NULL, false); 12819e95205Sopenharmony_ci if (g_waitHdiInitAlarm == NULL) { 12919e95205Sopenharmony_ci LOG_ERROR("HdiInited alarm create failed"); 13019e95205Sopenharmony_ci } else { 13119e95205Sopenharmony_ci AlarmSet(g_waitHdiInitAlarm, HCI_WAIT_HDI_INIT_TIME, HciOnHDIInitedTimerTimeout, NULL); 13219e95205Sopenharmony_ci } 13319e95205Sopenharmony_ci SemaphoreWait(g_waitHdiInit); 13419e95205Sopenharmony_ci if (g_hdiInitStatus != SUCCESS) { 13519e95205Sopenharmony_ci LOG_ERROR("HdiInited failed: %{public}d", g_hdiInitStatus); 13619e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 13719e95205Sopenharmony_ci } 13819e95205Sopenharmony_ci } else { 13919e95205Sopenharmony_ci LOG_ERROR("hdiInit failed: %{public}d", ret); 14019e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 14119e95205Sopenharmony_ci } 14219e95205Sopenharmony_ci SemaphoreDelete(g_waitHdiInit); 14319e95205Sopenharmony_ci g_waitHdiInit = NULL; 14419e95205Sopenharmony_ci 14519e95205Sopenharmony_ci return result; 14619e95205Sopenharmony_ci} 14719e95205Sopenharmony_ci 14819e95205Sopenharmony_cistatic void HciCloseQueue() 14919e95205Sopenharmony_ci{ 15019e95205Sopenharmony_ci if (g_hciTxReactorItem != NULL) { 15119e95205Sopenharmony_ci ReactorUnregister(g_hciTxReactorItem); 15219e95205Sopenharmony_ci g_hciTxReactorItem = NULL; 15319e95205Sopenharmony_ci } 15419e95205Sopenharmony_ci 15519e95205Sopenharmony_ci if (g_hciRxReactorItem != NULL) { 15619e95205Sopenharmony_ci ReactorUnregister(g_hciRxReactorItem); 15719e95205Sopenharmony_ci g_hciRxReactorItem = NULL; 15819e95205Sopenharmony_ci } 15919e95205Sopenharmony_ci 16019e95205Sopenharmony_ci if (g_hciTxQueue != NULL) { 16119e95205Sopenharmony_ci QueueDelete(g_hciTxQueue, HciFreePacket); 16219e95205Sopenharmony_ci g_hciTxQueue = NULL; 16319e95205Sopenharmony_ci } 16419e95205Sopenharmony_ci 16519e95205Sopenharmony_ci if (g_hciRxQueue != NULL) { 16619e95205Sopenharmony_ci QueueDelete(g_hciRxQueue, HciFreePacket); 16719e95205Sopenharmony_ci g_hciRxQueue = NULL; 16819e95205Sopenharmony_ci } 16919e95205Sopenharmony_ci} 17019e95205Sopenharmony_ci 17119e95205Sopenharmony_ciint HCI_Initialize() 17219e95205Sopenharmony_ci{ 17319e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 17419e95205Sopenharmony_ci int result; 17519e95205Sopenharmony_ci 17619e95205Sopenharmony_ci do { 17719e95205Sopenharmony_ci g_hdiLib = LoadHdiLib(); 17819e95205Sopenharmony_ci if (g_hdiLib == NULL) { 17919e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 18019e95205Sopenharmony_ci break; 18119e95205Sopenharmony_ci } 18219e95205Sopenharmony_ci 18319e95205Sopenharmony_ci HciInitFailure(); 18419e95205Sopenharmony_ci HciInitCmd(); 18519e95205Sopenharmony_ci HciInitEvent(); 18619e95205Sopenharmony_ci HciInitAcl(); 18719e95205Sopenharmony_ci HciVendorInit(); 18819e95205Sopenharmony_ci 18919e95205Sopenharmony_ci g_hciTxThread = ThreadCreate("HciTx"); 19019e95205Sopenharmony_ci if (g_hciTxThread == NULL) { 19119e95205Sopenharmony_ci result = BT_OPERATION_FAILED; 19219e95205Sopenharmony_ci break; 19319e95205Sopenharmony_ci } 19419e95205Sopenharmony_ci 19519e95205Sopenharmony_ci result = HciInitQueue(); 19619e95205Sopenharmony_ci if (result != BT_SUCCESS) { 19719e95205Sopenharmony_ci break; 19819e95205Sopenharmony_ci } 19919e95205Sopenharmony_ci 20019e95205Sopenharmony_ci result = HciInitHal(); 20119e95205Sopenharmony_ci } while (0); 20219e95205Sopenharmony_ci 20319e95205Sopenharmony_ci if (result != BT_SUCCESS) { 20419e95205Sopenharmony_ci if (g_hdiLib != NULL) { 20519e95205Sopenharmony_ci if (g_hdiLib->hdiClose != NULL) { 20619e95205Sopenharmony_ci g_hdiLib->hdiClose(); 20719e95205Sopenharmony_ci } 20819e95205Sopenharmony_ci UnloadHdiLib(g_hdiLib); 20919e95205Sopenharmony_ci g_hdiLib = NULL; 21019e95205Sopenharmony_ci } 21119e95205Sopenharmony_ci 21219e95205Sopenharmony_ci HciCloseQueue(); 21319e95205Sopenharmony_ci 21419e95205Sopenharmony_ci if (g_hciTxThread != NULL) { 21519e95205Sopenharmony_ci ThreadDelete(g_hciTxThread); 21619e95205Sopenharmony_ci g_hciTxThread = NULL; 21719e95205Sopenharmony_ci } 21819e95205Sopenharmony_ci } 21919e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 22019e95205Sopenharmony_ci return result; 22119e95205Sopenharmony_ci} 22219e95205Sopenharmony_ci 22319e95205Sopenharmony_cistatic void CleanTxPacket() 22419e95205Sopenharmony_ci{ 22519e95205Sopenharmony_ci if (g_hciTxQueue != NULL) { 22619e95205Sopenharmony_ci HciPacket *packet = QueueTryDequeue(g_hciTxQueue); 22719e95205Sopenharmony_ci while (packet != NULL) { 22819e95205Sopenharmony_ci HciFreePacket(packet); 22919e95205Sopenharmony_ci packet = QueueTryDequeue(g_hciTxQueue); 23019e95205Sopenharmony_ci } 23119e95205Sopenharmony_ci } 23219e95205Sopenharmony_ci} 23319e95205Sopenharmony_ci 23419e95205Sopenharmony_cistatic void CleanRxPacket() 23519e95205Sopenharmony_ci{ 23619e95205Sopenharmony_ci if (g_hciRxQueue != NULL) { 23719e95205Sopenharmony_ci HciPacket *packet = QueueTryDequeue(g_hciRxQueue); 23819e95205Sopenharmony_ci while (packet != NULL) { 23919e95205Sopenharmony_ci HciFreePacket(packet); 24019e95205Sopenharmony_ci packet = QueueTryDequeue(g_hciTxQueue); 24119e95205Sopenharmony_ci } 24219e95205Sopenharmony_ci } 24319e95205Sopenharmony_ci} 24419e95205Sopenharmony_ci 24519e95205Sopenharmony_cistatic void WaitRxTaskCompleteTask(void *context) 24619e95205Sopenharmony_ci{ 24719e95205Sopenharmony_ci Event *taskCompleteEvent = (Event *)context; 24819e95205Sopenharmony_ci if (taskCompleteEvent != NULL) { 24919e95205Sopenharmony_ci EventSet(taskCompleteEvent); 25019e95205Sopenharmony_ci } 25119e95205Sopenharmony_ci} 25219e95205Sopenharmony_ci 25319e95205Sopenharmony_cistatic void WaitRxTaskComplete() 25419e95205Sopenharmony_ci{ 25519e95205Sopenharmony_ci const int taskTimeout = 1000; 25619e95205Sopenharmony_ci 25719e95205Sopenharmony_ci Event *taskCompleteEvent = EventCreate(true); 25819e95205Sopenharmony_ci if (taskCompleteEvent != NULL) { 25919e95205Sopenharmony_ci ThreadPostTask(BTM_GetProcessingThread(), WaitRxTaskCompleteTask, taskCompleteEvent); 26019e95205Sopenharmony_ci EventWait(taskCompleteEvent, taskTimeout); 26119e95205Sopenharmony_ci EventDelete(taskCompleteEvent); 26219e95205Sopenharmony_ci } 26319e95205Sopenharmony_ci} 26419e95205Sopenharmony_ci 26519e95205Sopenharmony_ciNO_SANITIZE("cfi") void HCI_Close() 26619e95205Sopenharmony_ci{ 26719e95205Sopenharmony_ci LOG_DEBUG("%{public}s start", __FUNCTION__); 26819e95205Sopenharmony_ci 26919e95205Sopenharmony_ci CleanTxPacket(); 27019e95205Sopenharmony_ci 27119e95205Sopenharmony_ci if (g_waitHdiInitAlarm != NULL) { 27219e95205Sopenharmony_ci AlarmCancel(g_waitHdiInitAlarm); 27319e95205Sopenharmony_ci AlarmDelete(g_waitHdiInitAlarm); 27419e95205Sopenharmony_ci g_waitHdiInitAlarm = NULL; 27519e95205Sopenharmony_ci } 27619e95205Sopenharmony_ci 27719e95205Sopenharmony_ci if (g_hciTxReactorItem != NULL) { 27819e95205Sopenharmony_ci ReactorUnregister(g_hciTxReactorItem); 27919e95205Sopenharmony_ci g_hciTxReactorItem = NULL; 28019e95205Sopenharmony_ci } 28119e95205Sopenharmony_ci 28219e95205Sopenharmony_ci if (g_hciTxThread != NULL) { 28319e95205Sopenharmony_ci ThreadDelete(g_hciTxThread); 28419e95205Sopenharmony_ci g_hciTxThread = NULL; 28519e95205Sopenharmony_ci } 28619e95205Sopenharmony_ci 28719e95205Sopenharmony_ci if (g_hdiLib != NULL && g_hdiLib->hdiClose != NULL) { 28819e95205Sopenharmony_ci g_hdiLib->hdiClose(); 28919e95205Sopenharmony_ci } 29019e95205Sopenharmony_ci 29119e95205Sopenharmony_ci CleanRxPacket(); 29219e95205Sopenharmony_ci 29319e95205Sopenharmony_ci if (g_hciRxReactorItem != NULL) { 29419e95205Sopenharmony_ci ReactorUnregister(g_hciRxReactorItem); 29519e95205Sopenharmony_ci g_hciRxReactorItem = NULL; 29619e95205Sopenharmony_ci } 29719e95205Sopenharmony_ci 29819e95205Sopenharmony_ci WaitRxTaskComplete(); 29919e95205Sopenharmony_ci 30019e95205Sopenharmony_ci if (g_hciTxQueue != NULL) { 30119e95205Sopenharmony_ci QueueDelete(g_hciTxQueue, HciFreePacket); 30219e95205Sopenharmony_ci g_hciTxQueue = NULL; 30319e95205Sopenharmony_ci } 30419e95205Sopenharmony_ci 30519e95205Sopenharmony_ci if (g_hciRxQueue != NULL) { 30619e95205Sopenharmony_ci QueueDelete(g_hciRxQueue, HciFreePacket); 30719e95205Sopenharmony_ci g_hciRxQueue = NULL; 30819e95205Sopenharmony_ci } 30919e95205Sopenharmony_ci 31019e95205Sopenharmony_ci HciCloseCmd(); 31119e95205Sopenharmony_ci HciCloseEvent(); 31219e95205Sopenharmony_ci HciCloseAcl(); 31319e95205Sopenharmony_ci HciCloseFailure(); 31419e95205Sopenharmony_ci HciVendorClose(); 31519e95205Sopenharmony_ci 31619e95205Sopenharmony_ci if (g_hdiLib != NULL) { 31719e95205Sopenharmony_ci UnloadHdiLib(g_hdiLib); 31819e95205Sopenharmony_ci g_hdiLib = NULL; 31919e95205Sopenharmony_ci } 32019e95205Sopenharmony_ci 32119e95205Sopenharmony_ci LOG_DEBUG("%{public}s end", __FUNCTION__); 32219e95205Sopenharmony_ci} 32319e95205Sopenharmony_ci 32419e95205Sopenharmony_cistatic void HciOnHDIInited(BtInitStatus status) 32519e95205Sopenharmony_ci{ 32619e95205Sopenharmony_ci if (g_waitHdiInitAlarm != NULL) { 32719e95205Sopenharmony_ci AlarmCancel(g_waitHdiInitAlarm); 32819e95205Sopenharmony_ci AlarmDelete(g_waitHdiInitAlarm); 32919e95205Sopenharmony_ci g_waitHdiInitAlarm = NULL; 33019e95205Sopenharmony_ci } 33119e95205Sopenharmony_ci g_hdiInitStatus = status; 33219e95205Sopenharmony_ci SemaphorePost(g_waitHdiInit); 33319e95205Sopenharmony_ci} 33419e95205Sopenharmony_ci 33519e95205Sopenharmony_cistatic void HciOnReceivedHciPacket(BtPacketType type, const BtPacket *btPacket) 33619e95205Sopenharmony_ci{ 33719e95205Sopenharmony_ci if (g_transmissionCapture && g_transmissionCallback != NULL) { 33819e95205Sopenharmony_ci uint8_t transType = (type == PACKET_TYPE_EVENT) ? TRANSMISSON_TYPE_C2H_EVENT : TRANSMISSON_TYPE_C2H_DATA; 33919e95205Sopenharmony_ci g_transmissionCallback(transType, btPacket->data, btPacket->size); 34019e95205Sopenharmony_ci } 34119e95205Sopenharmony_ci 34219e95205Sopenharmony_ci HciPacket *hciPacket = MEM_MALLOC.alloc(sizeof(HciPacket)); 34319e95205Sopenharmony_ci if (hciPacket != NULL) { 34419e95205Sopenharmony_ci switch (type) { 34519e95205Sopenharmony_ci case PACKET_TYPE_ACL: 34619e95205Sopenharmony_ci hciPacket->type = C2H_ACLDATA; 34719e95205Sopenharmony_ci break; 34819e95205Sopenharmony_ci case PACKET_TYPE_EVENT: 34919e95205Sopenharmony_ci hciPacket->type = C2H_EVENT; 35019e95205Sopenharmony_ci break; 35119e95205Sopenharmony_ci default: 35219e95205Sopenharmony_ci break; 35319e95205Sopenharmony_ci } 35419e95205Sopenharmony_ci 35519e95205Sopenharmony_ci hciPacket->packet = PacketMalloc(0, 0, btPacket->size); 35619e95205Sopenharmony_ci PacketPayloadWrite(hciPacket->packet, btPacket->data, 0, btPacket->size); 35719e95205Sopenharmony_ci 35819e95205Sopenharmony_ci QueueEnqueue(g_hciRxQueue, hciPacket); 35919e95205Sopenharmony_ci } 36019e95205Sopenharmony_ci} 36119e95205Sopenharmony_ci 36219e95205Sopenharmony_ciNO_SANITIZE("cfi") static void HciSendPacketCallback(void *param) 36319e95205Sopenharmony_ci{ 36419e95205Sopenharmony_ci HciPacket *packet = QueueTryDequeue(g_hciTxQueue); 36519e95205Sopenharmony_ci if (packet != NULL) { 36619e95205Sopenharmony_ci BtPacket btPacket; 36719e95205Sopenharmony_ci btPacket.size = PacketSize(packet->packet); 36819e95205Sopenharmony_ci btPacket.data = MEM_MALLOC.alloc(btPacket.size); 36919e95205Sopenharmony_ci PacketRead(packet->packet, btPacket.data, 0, btPacket.size); 37019e95205Sopenharmony_ci 37119e95205Sopenharmony_ci int result; 37219e95205Sopenharmony_ci 37319e95205Sopenharmony_ci if (g_hdiLib == NULL) { 37419e95205Sopenharmony_ci LOG_ERROR("HDI is invalid."); 37519e95205Sopenharmony_ci return; 37619e95205Sopenharmony_ci } 37719e95205Sopenharmony_ci 37819e95205Sopenharmony_ci switch (packet->type) { 37919e95205Sopenharmony_ci case H2C_CMD: 38019e95205Sopenharmony_ci result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_CMD, &btPacket); 38119e95205Sopenharmony_ci break; 38219e95205Sopenharmony_ci case H2C_ACLDATA: 38319e95205Sopenharmony_ci result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_ACL, &btPacket); 38419e95205Sopenharmony_ci break; 38519e95205Sopenharmony_ci case H2C_SCODATA: 38619e95205Sopenharmony_ci result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_SCO, &btPacket); 38719e95205Sopenharmony_ci break; 38819e95205Sopenharmony_ci default: 38919e95205Sopenharmony_ci result = UNKNOWN; 39019e95205Sopenharmony_ci break; 39119e95205Sopenharmony_ci } 39219e95205Sopenharmony_ci 39319e95205Sopenharmony_ci if (result != SUCCESS) { 39419e95205Sopenharmony_ci LOG_ERROR("Send packet to HDI failed: %{public}d", result); 39519e95205Sopenharmony_ci } else { 39619e95205Sopenharmony_ci if (g_transmissionCapture && g_transmissionCallback != NULL) { 39719e95205Sopenharmony_ci uint8_t type = (packet->type == H2C_CMD) ? TRANSMISSON_TYPE_H2C_CMD : TRANSMISSON_TYPE_H2C_DATA; 39819e95205Sopenharmony_ci g_transmissionCallback(type, btPacket.data, btPacket.size); 39919e95205Sopenharmony_ci } 40019e95205Sopenharmony_ci } 40119e95205Sopenharmony_ci 40219e95205Sopenharmony_ci MEM_MALLOC.free(btPacket.data); 40319e95205Sopenharmony_ci HciFreePacket(packet); 40419e95205Sopenharmony_ci } 40519e95205Sopenharmony_ci} 40619e95205Sopenharmony_ci 40719e95205Sopenharmony_cistatic void HciRecvPacketCallback(void *param) 40819e95205Sopenharmony_ci{ 40919e95205Sopenharmony_ci HciPacket *packet = QueueTryDequeue(g_hciRxQueue); 41019e95205Sopenharmony_ci if (packet != NULL) { 41119e95205Sopenharmony_ci switch (packet->type) { 41219e95205Sopenharmony_ci case C2H_ACLDATA: 41319e95205Sopenharmony_ci HciOnAclData(packet->packet); 41419e95205Sopenharmony_ci break; 41519e95205Sopenharmony_ci case C2H_EVENT: 41619e95205Sopenharmony_ci HciOnEvent(packet->packet); 41719e95205Sopenharmony_ci break; 41819e95205Sopenharmony_ci case C2H_SCODATA: 41919e95205Sopenharmony_ci // NOT IMPLETEMENTED 42019e95205Sopenharmony_ci break; 42119e95205Sopenharmony_ci default: 42219e95205Sopenharmony_ci break; 42319e95205Sopenharmony_ci } 42419e95205Sopenharmony_ci HciFreePacket(packet); 42519e95205Sopenharmony_ci } 42619e95205Sopenharmony_ci} 42719e95205Sopenharmony_ci 42819e95205Sopenharmony_civoid HciPushToTxQueue(HciPacket *packet) 42919e95205Sopenharmony_ci{ 43019e95205Sopenharmony_ci QueueEnqueue(g_hciTxQueue, packet); 43119e95205Sopenharmony_ci} 43219e95205Sopenharmony_ci 43319e95205Sopenharmony_ciint HCI_SetTransmissionCaptureCallback(void (*onTransmission)(uint8_t type, const uint8_t *data, uint16_t length)) 43419e95205Sopenharmony_ci{ 43519e95205Sopenharmony_ci g_transmissionCallback = onTransmission; 43619e95205Sopenharmony_ci return BT_SUCCESS; 43719e95205Sopenharmony_ci} 43819e95205Sopenharmony_ci 43919e95205Sopenharmony_ciint HCI_EnableTransmissionCapture() 44019e95205Sopenharmony_ci{ 44119e95205Sopenharmony_ci g_transmissionCapture = true; 44219e95205Sopenharmony_ci return BT_SUCCESS; 44319e95205Sopenharmony_ci} 44419e95205Sopenharmony_ci 44519e95205Sopenharmony_ciint HCI_DisableTransmissionCapture() 44619e95205Sopenharmony_ci{ 44719e95205Sopenharmony_ci g_transmissionCapture = false; 44819e95205Sopenharmony_ci return BT_SUCCESS; 44919e95205Sopenharmony_ci} 45019e95205Sopenharmony_ci 45119e95205Sopenharmony_cistatic BtHciCallbacks g_hdiCallacks = { 45219e95205Sopenharmony_ci .OnInited = HciOnHDIInited, 45319e95205Sopenharmony_ci .OnReceivedHciPacket = HciOnReceivedHciPacket, 45419e95205Sopenharmony_ci}; 455