1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hci.h"
17
18 #include "btm/btm_thread.h"
19 #include "btstack.h"
20 #include "log.h"
21 #include "packet.h"
22 #include "platform/include/allocator.h"
23 #include "platform/include/event.h"
24 #include "platform/include/module.h"
25 #include "platform/include/queue.h"
26 #include "platform/include/reactor.h"
27 #include "platform/include/semaphore.h"
28 #include "platform/include/thread.h"
29
30 #include "alarm.h"
31 #include "acl/hci_acl.h"
32 #include "cmd/hci_cmd.h"
33 #include "evt/hci_evt.h"
34 #include "hdi_wrapper.h"
35 #include "hci_def.h"
36 #include "hci_failure.h"
37 #include "hci_internal.h"
38 #include "hci_vendor_if.h"
39
40 #include <unistd.h>
41 #include <sys/wait.h>
42 #include "securec.h"
43
44 #define HCI_TX_QUEUE_SIZE INT32_MAX
45 #define HCI_RX_QUEUE_SIZE INT32_MAX
46 #define HCI_WAIT_HDI_INIT_TIME 5000
47
48 static BtHciCallbacks g_hdiCallacks;
49
50 static Queue *g_hciTxQueue = NULL;
51 static Queue *g_hciRxQueue = NULL;
52
53 static ReactorItem *g_hciTxReactorItem = NULL;
54 static ReactorItem *g_hciRxReactorItem = NULL;
55
56 static Semaphore *g_waitHdiInit;
57 static BtInitStatus g_hdiInitStatus = UNKNOWN;
58 static Alarm *g_waitHdiInitAlarm = NULL;
59
60 static HDILib *g_hdiLib = NULL;
61
62 static bool g_transmissionCapture = false;
63 static void (*g_transmissionCallback)(uint8_t type, const uint8_t *data, uint16_t length) = NULL;
64
65 static Thread *g_hciTxThread = NULL;
66
67 // Function Declare
68 static void HciSendPacketCallback(void *param);
69 static void HciRecvPacketCallback(void *param);
70
HciFreePacket(void *packet)71 static void HciFreePacket(void *packet)
72 {
73 HciPacket *hciPacket = packet;
74 if (hciPacket != NULL) {
75 PacketFree(hciPacket->packet);
76 }
77 MEM_MALLOC.free(packet);
78 }
79
HciOnHDIInitedTimerTimeout(void *param)80 static void HciOnHDIInitedTimerTimeout(void *param)
81 {
82 pid_t pid = getpid();
83 LOG_DEBUG("%{public}s pid:%{public}d", __FUNCTION__, pid);
84 if (kill(pid, SIGTERM) == -1) {
85 if (ESRCH == errno) {
86 LOG_INFO("kill [%{public}d] success, pid no exist", pid);
87 }
88 LOG_ERROR("kill [%{public}d] failed", pid);
89 }
90 }
91
HciInitQueuenull92 static int HciInitQueue()
93 {
94 int result = BT_SUCCESS;
95
96 do {
97 g_hciTxQueue = QueueCreate(HCI_TX_QUEUE_SIZE);
98 if (g_hciTxQueue != NULL) {
99 Reactor *reactor = ThreadGetReactor(g_hciTxThread);
100 g_hciTxReactorItem =
101 ReactorRegister(reactor, QueueGetDequeueFd(g_hciTxQueue), NULL, HciSendPacketCallback, NULL);
102 } else {
103 result = BT_OPERATION_FAILED;
104 break;
105 }
106 g_hciRxQueue = QueueCreate(HCI_RX_QUEUE_SIZE);
107 if (g_hciRxQueue != NULL) {
108 Reactor *reactor = ThreadGetReactor(BTM_GetProcessingThread());
109 g_hciRxReactorItem =
110 ReactorRegister(reactor, QueueGetDequeueFd(g_hciRxQueue), NULL, HciRecvPacketCallback, NULL);
111 } else {
112 result = BT_OPERATION_FAILED;
113 break;
114 }
115 } while (0);
116
117 return result;
118 }
119
HciInitHalnull120 NO_SANITIZE("cfi") static int HciInitHal()
121 {
122 int result = BT_SUCCESS;
123
124 g_waitHdiInit = SemaphoreCreate(0);
125 int ret = g_hdiLib->hdiInit(&g_hdiCallacks);
126 if (ret == SUCCESS) {
127 g_waitHdiInitAlarm = AlarmCreate(NULL, false);
128 if (g_waitHdiInitAlarm == NULL) {
129 LOG_ERROR("HdiInited alarm create failed");
130 } else {
131 AlarmSet(g_waitHdiInitAlarm, HCI_WAIT_HDI_INIT_TIME, HciOnHDIInitedTimerTimeout, NULL);
132 }
133 SemaphoreWait(g_waitHdiInit);
134 if (g_hdiInitStatus != SUCCESS) {
135 LOG_ERROR("HdiInited failed: %{public}d", g_hdiInitStatus);
136 result = BT_OPERATION_FAILED;
137 }
138 } else {
139 LOG_ERROR("hdiInit failed: %{public}d", ret);
140 result = BT_OPERATION_FAILED;
141 }
142 SemaphoreDelete(g_waitHdiInit);
143 g_waitHdiInit = NULL;
144
145 return result;
146 }
147
HciCloseQueuenull148 static void HciCloseQueue()
149 {
150 if (g_hciTxReactorItem != NULL) {
151 ReactorUnregister(g_hciTxReactorItem);
152 g_hciTxReactorItem = NULL;
153 }
154
155 if (g_hciRxReactorItem != NULL) {
156 ReactorUnregister(g_hciRxReactorItem);
157 g_hciRxReactorItem = NULL;
158 }
159
160 if (g_hciTxQueue != NULL) {
161 QueueDelete(g_hciTxQueue, HciFreePacket);
162 g_hciTxQueue = NULL;
163 }
164
165 if (g_hciRxQueue != NULL) {
166 QueueDelete(g_hciRxQueue, HciFreePacket);
167 g_hciRxQueue = NULL;
168 }
169 }
170
HCI_Initializenull171 int HCI_Initialize()
172 {
173 LOG_DEBUG("%{public}s start", __FUNCTION__);
174 int result;
175
176 do {
177 g_hdiLib = LoadHdiLib();
178 if (g_hdiLib == NULL) {
179 result = BT_OPERATION_FAILED;
180 break;
181 }
182
183 HciInitFailure();
184 HciInitCmd();
185 HciInitEvent();
186 HciInitAcl();
187 HciVendorInit();
188
189 g_hciTxThread = ThreadCreate("HciTx");
190 if (g_hciTxThread == NULL) {
191 result = BT_OPERATION_FAILED;
192 break;
193 }
194
195 result = HciInitQueue();
196 if (result != BT_SUCCESS) {
197 break;
198 }
199
200 result = HciInitHal();
201 } while (0);
202
203 if (result != BT_SUCCESS) {
204 if (g_hdiLib != NULL) {
205 if (g_hdiLib->hdiClose != NULL) {
206 g_hdiLib->hdiClose();
207 }
208 UnloadHdiLib(g_hdiLib);
209 g_hdiLib = NULL;
210 }
211
212 HciCloseQueue();
213
214 if (g_hciTxThread != NULL) {
215 ThreadDelete(g_hciTxThread);
216 g_hciTxThread = NULL;
217 }
218 }
219 LOG_DEBUG("%{public}s end", __FUNCTION__);
220 return result;
221 }
222
CleanTxPacketnull223 static void CleanTxPacket()
224 {
225 if (g_hciTxQueue != NULL) {
226 HciPacket *packet = QueueTryDequeue(g_hciTxQueue);
227 while (packet != NULL) {
228 HciFreePacket(packet);
229 packet = QueueTryDequeue(g_hciTxQueue);
230 }
231 }
232 }
233
CleanRxPacketnull234 static void CleanRxPacket()
235 {
236 if (g_hciRxQueue != NULL) {
237 HciPacket *packet = QueueTryDequeue(g_hciRxQueue);
238 while (packet != NULL) {
239 HciFreePacket(packet);
240 packet = QueueTryDequeue(g_hciTxQueue);
241 }
242 }
243 }
244
WaitRxTaskCompleteTask(void *context)245 static void WaitRxTaskCompleteTask(void *context)
246 {
247 Event *taskCompleteEvent = (Event *)context;
248 if (taskCompleteEvent != NULL) {
249 EventSet(taskCompleteEvent);
250 }
251 }
252
WaitRxTaskCompletenull253 static void WaitRxTaskComplete()
254 {
255 const int taskTimeout = 1000;
256
257 Event *taskCompleteEvent = EventCreate(true);
258 if (taskCompleteEvent != NULL) {
259 ThreadPostTask(BTM_GetProcessingThread(), WaitRxTaskCompleteTask, taskCompleteEvent);
260 EventWait(taskCompleteEvent, taskTimeout);
261 EventDelete(taskCompleteEvent);
262 }
263 }
264
HCI_Closenull265 NO_SANITIZE("cfi") void HCI_Close()
266 {
267 LOG_DEBUG("%{public}s start", __FUNCTION__);
268
269 CleanTxPacket();
270
271 if (g_waitHdiInitAlarm != NULL) {
272 AlarmCancel(g_waitHdiInitAlarm);
273 AlarmDelete(g_waitHdiInitAlarm);
274 g_waitHdiInitAlarm = NULL;
275 }
276
277 if (g_hciTxReactorItem != NULL) {
278 ReactorUnregister(g_hciTxReactorItem);
279 g_hciTxReactorItem = NULL;
280 }
281
282 if (g_hciTxThread != NULL) {
283 ThreadDelete(g_hciTxThread);
284 g_hciTxThread = NULL;
285 }
286
287 if (g_hdiLib != NULL && g_hdiLib->hdiClose != NULL) {
288 g_hdiLib->hdiClose();
289 }
290
291 CleanRxPacket();
292
293 if (g_hciRxReactorItem != NULL) {
294 ReactorUnregister(g_hciRxReactorItem);
295 g_hciRxReactorItem = NULL;
296 }
297
298 WaitRxTaskComplete();
299
300 if (g_hciTxQueue != NULL) {
301 QueueDelete(g_hciTxQueue, HciFreePacket);
302 g_hciTxQueue = NULL;
303 }
304
305 if (g_hciRxQueue != NULL) {
306 QueueDelete(g_hciRxQueue, HciFreePacket);
307 g_hciRxQueue = NULL;
308 }
309
310 HciCloseCmd();
311 HciCloseEvent();
312 HciCloseAcl();
313 HciCloseFailure();
314 HciVendorClose();
315
316 if (g_hdiLib != NULL) {
317 UnloadHdiLib(g_hdiLib);
318 g_hdiLib = NULL;
319 }
320
321 LOG_DEBUG("%{public}s end", __FUNCTION__);
322 }
323
HciOnHDIInited(BtInitStatus status)324 static void HciOnHDIInited(BtInitStatus status)
325 {
326 if (g_waitHdiInitAlarm != NULL) {
327 AlarmCancel(g_waitHdiInitAlarm);
328 AlarmDelete(g_waitHdiInitAlarm);
329 g_waitHdiInitAlarm = NULL;
330 }
331 g_hdiInitStatus = status;
332 SemaphorePost(g_waitHdiInit);
333 }
334
HciOnReceivedHciPacket(BtPacketType type, const BtPacket *btPacket)335 static void HciOnReceivedHciPacket(BtPacketType type, const BtPacket *btPacket)
336 {
337 if (g_transmissionCapture && g_transmissionCallback != NULL) {
338 uint8_t transType = (type == PACKET_TYPE_EVENT) ? TRANSMISSON_TYPE_C2H_EVENT : TRANSMISSON_TYPE_C2H_DATA;
339 g_transmissionCallback(transType, btPacket->data, btPacket->size);
340 }
341
342 HciPacket *hciPacket = MEM_MALLOC.alloc(sizeof(HciPacket));
343 if (hciPacket != NULL) {
344 switch (type) {
345 case PACKET_TYPE_ACL:
346 hciPacket->type = C2H_ACLDATA;
347 break;
348 case PACKET_TYPE_EVENT:
349 hciPacket->type = C2H_EVENT;
350 break;
351 default:
352 break;
353 }
354
355 hciPacket->packet = PacketMalloc(0, 0, btPacket->size);
356 PacketPayloadWrite(hciPacket->packet, btPacket->data, 0, btPacket->size);
357
358 QueueEnqueue(g_hciRxQueue, hciPacket);
359 }
360 }
361
HciSendPacketCallback(void *param)362 NO_SANITIZE("cfi") static void HciSendPacketCallback(void *param)
363 {
364 HciPacket *packet = QueueTryDequeue(g_hciTxQueue);
365 if (packet != NULL) {
366 BtPacket btPacket;
367 btPacket.size = PacketSize(packet->packet);
368 btPacket.data = MEM_MALLOC.alloc(btPacket.size);
369 PacketRead(packet->packet, btPacket.data, 0, btPacket.size);
370
371 int result;
372
373 if (g_hdiLib == NULL) {
374 LOG_ERROR("HDI is invalid.");
375 return;
376 }
377
378 switch (packet->type) {
379 case H2C_CMD:
380 result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_CMD, &btPacket);
381 break;
382 case H2C_ACLDATA:
383 result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_ACL, &btPacket);
384 break;
385 case H2C_SCODATA:
386 result = g_hdiLib->hdiSendHciPacket(PACKET_TYPE_SCO, &btPacket);
387 break;
388 default:
389 result = UNKNOWN;
390 break;
391 }
392
393 if (result != SUCCESS) {
394 LOG_ERROR("Send packet to HDI failed: %{public}d", result);
395 } else {
396 if (g_transmissionCapture && g_transmissionCallback != NULL) {
397 uint8_t type = (packet->type == H2C_CMD) ? TRANSMISSON_TYPE_H2C_CMD : TRANSMISSON_TYPE_H2C_DATA;
398 g_transmissionCallback(type, btPacket.data, btPacket.size);
399 }
400 }
401
402 MEM_MALLOC.free(btPacket.data);
403 HciFreePacket(packet);
404 }
405 }
406
HciRecvPacketCallback(void *param)407 static void HciRecvPacketCallback(void *param)
408 {
409 HciPacket *packet = QueueTryDequeue(g_hciRxQueue);
410 if (packet != NULL) {
411 switch (packet->type) {
412 case C2H_ACLDATA:
413 HciOnAclData(packet->packet);
414 break;
415 case C2H_EVENT:
416 HciOnEvent(packet->packet);
417 break;
418 case C2H_SCODATA:
419 // NOT IMPLETEMENTED
420 break;
421 default:
422 break;
423 }
424 HciFreePacket(packet);
425 }
426 }
427
HciPushToTxQueue(HciPacket *packet)428 void HciPushToTxQueue(HciPacket *packet)
429 {
430 QueueEnqueue(g_hciTxQueue, packet);
431 }
432
HCI_SetTransmissionCaptureCallback(void (*onTransmission)(uint8_t type, const uint8_t *data, uint16_t length))433 int HCI_SetTransmissionCaptureCallback(void (*onTransmission)(uint8_t type, const uint8_t *data, uint16_t length))
434 {
435 g_transmissionCallback = onTransmission;
436 return BT_SUCCESS;
437 }
438
HCI_EnableTransmissionCapturenull439 int HCI_EnableTransmissionCapture()
440 {
441 g_transmissionCapture = true;
442 return BT_SUCCESS;
443 }
444
HCI_DisableTransmissionCapturenull445 int HCI_DisableTransmissionCapture()
446 {
447 g_transmissionCapture = false;
448 return BT_SUCCESS;
449 }
450
451 static BtHciCallbacks g_hdiCallacks = {
452 .OnInited = HciOnHDIInited,
453 .OnReceivedHciPacket = HciOnReceivedHciPacket,
454 };
455