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