1 /*
2 * Copyright (C) 2021 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_evt_le.h"
17
18 #include <securec.h>
19
20 #include "btstack.h"
21 #include "platform/include/allocator.h"
22 #include "platform/include/list.h"
23 #include "platform/include/mutex.h"
24
25 #include "hci/acl/hci_acl.h"
26 #include "hci/hci.h"
27 #include "hci/hci_def.h"
28 #include "hci/hci_error.h"
29
30 #include "hci_evt.h"
31 #include "log.h"
32
33 typedef void (*HciLeEventFunc)(const uint8_t *param, size_t length);
34
HciEventOnLeConnectionCompleteEvent(const uint8_t * param,size_t length)35 static void HciEventOnLeConnectionCompleteEvent(const uint8_t *param, size_t length)
36 {
37 if (param == NULL || (length != sizeof(HciLeConnectionCompleteEventParam))) {
38 return;
39 }
40
41 HciLeConnectionCompleteEventParam *eventParam = (HciLeConnectionCompleteEventParam *)param;
42
43 if (eventParam->status == HCI_SUCCESS) {
44 HciAclOnConnectionComplete(eventParam->connectionHandle, TRANSPORT_LE);
45 }
46
47 HciEventCallbacks *callbacks = NULL;
48 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
49 if (callbacks->leConnectionComplete != NULL) {
50 callbacks->leConnectionComplete(eventParam);
51 }
52 HCI_FOREACH_EVT_CALLBACKS_END;
53 }
54
HciEventOnLeAdvertisingReportEvent(const uint8_t * param,size_t length)55 static void HciEventOnLeAdvertisingReportEvent(const uint8_t *param, size_t length)
56 {
57 if (param == NULL || length <= 1) {
58 return;
59 }
60
61 int offset = 0;
62 HciLeAdvertisingReportEventParam eventParam = {
63 .numReports = param[offset],
64 .reports = NULL,
65 };
66 offset += sizeof(uint8_t);
67
68 if (eventParam.numReports == 0) {
69 return;
70 }
71
72 HciLeAdvertisingReport *reports = MEM_MALLOC.alloc(sizeof(HciLeAdvertisingReport) * eventParam.numReports);
73 if (reports != NULL) {
74 for (uint8_t i = 0; i < eventParam.numReports; i++) {
75 reports[i].eventType = param[offset];
76 offset += sizeof(uint8_t);
77
78 reports[i].addressType = param[offset];
79 offset += sizeof(uint8_t);
80
81 (void)memcpy_s(reports[i].address.raw, BT_ADDRESS_SIZE, param + offset, BT_ADDRESS_SIZE);
82 offset += BT_ADDRESS_SIZE;
83
84 reports[i].lengthData = param[offset];
85 offset += sizeof(uint8_t);
86
87 reports[i].data = (uint8_t *)(param + offset);
88 offset += reports[i].lengthData;
89
90 reports[i].rssi = param[offset];
91 offset += sizeof(uint8_t);
92 }
93
94 eventParam.reports = reports;
95 } else {
96 return;
97 }
98
99 HciEventCallbacks *callbacks = NULL;
100 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
101 if (callbacks->leAdvertisingReport != NULL) {
102 callbacks->leAdvertisingReport(&eventParam);
103 }
104 HCI_FOREACH_EVT_CALLBACKS_END;
105
106 if (reports != NULL) {
107 MEM_MALLOC.free(reports);
108 }
109 }
110
HciEventOnLeConnectionUpdateCompleteEvent(const uint8_t * param,size_t length)111 static void HciEventOnLeConnectionUpdateCompleteEvent(const uint8_t *param, size_t length)
112 {
113 if (param == NULL || (length != sizeof(HciLeConnectionUpdateCompleteEventParam))) {
114 return;
115 }
116
117 HciLeConnectionUpdateCompleteEventParam *eventParam = (HciLeConnectionUpdateCompleteEventParam *)param;
118
119 HciEventCallbacks *callbacks = NULL;
120 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
121 if (callbacks->leConnectionUpdateComplete != NULL) {
122 callbacks->leConnectionUpdateComplete(eventParam);
123 }
124 HCI_FOREACH_EVT_CALLBACKS_END;
125 }
126
HciEventOnLeReadRemoteFeaturesCompleteEvent(const uint8_t * param,size_t length)127 static void HciEventOnLeReadRemoteFeaturesCompleteEvent(const uint8_t *param, size_t length)
128 {
129 if (param == NULL || (length != sizeof(HciLeReadRemoteFeaturesCompleteEventParam))) {
130 return;
131 }
132
133 HciLeReadRemoteFeaturesCompleteEventParam *eventParam = (HciLeReadRemoteFeaturesCompleteEventParam *)param;
134
135 HciEventCallbacks *callbacks = NULL;
136 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
137 if (callbacks->leReadRemoteFeaturesComplete != NULL) {
138 callbacks->leReadRemoteFeaturesComplete(eventParam);
139 }
140 HCI_FOREACH_EVT_CALLBACKS_END;
141 }
142
HciEventOnLeLongTermKeyRequestEvent(const uint8_t * param,size_t length)143 static void HciEventOnLeLongTermKeyRequestEvent(const uint8_t *param, size_t length)
144 {
145 if (param == NULL || (length != sizeof(HciLeLongTermKeyRequestEventParam))) {
146 return;
147 }
148
149 HciLeLongTermKeyRequestEventParam *eventParam = (HciLeLongTermKeyRequestEventParam *)param;
150
151 HciEventCallbacks *callbacks = NULL;
152 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
153 if (callbacks->leLongTermKeyRequest != NULL) {
154 callbacks->leLongTermKeyRequest(eventParam);
155 }
156 HCI_FOREACH_EVT_CALLBACKS_END;
157 }
158
HciEventOnLeRemoteConnectionParameterRequestEvent(const uint8_t * param,size_t length)159 static void HciEventOnLeRemoteConnectionParameterRequestEvent(const uint8_t *param, size_t length)
160 {
161 if (param == NULL || (length != sizeof(HciLeRemoteConnectionParameterRequestEventParam))) {
162 return;
163 }
164
165 HciLeRemoteConnectionParameterRequestEventParam *eventParam =
166 (HciLeRemoteConnectionParameterRequestEventParam *)param;
167
168 HciEventCallbacks *callbacks = NULL;
169 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
170 if (callbacks->leRemoteConnectionParameterRequest != NULL) {
171 callbacks->leRemoteConnectionParameterRequest(eventParam);
172 }
173 HCI_FOREACH_EVT_CALLBACKS_END;
174 }
175
HciEventOnLeReadLocalP256PublicKeyCompleteEvent(const uint8_t * param,size_t length)176 static void HciEventOnLeReadLocalP256PublicKeyCompleteEvent(const uint8_t *param, size_t length)
177 {
178 if (param == NULL || (length != sizeof(HciLeReadLocalP256PublicKeyCompleteEventParam))) {
179 return;
180 }
181
182 HciLeReadLocalP256PublicKeyCompleteEventParam *eventParam = (HciLeReadLocalP256PublicKeyCompleteEventParam *)param;
183
184 HciEventCallbacks *callbacks = NULL;
185 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
186 if (callbacks->leReadLocalP256PublicKeyComplete != NULL) {
187 callbacks->leReadLocalP256PublicKeyComplete(eventParam);
188 }
189 HCI_FOREACH_EVT_CALLBACKS_END;
190 }
191
HciEventOnLeGenerateDHKeyCompleteEvent(const uint8_t * param,size_t length)192 static void HciEventOnLeGenerateDHKeyCompleteEvent(const uint8_t *param, size_t length)
193 {
194 if (param == NULL || (length != sizeof(HciLeGenerateDHKeyCompleteEventParam))) {
195 return;
196 }
197
198 HciLeGenerateDHKeyCompleteEventParam *eventParam = (HciLeGenerateDHKeyCompleteEventParam *)param;
199
200 HciEventCallbacks *callbacks = NULL;
201 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
202 if (callbacks->leGenerateDHKeyComplete != NULL) {
203 callbacks->leGenerateDHKeyComplete(eventParam);
204 }
205 HCI_FOREACH_EVT_CALLBACKS_END;
206 }
207
HciEventOnLeEnhancedConnectionCompleteEvent(const uint8_t * param,size_t length)208 static void HciEventOnLeEnhancedConnectionCompleteEvent(const uint8_t *param, size_t length)
209 {
210 if (param == NULL || (length != sizeof(HciLeEnhancedConnectionCompleteEventParam))) {
211 return;
212 }
213
214 HciLeEnhancedConnectionCompleteEventParam *eventParam = (HciLeEnhancedConnectionCompleteEventParam *)param;
215
216 if (eventParam->status == HCI_SUCCESS) {
217 HciAclOnConnectionComplete(eventParam->connectionHandle, TRANSPORT_LE);
218 }
219
220 HciEventCallbacks *callbacks = NULL;
221 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
222 if (callbacks->leEnhancedConnectionComplete != NULL) {
223 callbacks->leEnhancedConnectionComplete(eventParam);
224 }
225 HCI_FOREACH_EVT_CALLBACKS_END;
226 }
227
HciParseLeDirectedAdvertisingReport(HciLeDirectedAdvertisingReport * report,const uint8_t * param,int * offset)228 static void HciParseLeDirectedAdvertisingReport(
229 HciLeDirectedAdvertisingReport *report, const uint8_t *param, int *offset)
230 {
231 report->eventType = param[*offset];
232 *offset += sizeof(uint8_t);
233
234 report->addressType = param[*offset];
235 *offset += sizeof(uint8_t);
236
237 if (memcpy_s(report->address.raw, BT_ADDRESS_SIZE, param + *offset, BT_ADDRESS_SIZE) != EOK) {
238 return;
239 }
240 *offset += BT_ADDRESS_SIZE;
241
242 report->directAddressType = param[*offset];
243 *offset += sizeof(uint8_t);
244
245 (void)memcpy_s(report->directAddress.raw, BT_ADDRESS_SIZE, param + *offset, BT_ADDRESS_SIZE);
246 *offset += BT_ADDRESS_SIZE;
247
248 report->rssi = param[*offset];
249 *offset += sizeof(uint8_t);
250 }
251
HciEventOnLeDirectedAdvertisingReportCompleteEvent(const uint8_t * param,size_t length)252 static void HciEventOnLeDirectedAdvertisingReportCompleteEvent(const uint8_t *param, size_t length)
253 {
254 if (param == NULL || length <= 1) {
255 return;
256 }
257
258 int offset = 0;
259 HciLeDirectedAdvertisingReportEventParam eventParam = {
260 .numReports = param[offset],
261 .reports = NULL,
262 };
263
264 if (eventParam.numReports == 0) {
265 return;
266 }
267
268 HciLeDirectedAdvertisingReport *reports =
269 MEM_MALLOC.alloc(sizeof(HciLeDirectedAdvertisingReport) * eventParam.numReports);
270 if (reports != NULL) {
271 for (uint8_t i = 0; i < eventParam.numReports; i++) {
272 HciParseLeDirectedAdvertisingReport(reports + i, param, &offset);
273 }
274
275 eventParam.reports = reports;
276 }
277
278 HciEventCallbacks *callbacks = NULL;
279 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
280 if (callbacks->leDirectedAdvertisingReport != NULL) {
281 callbacks->leDirectedAdvertisingReport(&eventParam);
282 }
283 HCI_FOREACH_EVT_CALLBACKS_END;
284
285 if (reports != NULL) {
286 MEM_MALLOC.free(reports);
287 }
288 }
289
HciEventOnLePHYUpdateCompleteEvent(const uint8_t * param,size_t length)290 static void HciEventOnLePHYUpdateCompleteEvent(const uint8_t *param, size_t length)
291 {
292 if (param == NULL || (length != sizeof(HciLePhyUpdateCompleteEventParam))) {
293 return;
294 }
295
296 HciLePhyUpdateCompleteEventParam *eventParam = (HciLePhyUpdateCompleteEventParam *)param;
297
298 HciEventCallbacks *callbacks = NULL;
299 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
300 if (callbacks->lePhyUpdateComplete != NULL) {
301 callbacks->lePhyUpdateComplete(eventParam);
302 }
303 HCI_FOREACH_EVT_CALLBACKS_END;
304 }
305
HciParseLeExtendedAdvertisingReport(HciLeExtendedAdvertisingReport * report,const uint8_t * param,size_t length,int * offset)306 static bool HciParseLeExtendedAdvertisingReport(
307 HciLeExtendedAdvertisingReport *report, const uint8_t *param, size_t length, int *offset)
308 {
309 const size_t EXT_ADV_COMMON_REPORT_SIZE = 24; // A extended advertising report size except 'Data' field.
310 if (*offset + EXT_ADV_COMMON_REPORT_SIZE > length) {
311 LOG_ERROR("%{public}s: Error length, offset(%{public}d), length(%{public}zu)",
312 __FUNCTION__, *offset, length);
313 return false;
314 }
315
316 report->eventType = param[*offset];
317 *offset += sizeof(uint16_t);
318
319 report->addressType = param[*offset];
320 *offset += sizeof(uint8_t);
321
322 if (memcpy_s(report->address.raw, BT_ADDRESS_SIZE, param + *offset, BT_ADDRESS_SIZE) != EOK) {
323 return false;
324 }
325 *offset += BT_ADDRESS_SIZE;
326
327 report->primaryPHY = param[*offset];
328 *offset += sizeof(uint8_t);
329
330 report->secondaryPHY = param[*offset];
331 *offset += sizeof(uint8_t);
332
333 report->advertisingSID = param[*offset];
334 *offset += sizeof(uint8_t);
335
336 report->txPower = param[*offset];
337 *offset += sizeof(uint8_t);
338
339 report->rssi = param[*offset];
340 *offset += sizeof(uint8_t);
341
342 report->periodicAdvertisingInterval = param[*offset];
343 *offset += sizeof(uint16_t);
344
345 report->directAddressType = param[*offset];
346 *offset += sizeof(uint8_t);
347
348 if (memcpy_s(report->directAddress.raw, BT_ADDRESS_SIZE, param + *offset, BT_ADDRESS_SIZE) != EOK) {
349 return false;
350 }
351 *offset += BT_ADDRESS_SIZE;
352
353 report->dataLength = param[*offset];
354 *offset += sizeof(uint8_t);
355
356 if (*offset + report->dataLength > length) {
357 LOG_ERROR("%{public}s: Error data length, offset(%{public}d), dataLength(%{public}u), "
358 "length(%{public}zu)", __FUNCTION__, *offset, report->dataLength, length);
359 return false;
360 }
361 report->data = (uint8_t *)(param + *offset);
362 *offset += report->dataLength;
363 return true;
364 }
365
HciEventOnLeExtendedAdvertisingReportEvent(const uint8_t * param,size_t length)366 static void HciEventOnLeExtendedAdvertisingReportEvent(const uint8_t *param, size_t length)
367 {
368 if (param == NULL || length <= 1) {
369 return;
370 }
371
372 int offset = 0;
373 HciLeExtendedAdvertisingReportEventParam eventParam = {
374 .numReports = param[offset],
375 .reports = NULL,
376 };
377 offset += sizeof(uint8_t);
378
379 if (eventParam.numReports == 0) {
380 return;
381 }
382
383 HciLeExtendedAdvertisingReport *reports =
384 MEM_MALLOC.alloc(sizeof(HciLeExtendedAdvertisingReport) * eventParam.numReports);
385 if (reports != NULL) {
386 for (uint8_t i = 0; i < eventParam.numReports; i++) {
387 bool ret = HciParseLeExtendedAdvertisingReport(reports + i, param, length, &offset);
388 if (!ret) {
389 LOG_ERROR("HciParseLeExtendedAdvertisingReport failed");
390 MEM_MALLOC.free(reports);
391 return;
392 }
393 }
394
395 eventParam.reports = reports;
396 } else {
397 return;
398 }
399
400 HciEventCallbacks *callbacks = NULL;
401 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
402 if (callbacks->leExtendedAdvertisingReport != NULL) {
403 callbacks->leExtendedAdvertisingReport(&eventParam);
404 }
405 HCI_FOREACH_EVT_CALLBACKS_END;
406
407 MEM_MALLOC.free(reports);
408 }
409
HciEventOnLeChannelSelectionAlgorithmEvent(const uint8_t * param,size_t length)410 static void HciEventOnLeChannelSelectionAlgorithmEvent(const uint8_t *param, size_t length)
411 {
412 if (param == NULL || (length != sizeof(HciLeChannelSelectionAlgorithmEventParam))) {
413 return;
414 }
415
416 HciLeChannelSelectionAlgorithmEventParam *eventParam = (HciLeChannelSelectionAlgorithmEventParam *)param;
417
418 HciEventCallbacks *callbacks = NULL;
419 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
420 if (callbacks->leChannelSelectionAlgorithm != NULL) {
421 callbacks->leChannelSelectionAlgorithm(eventParam);
422 }
423 HCI_FOREACH_EVT_CALLBACKS_END;
424 }
425
HciEventOnLeScanTimeoutEvent(const uint8_t * param,size_t length)426 static void HciEventOnLeScanTimeoutEvent(const uint8_t *param, size_t length)
427 {
428 HciEventCallbacks *callbacks = NULL;
429 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
430 if (callbacks->leScanTimeoutComplete != NULL) {
431 callbacks->leScanTimeoutComplete();
432 }
433 HCI_FOREACH_EVT_CALLBACKS_END;
434 }
435
HciEventOnLeAdvertisingSetTerminatedEvent(const uint8_t * param,size_t length)436 static void HciEventOnLeAdvertisingSetTerminatedEvent(const uint8_t *param, size_t length)
437 {
438 if (param == NULL || (length != sizeof(HciLeAdvertisingSetTerminatedEventParam))) {
439 return;
440 }
441
442 HciLeAdvertisingSetTerminatedEventParam *eventParam = (HciLeAdvertisingSetTerminatedEventParam *)param;
443
444 HciEventCallbacks *callbacks = NULL;
445 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
446 if (callbacks->leAdvertisingSetTerminated != NULL) {
447 callbacks->leAdvertisingSetTerminated(eventParam);
448 }
449 HCI_FOREACH_EVT_CALLBACKS_END;
450 }
451
HciEventOnLeScanRequestReceivedEvent(const uint8_t * param,size_t length)452 static void HciEventOnLeScanRequestReceivedEvent(const uint8_t *param, size_t length)
453 {
454 if (param == NULL || (length != sizeof(HciLeScanRequestReceivedEventParam))) {
455 return;
456 }
457
458 HciLeScanRequestReceivedEventParam *eventParam = (HciLeScanRequestReceivedEventParam *)param;
459
460 HciEventCallbacks *callbacks = NULL;
461 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
462 if (callbacks->leScanRequestReceived != NULL) {
463 callbacks->leScanRequestReceived(eventParam);
464 }
465 HCI_FOREACH_EVT_CALLBACKS_END;
466 }
467
HciEventOnLEDataLengthChangeEvent(const uint8_t * param,size_t length)468 static void HciEventOnLEDataLengthChangeEvent(const uint8_t *param, size_t length)
469 {
470 if (param == NULL || (length != sizeof(HciLeDataLengthChangeEventParam))) {
471 return;
472 }
473
474 HciLeDataLengthChangeEventParam *eventParam = (HciLeDataLengthChangeEventParam *)param;
475
476 HciEventCallbacks *callbacks = NULL;
477 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
478 if (callbacks->leDataLengthChange != NULL) {
479 callbacks->leDataLengthChange(eventParam);
480 }
481 HCI_FOREACH_EVT_CALLBACKS_END;
482 }
483
HciEventOnLEPeriodicAdvertisingSyncEstablishedEvent(const uint8_t * param,size_t length)484 static void HciEventOnLEPeriodicAdvertisingSyncEstablishedEvent(const uint8_t *param, size_t length)
485 {
486 if (param == NULL || (length != sizeof(HciLePeriodicAdvertisingSyncEstablishedEventParam))) {
487 return;
488 }
489
490 HciLePeriodicAdvertisingSyncEstablishedEventParam *eventParam =
491 (HciLePeriodicAdvertisingSyncEstablishedEventParam *)param;
492
493 HciEventCallbacks *callbacks = NULL;
494 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
495 if (callbacks->lePeriodicAdvertisingSyncEstablished != NULL) {
496 callbacks->lePeriodicAdvertisingSyncEstablished(eventParam);
497 }
498 HCI_FOREACH_EVT_CALLBACKS_END;
499 }
500
HciEventOnLEPeriodicAdvertisingReportEvent(const uint8_t * param,size_t length)501 static void HciEventOnLEPeriodicAdvertisingReportEvent(const uint8_t *param, size_t length)
502 {
503 if (param == NULL || (length != sizeof(HciLePeriodicAdvertisingReportEventParam))) {
504 return;
505 }
506
507 HciLePeriodicAdvertisingReportEventParam *eventParam = (HciLePeriodicAdvertisingReportEventParam *)param;
508
509 HciEventCallbacks *callbacks = NULL;
510 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
511 if (callbacks->lePeriodicAdvertisingReport != NULL) {
512 callbacks->lePeriodicAdvertisingReport(eventParam);
513 }
514 HCI_FOREACH_EVT_CALLBACKS_END;
515 }
516
HciEventOnLEPeriodicAdvertisingSyncLostEvent(const uint8_t * param,size_t length)517 static void HciEventOnLEPeriodicAdvertisingSyncLostEvent(const uint8_t *param, size_t length)
518 {
519 if (param == NULL || (length != sizeof(HciLePeriodicAdvertisingSyncLostEventParam))) {
520 return;
521 }
522
523 HciLePeriodicAdvertisingSyncLostEventParam *eventParam = (HciLePeriodicAdvertisingSyncLostEventParam *)param;
524
525 HciEventCallbacks *callbacks = NULL;
526 HCI_FOREACH_EVT_CALLBACKS_START(callbacks);
527 if (callbacks->lePeriodicAdvertisingSyncLost != NULL) {
528 callbacks->lePeriodicAdvertisingSyncLost(eventParam);
529 }
530 HCI_FOREACH_EVT_CALLBACKS_END;
531 }
532
533 static HciLeEventFunc g_leEventMap[] = {
534 NULL, // 0x00
535 HciEventOnLeConnectionCompleteEvent, // 0x01
536 HciEventOnLeAdvertisingReportEvent, // 0x02
537 HciEventOnLeConnectionUpdateCompleteEvent, // 0x03
538 HciEventOnLeReadRemoteFeaturesCompleteEvent, // 0x04
539 HciEventOnLeLongTermKeyRequestEvent, // 0x05
540 HciEventOnLeRemoteConnectionParameterRequestEvent, // 0x06
541 HciEventOnLEDataLengthChangeEvent, // 0x07
542 HciEventOnLeReadLocalP256PublicKeyCompleteEvent, // 0x08
543 HciEventOnLeGenerateDHKeyCompleteEvent, // 0x09
544 HciEventOnLeEnhancedConnectionCompleteEvent, // 0x0A
545 HciEventOnLeDirectedAdvertisingReportCompleteEvent, // 0x0B
546 HciEventOnLePHYUpdateCompleteEvent, // 0x0C
547 HciEventOnLeExtendedAdvertisingReportEvent, // 0x0D
548 HciEventOnLEPeriodicAdvertisingSyncEstablishedEvent, // 0x0E
549 HciEventOnLEPeriodicAdvertisingReportEvent, // 0x0F
550 HciEventOnLEPeriodicAdvertisingSyncLostEvent, // 0x10
551 HciEventOnLeScanTimeoutEvent, // 0x11
552 HciEventOnLeAdvertisingSetTerminatedEvent, // 0x12
553 HciEventOnLeScanRequestReceivedEvent, // 0x13
554 HciEventOnLeChannelSelectionAlgorithmEvent, // 0x14
555 };
556
557 #define LESUBEVENTCODE_MAX 0x14
558
HciEventOnLeMetaEvent(Packet * packet)559 void HciEventOnLeMetaEvent(Packet *packet)
560 {
561 Buffer *payloadBuffer = PacketContinuousPayload(packet);
562 if (payloadBuffer == NULL) {
563 return;
564 }
565 uint8_t *buf = (uint8_t *)BufferPtr(payloadBuffer);
566 if (buf == NULL) {
567 return;
568 }
569 size_t length = BufferGetSize(payloadBuffer);
570 if (length < 1) {
571 return;
572 }
573
574 if (buf[0] > LESUBEVENTCODE_MAX) {
575 return;
576 }
577
578 HciLeEventFunc func = g_leEventMap[buf[0]];
579 if (func != NULL) {
580 if (length > 1) {
581 func(buf + 1, length - 1);
582 } else {
583 func(NULL, 0);
584 }
585 }
586 }
587