1
6
7
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
36
37
38
39
40
41
42
43
44
46
48
50
52
54
56
58
60
62
64
66
68
70
72
74
76
78
80
82
84
86
88
90
92
94
96
98
100
102
104
106
108
110
112
114
116
118
120
122
124
126
128
130
132
134
136
138
140
142
144
146
148
150
152
154
156
158
160
162
164
166
168
170
172
174
176
178
180
182
184
186
187
188
189
190
191
192
196
197
201
202
210
211
220
221
222
223
224
225
226
227
228
229
230
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
277
278
279
280
284
285
286
287
288
289
290
291
292
293
294
295
299
300
306
307
308
309
328
329
330
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
363
364
367
368
373
374
379
380
385
386
387
397
398
399
400
401
402
403
404
409
410
411
412
413
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
444
445
446
447
458
471
472
473
474
475
476
477
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
506
507
508
509
510
511
512
517
518
523
524
525
529
530
531
532
533
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
592
593
594
595
596
597
598
599
600
601
602
609
610
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
633
634
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
694
695
696
697
698
704
705
706
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
736
737
741
742
743
744
745
758
759
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
789
790
794
795
796
803
804
805
806
807
808
809
810
811
812
813
814
815
816
821
822
823
824
825
827
828
832
833
834
839
840
843
844
845
852
853
854
858
859
860
864
865
866
867
868
869
870
871
872
873
874
875
876
877
884
885
886
887
888
889
893
894
897
898
899
900
901
902
903
904
905
906
907
908
909
910
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
951
952
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
975
976
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1019
1020
1024
1025
1030
1031
1036
1037
1042
1043
1044
1045
1046
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1071
1072
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1103
1104
1105
1106
1107
1108
1112
1113
1117
1118
1119
1120
1123
1124
1128
1129
1136
1137
1138
1139
1140
1144
1145
1146
1150
1151
1152
1153
1154
1155
1156
1157
1161
1162
1166
1167
1171
1172
1173
1177
1178
1179
1191
1192
1193
1194
1195
1196
1197
1198
1199
1203
1204
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1225
1226
1227
1228
1229
1230
1234
1235
1236
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1393
1394
1395
1399
1400
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1432
1433
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1453
1454
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1476
1477
1478
1479
1480
1481
1482
1483
1484
1488
1489
1495
1496
1497
1498
1499
1500
1501
1502
1503
1507
1508
1509
1510
1511
1512
/* ... */
#include "btm_int.h"
#include "stack/hcimsgs.h"
#include "osi/allocator.h"
#include "device/controller.h"
#include <string.h>
#include "l2c_int.h"6 includes
#if (BLE_50_FEATURE_SUPPORT == TRUE)
#define SET_BIT(t, n) (t |= 1UL << (n))
tBTM_BLE_EXTENDED_CB extend_adv_cb;
tBTM_BLE_5_HCI_CBACK ble_5_hci_cb;
#define INVALID_VALUE 0XFF
extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda);
extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda);
extern void BTM_BleSetStaticAddr(BD_ADDR rand_addr);
extern uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params);
static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data);
typedef struct {
uint16_t ter_con_handle;
bool invalid;
bool enabled;
UINT8 instance;
int duration;
int max_events;
uint8_t retry_count;
}{...} tBTM_EXT_ADV_RECORD;
tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0};
extern void btm_ble_inter_set(bool extble_inter);
#if !UC_BT_STACK_NO_LOG
static const char *btm_ble_hci_status_to_str(tHCI_STATUS status)
{
switch(status) {
case HCI_SUCCESS:
return "HCI_SUCCESS";...
case HCI_ERR_ILLEGAL_COMMAND:
return "HCI_ERR_ILLEGAL_COMMAND";...
case HCI_ERR_NO_CONNECTION:
return "HCI_ERR_NO_CONNECTION";...
case HCI_ERR_HW_FAILURE:
return "HCI_ERR_HW_FAILURE";...
case HCI_ERR_PAGE_TIMEOUT:
return "HCI_ERR_PAGE_TIMEOUT";...
case HCI_ERR_AUTH_FAILURE:
return "HCI_ERR_AUTH_FAILURE";...
case HCI_ERR_KEY_MISSING:
return "HCI_ERR_KEY_MISSING";...
case HCI_ERR_MEMORY_FULL:
return "HCI_ERR_MEMORY_FULL";...
case HCI_ERR_CONNECTION_TOUT:
return "HCI_ERR_CONNECTION_TOUT";...
case HCI_ERR_MAX_NUM_OF_CONNECTIONS:
return "HCI_ERR_MAX_NUM_OF_CONNECTIONS";...
case HCI_ERR_MAX_NUM_OF_SCOS:
return "HCI_ERR_MAX_NUM_OF_SCOS";...
case HCI_ERR_CONNECTION_EXISTS:
return "HCI_ERR_CONNECTION_EXISTS";...
case HCI_ERR_COMMAND_DISALLOWED:
return "HCI_ERR_COMMAND_DISALLOWED";...
case HCI_ERR_HOST_REJECT_RESOURCES:
return "HCI_ERR_HOST_REJECT_RESOURCES";...
case HCI_ERR_HOST_REJECT_SECURITY:
return "HCI_ERR_HOST_REJECT_SECURITY";...
case HCI_ERR_HOST_REJECT_DEVICE:
return "HCI_ERR_HOST_REJECT_DEVICE";...
case HCI_ERR_HOST_TIMEOUT:
return "HCI_ERR_HOST_TIMEOUT";...
case HCI_ERR_UNSUPPORTED_VALUE:
return "HCI_ERR_UNSUPPORTED_VALUE";...
case HCI_ERR_ILLEGAL_PARAMETER_FMT:
return "HCI_ERR_ILLEGAL_PARAMETER_FMT";...
case HCI_ERR_PEER_USER:
return "HCI_ERR_PEER_USER";...
case HCI_ERR_PEER_LOW_RESOURCES:
return "HCI_ERR_PEER_LOW_RESOURCES";...
case HCI_ERR_PEER_POWER_OFF:
return "HCI_ERR_PEER_POWER_OFF";...
case HCI_ERR_CONN_CAUSE_LOCAL_HOST:
return "HCI_ERR_CONN_CAUSE_LOCAL_HOST";...
case HCI_ERR_REPEATED_ATTEMPTS:
return "HCI_ERR_REPEATED_ATTEMPTS";...
case HCI_ERR_PAIRING_NOT_ALLOWED:
return "HCI_ERR_PAIRING_NOT_ALLOWED";...
case HCI_ERR_UNKNOWN_LMP_PDU:
return "HCI_ERR_UNKNOWN_LMP_PDU";...
case HCI_ERR_UNSUPPORTED_REM_FEATURE:
return "HCI_ERR_UNSUPPORTED_REM_FEATURE";...
case HCI_ERR_SCO_OFFSET_REJECTED:
return "HCI_ERR_SCO_OFFSET_REJECTED";...
case HCI_ERR_SCO_INTERVAL_REJECTED:
return "HCI_ERR_SCO_INTERVAL_REJECTED";...
case HCI_ERR_SCO_AIR_MODE:
return "HCI_ERR_SCO_AIR_MODE";...
case HCI_ERR_INVALID_LMP_PARAM:
return "HCI_ERR_INVALID_LMP_PARAM";...
case HCI_ERR_UNSPECIFIED:
return "HCI_ERR_UNSPECIFIED";...
case HCI_ERR_UNSUPPORTED_LMP_PARAMETERS:
return "HCI_ERR_UNSUPPORTED_LMP_PARAMETERS";...
case HCI_ERR_ROLE_CHANGE_NOT_ALLOWED:
return "HCI_ERR_ROLE_CHANGE_NOT_ALLOWED";...
case HCI_ERR_LMP_RESPONSE_TIMEOUT:
return "HCI_ERR_LMP_RESPONSE_TIMEOUT";...
case HCI_ERR_LMP_ERR_TRANS_COLLISION:
return "HCI_ERR_LMP_ERR_TRANS_COLLISION";...
case HCI_ERR_LMP_PDU_NOT_ALLOWED:
return "HCI_ERR_LMP_PDU_NOT_ALLOWED";...
case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE:
return "HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE";...
case HCI_ERR_UNIT_KEY_USED:
return "HCI_ERR_UNIT_KEY_USED";...
case HCI_ERR_QOS_NOT_SUPPORTED:
return "HCI_ERR_QOS_NOT_SUPPORTED";...
case HCI_ERR_INSTANT_PASSED:
return "HCI_ERR_INSTANT_PASSED";...
case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED:
return "HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED";...
case HCI_ERR_DIFF_TRANSACTION_COLLISION:
return "HCI_ERR_DIFF_TRANSACTION_COLLISION";...
case HCI_ERR_UNDEFINED_0x2B:
return "HCI_ERR_UNDEFINED_0x2B";...
case HCI_ERR_QOS_UNACCEPTABLE_PARAM:
return "HCI_ERR_QOS_UNACCEPTABLE_PARAM";...
case HCI_ERR_QOS_REJECTED:
return "HCI_ERR_QOS_REJECTED";...
case HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED:
return "HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED";...
case HCI_ERR_INSUFFCIENT_SECURITY:
return "HCI_ERR_INSUFFCIENT_SECURITY";...
case HCI_ERR_PARAM_OUT_OF_RANGE:
return "HCI_ERR_PARAM_OUT_OF_RANGE";...
case HCI_ERR_UNDEFINED_0x31:
return "HCI_ERR_UNDEFINED_0x31";...
case HCI_ERR_ROLE_SWITCH_PENDING:
return "HCI_ERR_ROLE_SWITCH_PENDING";...
case HCI_ERR_UNDEFINED_0x33:
return "HCI_ERR_UNDEFINED_0x33";...
case HCI_ERR_RESERVED_SLOT_VIOLATION:
return "HCI_ERR_RESERVED_SLOT_VIOLATION";...
case HCI_ERR_ROLE_SWITCH_FAILED:
return "HCI_ERR_ROLE_SWITCH_FAILED";...
case HCI_ERR_INQ_RSP_DATA_TOO_LARGE:
return "HCI_ERR_INQ_RSP_DATA_TOO_LARGE";...
case HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED:
return "HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED";...
case HCI_ERR_HOST_BUSY_PAIRING:
return "HCI_ERR_HOST_BUSY_PAIRING";...
case HCI_ERR_REJ_NO_SUITABLE_CHANNEL:
return "HCI_ERR_REJ_NO_SUITABLE_CHANNEL";...
case HCI_ERR_CONTROLLER_BUSY:
return "HCI_ERR_CONTROLLER_BUSY";...
case HCI_ERR_UNACCEPT_CONN_INTERVAL:
return "HCI_ERR_UNACCEPT_CONN_INTERVAL";...
case HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT:
return "HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT";...
case HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE:
return "HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE";...
case HCI_ERR_CONN_FAILED_ESTABLISHMENT:
return "HCI_ERR_CONN_FAILED_ESTABLISHMENT";...
case HCI_ERR_MAC_CONNECTION_FAILED:
return "HCI_ERR_MAC_CONNECTION_FAILED";...
case HCI_ERR_LT_ADDR_ALREADY_IN_USE:
return "HCI_ERR_LT_ADDR_ALREADY_IN_USE";...
case HCI_ERR_LT_ADDR_NOT_ALLOCATED:
return "HCI_ERR_LT_ADDR_NOT_ALLOCATED";...
case HCI_ERR_CLB_NOT_ENABLED:
return "HCI_ERR_CLB_NOT_ENABLED";...
case HCI_ERR_MAX_ERR:
return "HCI_ERR_MAX_ERR";...
case HCI_ERR_ESP_VENDOR_FAIL:
return "HCI_ERR_ESP_VENDOR_FAIL";...
case HCI_HINT_TO_RECREATE_AMP_PHYS_LINK:
return "HCI_HINT_TO_RECREATE_AMP_PHYS_LINK";...
default:
return "Invalid HCI status code.";...
}{...}
return NULL;
}{...}
/* ... */#endif
void btm_ble_extendadvcb_init(void)
{
memset(&extend_adv_cb, 0, sizeof(tBTM_BLE_EXTENDED_CB));
}{...}
void btm_ble_advrecod_init(void)
{
memset(&adv_record[0], 0, sizeof(tBTM_EXT_ADV_RECORD)*MAX_BLE_ADV_INSTANCE);
}{...}
void BTM_BleGapRegisterCallback(tBTM_BLE_5_HCI_CBACK cb)
{
if (cb) {
ble_5_hci_cb = cb;
}{...} else {
BTM_TRACE_ERROR("%s, register fail, the cb function is NULL.", __func__);
}{...}
}{...}
void BTM_ExtBleCallbackTrigger(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_5_GAP_CB_PARAMS *params)
{
if(params && params->status == BTM_SUCCESS) {
btm_ble_inter_set(true);
}{...}
if (ble_5_hci_cb) {
ble_5_hci_cb(event, params);
}{...}
}{...}
tBTM_STATUS BTM_BleReadPhy(BD_ADDR bd_addr, UINT8 *tx_phy, UINT8 *rx_phy)
{
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!tx_phy || !rx_phy || !p_lcb) {
cb_params.read_phy.status = BTM_ILLEGAL_VALUE;
memcpy(cb_params.read_phy.addr, bd_addr, BD_ADDR_LEN);
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params);
}{...}
BTM_TRACE_ERROR("%s, invalid parameters", __func__);
return BTM_ILLEGAL_VALUE;
}{...}
btsnd_hcic_ble_read_phy(p_lcb->handle);
return BTM_SUCCESS;
}{...}
tBTM_STATUS BTM_BleSetPreferDefaultPhy(UINT8 tx_phy_mask, UINT8 rx_phy_mask)
{
UINT8 all_phys = 0;
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_set_prefered_default_phy(all_phys, tx_phy_mask, rx_phy_mask)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.set_perf_def_phy.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleSetPreferPhy(BD_ADDR bd_addr, UINT8 all_phys, UINT8 tx_phy_mask,
UINT8 rx_phy_mask, UINT16 phy_options)
{
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!p_lcb) {
cb_params.status = BTM_ILLEGAL_VALUE;
if (ble_5_hci_cb) {
ble_5_hci_cb(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}{...}
BTM_TRACE_ERROR("%s, invalid parameters", __func__);
return BTM_ILLEGAL_VALUE;
}{...}
if (!btsnd_hcic_ble_set_phy(p_lcb->handle, all_phys, tx_phy_mask, rx_phy_mask, phy_options)) {
cb_params.status = BTM_ILLEGAL_VALUE;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}{...}
return BTM_SUCCESS;
}{...}
tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (instance >= MAX_BLE_ADV_INSTANCE || rand_addr == NULL) {
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
/* ... */
BD_ADDR invalid_rand_addr_a, invalid_rand_addr_b;
memset(invalid_rand_addr_a, 0xff, sizeof(BD_ADDR));
memset(invalid_rand_addr_b, 0x00, sizeof(BD_ADDR));
if((rand_addr[0] & BT_STATIC_RAND_ADDR_MASK) == BT_STATIC_RAND_ADDR_MASK) {
invalid_rand_addr_b[0] = invalid_rand_addr_b[0] | BT_STATIC_RAND_ADDR_MASK;
if (memcmp(invalid_rand_addr_a, rand_addr, BD_ADDR_LEN) == 0
|| memcmp(invalid_rand_addr_b, rand_addr, BD_ADDR_LEN) == 0) {
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
}{...} else if ((rand_addr[0] | BT_NON_RPA_MASK) == BT_NON_RPA_MASK) {
invalid_rand_addr_a[0] = invalid_rand_addr_a[0] & BT_NON_RPA_MASK;
if (memcmp(invalid_rand_addr_a, rand_addr, BD_ADDR_LEN) == 0
|| memcmp(invalid_rand_addr_b, rand_addr, BD_ADDR_LEN) == 0) {
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
}{...} else {
BTM_TRACE_ERROR("%s invalid random address", __func__);
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)",
__func__, btm_ble_hci_status_to_str(err), err);
status = BTM_HCI_ERROR | err;
}{...} else {
if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) {
BTM_BleSetStaticAddr(rand_addr);
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
}{...}
}{...}
end:
cb_params.set_ext_rand_addr.status = status;
cb_params.set_ext_rand_addr.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PARAMS *params)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
bool use_rpa_addr = false;
BD_ADDR rand_addr;
if (instance >= MAX_BLE_ADV_INSTANCE) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid instance %d", __func__, instance);
goto end;
}{...}
if ((status = btm_ble_ext_adv_params_validate(params)) != BTM_SUCCESS) {
BTM_TRACE_ERROR("%s, invalid extend adv params.", __func__);
}{...}
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE) {
extend_adv_cb.inst[instance].connetable = true;
}{...} else {
extend_adv_cb.inst[instance].connetable = false;
}{...}
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE) {
extend_adv_cb.inst[instance].scannable = true;
}{...} else {
extend_adv_cb.inst[instance].scannable = false;
}{...}
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY) {
extend_adv_cb.inst[instance].legacy_pdu = true;
}{...} else {
extend_adv_cb.inst[instance].legacy_pdu = false;
}{...}
#if (CONTROLLER_RPA_LIST_ENABLE == FALSE)
if((params->own_addr_type == BLE_ADDR_PUBLIC_ID || params->own_addr_type == BLE_ADDR_RANDOM_ID) && BTM_GetLocalResolvablePrivateAddr(rand_addr)) {
params->own_addr_type = BLE_ADDR_RANDOM;
use_rpa_addr = true;
}{...} else if(params->own_addr_type == BLE_ADDR_PUBLIC_ID){
params->own_addr_type = BLE_ADDR_PUBLIC;
}{...} else if (params->own_addr_type == BLE_ADDR_RANDOM_ID) {
params->own_addr_type = BLE_ADDR_RANDOM;
}{...}
/* ... */#else
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = params->own_addr_type;
#endif
if ((err = btsnd_hcic_ble_set_ext_adv_params(instance, params->type, params->interval_min, params->interval_max,
params->channel_map, params->own_addr_type, params->peer_addr_type,
params->peer_addr, params->filter_policy, params->tx_power,
params->primary_phy, params->max_skip,
params->secondary_phy, params->sid, params->scan_req_notif)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
goto end;
}{...}
extend_adv_cb.inst[instance].configured = true;
end:
if(use_rpa_addr) {
if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...} else {
BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr);
}{...}
}{...}
cb_params.set_params.status = status;
cb_params.set_params.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, UINT16 len, UINT8 *data)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
UINT16 rem_len = len;
UINT8 operation = 0;
UINT16 data_offset = 0;
if ((status = btm_ble_ext_adv_set_data_validate(instance, len, data)) != BTM_SUCCESS) {
BTM_TRACE_ERROR("%s, invalid extend adv data.", __func__);
goto end;
}{...}
do {
UINT8 send_data_len = (rem_len > BTM_BLE_EXT_ADV_DATA_LEN_MAX) ? BTM_BLE_EXT_ADV_DATA_LEN_MAX : rem_len;
if (len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) {
operation = BTM_BLE_ADV_DATA_OP_COMPLETE;
}{...} else {
if (rem_len == len) {
operation = BTM_BLE_ADV_DATA_OP_FIRST_FRAG;
}{...} else if (rem_len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) {
operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG;
}{...} else {
operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG;
}{...}
}{...}
if (!is_scan_rsp) {
if ((err = btsnd_hcic_ble_set_ext_adv_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetAdvData: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
break;
}{...}
}{...} else {
if ((err = btsnd_hcic_ble_set_ext_adv_scan_rsp_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA SetScanRspData: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
break;
}{...}
}{...}
rem_len -= send_data_len;
data_offset += send_data_len;
}{...} while (rem_len);
end:
if (is_scan_rsp) {
cb_params.scan_rsp_data_set.status = status;
cb_params.scan_rsp_data_set.instance = instance;
}{...} else {
cb_params.adv_data_set.status = status;
cb_params.adv_data_set.instance = instance;
}{...}
BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_adv)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
UINT8 *instance = NULL;
UINT16 *duration = NULL;
UINT8 *max_events = NULL;
if ((!ext_adv || num == 0) && enable) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid parameters", __func__);
goto end;
}{...}
if (num != 0 && ext_adv != NULL) {
instance = osi_malloc(num);
duration = osi_malloc(num*sizeof(UINT16));
max_events = osi_malloc(num*sizeof(UINT8));
if (!instance || !duration || !max_events) {
status = BTM_NO_RESOURCES;
BTM_TRACE_ERROR("%s invalid parameters", __func__);
goto end;
}{...}
for (int i = 0; i < num; i++) {
instance[i] = ext_adv[i].instance;
duration[i] = ext_adv[i].duration;
max_events[i] = ext_adv[i].max_events;
}{...}
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, instance,
duration, max_events)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
status = BTM_HCI_ERROR | err;
}{...}
osi_free(instance);
osi_free(duration);
osi_free(max_events);
}{...} else {
if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, NULL, NULL, NULL)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err);
status = BTM_HCI_ERROR | err;
}{...}
goto end;
}{...}
end:
if (!enable && status == BTM_SUCCESS) {
if(num == 0) {
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++)
{
adv_record[i].invalid = false;
adv_record[i].enabled = false;
adv_record[i].instance = INVALID_VALUE;
adv_record[i].duration = INVALID_VALUE;
adv_record[i].max_events = INVALID_VALUE;
adv_record[i].retry_count = 0;
}{...}
}{...} else {
for (uint8_t i = 0; i < num; i++)
{
uint8_t index = ext_adv[i].instance;
adv_record[index].invalid = false;
adv_record[index].enabled = false;
adv_record[index].instance = INVALID_VALUE;
adv_record[index].duration = INVALID_VALUE;
adv_record[index].max_events = INVALID_VALUE;
adv_record[index].retry_count = 0;
}{...}
}{...}
}{...}
if(enable && status == BTM_SUCCESS) {
for (uint8_t i = 0; i < num; i++)
{
uint8_t index = ext_adv[i].instance;
adv_record[index].invalid = true;
adv_record[index].enabled = true;
adv_record[index].instance = ext_adv[i].instance;
adv_record[index].duration = ext_adv[i].duration;
adv_record[index].max_events = ext_adv[i].max_events;
adv_record[index].retry_count = 0;
}{...}
}{...}
cb_params.adv_start.status = status;
cb_params.adv_start.instance_num = num;
for (uint8_t i = 0; i < num; i++) {
cb_params.adv_start.instance[i] = ext_adv[i].instance;
}{...}
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle)
{
tBTM_BLE_EXT_ADV ext_adv;
uint8_t index = INVALID_VALUE;
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++)
{
if(adv_record[i].ter_con_handle == con_handle) {
index = i;
break;
}{...}
}{...}
if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid)) {
return BTM_WRONG_MODE;
}{...}
adv_record[index].retry_count ++;
BTM_TRACE_DEBUG("remote device did not receive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle);
ext_adv.instance = adv_record[index].instance;
ext_adv.duration = adv_record[index].duration;
ext_adv.max_events = adv_record[index].max_events;
return BTM_BleStartExtAdv(true, 1, &ext_adv);
}{...}
tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (instance >= MAX_BLE_ADV_INSTANCE) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid instance %d", __func__, instance);
goto end;
}{...}
if ((err = btsnd_hcic_ble_remove_adv_set(instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Rm: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...} else {
extend_adv_cb.inst[instance].configured = false;
extend_adv_cb.inst[instance].legacy_pdu = false;
extend_adv_cb.inst[instance].directed = false;
extend_adv_cb.inst[instance].scannable = false;
extend_adv_cb.inst[instance].connetable = false;
}{...}
end:
cb_params.adv_start.status = status;
cb_params.adv_start.instance_num = 1;
cb_params.adv_start.instance[0] = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleExtAdvSetClear(void)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_clear_adv_set()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE EAS Clr: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...} else {
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
extend_adv_cb.inst[i].configured = false;
extend_adv_cb.inst[i].legacy_pdu = false;
extend_adv_cb.inst[i].directed = false;
extend_adv_cb.inst[i].scannable = false;
extend_adv_cb.inst[i].connetable = false;
}{...}
}{...}
cb_params.adv_start.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Params *params)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (instance >= MAX_BLE_ADV_INSTANCE) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid instance %d", __func__, instance);
goto end;
}{...}
if (!extend_adv_cb.inst[instance].configured ||
extend_adv_cb.inst[instance].scannable ||
extend_adv_cb.inst[instance].connetable ||
extend_adv_cb.inst[instance].legacy_pdu) {
BTM_TRACE_ERROR("%s, instance = %d, Before set the periodic adv parameters, please configure the the \
extend adv to nonscannable and nonconnectable first, and it shouldn't include the legacy bit.", __func__, instance);
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min,
params->interval_max, params->properties)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
end:
cb_params.per_adv_set_params.status = status;
cb_params.per_adv_set_params.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data,BOOLEAN only_update_did)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
uint16_t rem_len = len;
UINT8 operation = 0;
UINT16 data_offset = 0;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (only_update_did)
{
len = 0;
data = NULL;
rem_len = 0;
operation = BTM_BLE_ADV_DATA_OP_UNCHANGED_DATA;
}{...}
if ((status = btm_ble_ext_adv_set_data_validate(instance, len, data)) != BTM_SUCCESS) {
BTM_TRACE_ERROR("%s, invalid extend adv data.", __func__);
goto end;
}{...}
do {
UINT8 send_data_len = (rem_len > BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) ? BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX : rem_len;
if (len <= BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) {
if (!only_update_did) {
operation = BTM_BLE_ADV_DATA_OP_COMPLETE;
}{...}
}{...} else {
if (rem_len == len) {
operation = BTM_BLE_ADV_DATA_OP_FIRST_FRAG;
}{...} else if (rem_len <= BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) {
operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG;
}{...} else {
operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG;
}{...}
}{...}
if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
break;
}{...}
rem_len -= send_data_len;
data_offset += send_data_len;
}{...} while(rem_len);
end:
cb_params.per_adv_data_set.status = status;
cb_params.per_adv_data_set.instance = instance;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable)
{
tBTM_STATUS status = BTM_SUCCESS;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (instance >= MAX_BLE_ADV_INSTANCE) {
BTM_TRACE_ERROR("%s, invalid instance %d", __func__, instance);
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
if ((err = btsnd_hcic_ble_periodic_adv_enable(enable, instance)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA En=%d: cmd err=0x%x", enable, err);
status = BTM_HCI_ERROR | err;
}{...}
end:
if (enable) {
cb_params.per_adv_start.status = status;
cb_params.per_adv_start.instance = instance;
}{...} else {
cb_params.per_adv_stop.status = status;
cb_params.per_adv_stop.instance = instance;
}{...}
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params)
{
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s, the parameter is NULL.", __func__);
goto end;
}{...}
if ((params->sync_timeout < 0x0a || params->sync_timeout > 0x4000)
|| (params->filter_policy > 0x01)
#if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
|| (params->reports_disabled > 0x01)
|| (params->filter_duplicates > 0x01)/* ... */
#endif
/* ... */
|| (params->filter_policy == 0 && params->addr_type > 0x01)
|| (params->filter_policy == 0 && params->sid > 0xf)
|| (params->skip > 0x01F3)) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s, The sync parameters is invalid.", __func__);
goto end;
}{...}
uint8_t option = 0x00;
if (params->filter_policy) {
SET_BIT(option, 0);
}{...}
#if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH)
if (params->reports_disabled) {
SET_BIT(option, 1);
}{...}
if (params->filter_duplicates) {
SET_BIT(option, 2);
}{...}
/* ... */ #endif
if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type,
params->addr, params->sync_timeout, 0)) {
BTM_TRACE_ERROR("LE PA CreateSync cmd failed");
status = BTM_ILLEGAL_VALUE;
}{...}
end:
if(status != BTM_SUCCESS) {
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
}{...}
return status;
}{...}
void btm_set_phy_callback(UINT8 status)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params);
}{...}
void btm_create_sync_callback(UINT8 status)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT, &cb_params);
}{...}
void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy)
{
tBTM_STATUS status = BTM_SUCCESS;
tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(conn_handle);
if(hci_status != HCI_SUCCESS) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s error status %d", __func__, hci_status);
}{...}
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if(p_lcb) {
memcpy(cb_params.read_phy.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
}{...}
cb_params.read_phy.status = status;
cb_params.read_phy.tx_phy = tx_phy;
cb_params.read_phy.rx_phy = rx_phy;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT, &cb_params);
}{...}
tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_CANCEL_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvSyncTerm(UINT16 sync_handle)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (( err = btsnd_hcic_ble_periodic_adv_term_sync(sync_handle)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA SyncTerm: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_TERMINATE_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, BD_ADDR addr, UINT16 sid)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (addr_type > BLE_ADDR_TYPE_MAX) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid addr_type %d", __func__, addr_type);
goto end;
}{...}
if ((err = btsnd_hcic_ble_add_dev_to_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA AddDevToList: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_ADD_DEV_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, BD_ADDR addr, UINT16 sid)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (addr_type > BLE_ADDR_TYPE_MAX) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid addr_type %d", __func__, addr_type);
goto end;
}{...}
if ((err = btsnd_hcic_ble_rm_dev_from_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA RmDevFromList: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_REMOVE_DEV_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BlePeriodicAdvClearDev(void)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_clear_periodic_adv_list()) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE PA ClrDev: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_CLEAR_DEV_COMPLETE_EVT, &cb_params);
return status;
}{...}
tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params)
{
UINT8 phy_mask = 0;
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tHCI_EXT_SCAN_PARAMS hci_params[2];
int phy_count = 0;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid parameters", __func__);
goto end;
}{...}
if (params->own_addr_type > BLE_ADDR_TYPE_MAX) {
status = BTM_ILLEGAL_VALUE;
goto end;
}{...}
if (params->cfg_mask & BTM_BLE_GAP_EXT_SCAN_UNCODE_MASK) {
phy_mask |= 0x01;
memcpy(&hci_params[phy_count], ¶ms->uncoded_cfg, sizeof(tHCI_EXT_SCAN_PARAMS));
phy_count++;
}{...}
if (params->cfg_mask & BTM_BLE_GAP_EXT_SCAN_CODE_MASK) {
phy_mask |= 0x04;
memcpy(&hci_params[phy_count], ¶ms->coded_cfg, sizeof(tHCI_EXT_SCAN_PARAMS));
phy_count++;
}{...}
if (BTM_BleUpdateOwnType(¶ms->own_addr_type, NULL) != 0 ) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("LE UpdateOwnType err");
goto end;
}{...}
extend_adv_cb.scan_duplicate = params->scan_duplicate;
if ((err = btsnd_hcic_ble_set_ext_scan_params(params->own_addr_type, params->filter_policy, phy_mask, phy_count,
hci_params)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES SetParams: cmd err=0x%x", err);
status = BTM_HCI_ERROR | err;
}{...}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_EXT_SCAN_PARAMS_COMPLETE_EVT, &cb_params);
return cb_params.status;
}{...}
tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
tBTM_STATUS status = BTM_SUCCESS;
if (extend_adv_cb.scan_duplicate > 0x03) {
status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s invalid scan_duplicate %d", __func__, extend_adv_cb.scan_duplicate);
goto end;
}{...}
if ((err = btsnd_hcic_ble_ext_scan_enable(enable, extend_adv_cb.scan_duplicate, duration, period)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("LE ES En=%d: cmd err=0x%x", enable, err);
status = BTM_HCI_ERROR | err;
}{...}
end:
cb_params.status = status;
BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT, &cb_params);
return status;
}{...}
void BTM_BleSetPreferExtenedConnParams (BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params)
{
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bd_addr);
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (p_dev_rec) {
if (params) {
memcpy(&p_dev_rec->ext_conn_params, params, sizeof(tBTM_EXT_CONN_PARAMS));
}{...} else {
BTM_TRACE_ERROR("Invalid Extended connection parameters");
status = BTM_ILLEGAL_VALUE;
}{...}
}{...} else {
BTM_TRACE_ERROR("Unknown Device, setting rejected");
status = BTM_UNKNOWN_ADDR;
}{...}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PREFER_EXT_CONN_PARAMS_SET_COMPLETE_EVT, &cb_params);
}{...}
void btm_ble_extended_init(void)
{
}{...}
void btm_ble_extended_cleanup(void)
{
}{...}
static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS *params)
{
if (!params) {
return BTM_ILLEGAL_VALUE;
}{...}
if (params->own_addr_type > BLE_ADDR_TYPE_MAX) {
BTM_TRACE_ERROR("%s, invalid own address type, line %d, addr type %d", __func__, __LINE__, params->own_addr_type);
return BTM_ILLEGAL_VALUE;
}{...}
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY) {
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_INCLUDE_TX_PWR) {
BTM_TRACE_ERROR("%s, The Legacy adv can't include tx power bit, line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
}{...}
if (!(params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY)) {
if ((params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_CONNECTABLE) &&
(params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_SCANNABLE)) {
BTM_TRACE_ERROR("%s, For the Extend adv, the properties can't be connectable and scannable at the same time, line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
if (params->type & BTM_BLE_GAP_SET_EXT_ADV_PROP_HD_DIRECTED) {
BTM_TRACE_ERROR("%s, HD directed advertising allowed only for legacy PDUs. line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
}{...}
return BTM_SUCCESS;
}{...}
static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data)
{
if (data == NULL && len > 0) {
BTM_TRACE_ERROR("%s, the extend adv data is NULL. line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
if (instance >= MAX_BLE_ADV_INSTANCE) {
BTM_TRACE_ERROR("%s, adv instance is %d, Exceeded the maximum. line %d", __func__, instance, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
if (!extend_adv_cb.inst[instance].configured) {
BTM_TRACE_ERROR("%s, The extend adv hasn't configured, please use the set_ext_adv_params API to set the ext adv parameters first. line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
if (extend_adv_cb.inst[instance].legacy_pdu && extend_adv_cb.inst[instance].directed) {
BTM_TRACE_ERROR("%s, Not allowed with the direted advertising for legacy. line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
if (extend_adv_cb.inst[instance].legacy_pdu) {
if (len > 31) {
BTM_TRACE_ERROR("%s, for the legacy adv, the adv data length can't exceed 31. line %d", __func__, __LINE__);
return BTM_ILLEGAL_VALUE;
}{...}
}{...} else {
if (len > controller_get_interface()->ble_get_ext_adv_data_max_len()) {
BTM_TRACE_ERROR("%s, The adv data len(%d) is longer then the controller adv max len(%d)",
__func__, len, controller_get_interface()->ble_get_ext_adv_data_max_len());
return BTM_ILLEGAL_VALUE;
}{...}
}{...}
return BTM_SUCCESS;
}{...}
void btm_ble_update_phy_evt(tBTM_BLE_UPDATE_PHY *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(params->conn_idx);
if(!p_lcb) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
cb_params.phy_update.status = params->status;
cb_params.phy_update.tx_phy = params->tx_phy;
cb_params.phy_update.rx_phy = params->rx_phy;
memcpy(cb_params.phy_update.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PHY_UPDATE_COMPLETE_EVT, &cb_params);
return;
}{...}
void btm_ble_scan_timeout_evt(void)
{
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_TIMEOUT_EVT, NULL);
}{...}
void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
if(params->completed_event == 0x00) {
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
}{...} else {
adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE;
adv_record[params->adv_handle].invalid = false;
}{...}
adv_record[params->adv_handle].enabled = false;
memcpy(&cb_params.adv_term, params, sizeof(tBTM_BLE_ADV_TERMINAT));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_ADV_TERMINATED_EVT, &cb_params);
return;
}{...}
void btm_ble_ext_adv_report_evt(tBTM_BLE_EXT_ADV_REPORT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.ext_adv_report, params, sizeof(tBTM_BLE_EXT_ADV_REPORT));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_REPORT_EVT, &cb_params);
return;
}{...}
void btm_ble_scan_req_received_evt(tBTM_BLE_SCAN_REQ_RECEIVED *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.scan_req, params, sizeof(tBTM_BLE_SCAN_REQ_RECEIVED));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SCAN_REQ_RECEIVED_EVT, &cb_params);
return;
}{...}
void btm_ble_channel_select_algorithm_evt(tBTM_BLE_CHANNEL_SEL_ALG *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.channel_sel, params, sizeof(tBTM_BLE_CHANNEL_SEL_ALG));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_CHANNEL_SELETE_ALGORITHM_EVT, &cb_params);
return;
}{...}
void btm_ble_periodic_adv_report_evt(tBTM_PERIOD_ADV_REPORT *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.period_adv_report, params, sizeof(tBTM_PERIOD_ADV_REPORT));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT, &cb_params);
return;
}{...}
void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.sync_lost, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_LOST));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT, &cb_params);
return;
}{...}
void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.sync_estab, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB));
BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT, &cb_params);
return;
}{...}
uint8_t btm_ble_ext_adv_active_count(void)
{
uint8_t count = 0;
for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) {
if (adv_record[i].enabled == true) {
count++;
}{...}
}{...}
return count;
}{...}
/* ... */
#endif
#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
UINT8 evt = BTM_BLE_5_GAP_UNKNOWN_EVT;
tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(conn_handle);
switch (op_code) {
case HCI_BLE_PERIOD_ADV_SYNC_TRANS:
evt = BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT;
break;...
case HCI_BLE_PERIOD_ADV_SET_INFO_TRANS:
evt = BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT;
break;...
case HCI_BLE_SET_PAST_PARAMS:
evt = BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT;
break;...
default:
return;...
}{...}
cb_params.per_adv_sync_trans.status = BTM_SUCCESS;
if(hci_status != HCI_SUCCESS) {
cb_params.per_adv_sync_trans.status = BTM_ILLEGAL_VALUE;
BTM_TRACE_ERROR("%s error status %d", __func__, hci_status);
}{...}
if(p_lcb) {
memcpy(cb_params.per_adv_sync_trans.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
}{...}
BTM_ExtBleCallbackTrigger(evt, &cb_params);
}{...}
void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable)
{
tHCI_STATUS err = HCI_SUCCESS;
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.status = status;
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, &cb_params);
}{...}
void BTM_BlePeriodicAdvSyncTrans(BD_ADDR bd_addr, UINT16 service_data, UINT16 sync_handle)
{
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
if (!p_lcb) {
BTM_TRACE_ERROR("%s, invalid parameters", __func__);
status = BTM_ILLEGAL_VALUE;
}{...}
if (status != BTM_SUCCESS) {
cb_params.per_adv_sync_trans.status = status;
memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR));
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, &cb_params);
return;
}{...}
btsnd_hcic_ble_periodic_adv_sync_trans(p_lcb->handle, service_data, sync_handle);
}{...}
void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle)
{
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
if (!p_lcb) {
BTM_TRACE_ERROR("%s, invalid parameters", __func__);
status = BTM_ILLEGAL_VALUE;
}{...}
if (status != BTM_SUCCESS) {
cb_params.per_adv_sync_trans.status = status;
memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR));
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, &cb_params);
return;
}{...}
btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle);
}{...}
void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type)
{
tBTM_STATUS status = BTM_SUCCESS;
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (bdaddr_is_empty((bt_bdaddr_t *)bd_addr)) {
tHCI_STATUS err = HCI_SUCCESS;
if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) {
BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err);
status = BTM_HCI_ERROR | err;
}{...}
cb_params.set_past_params.status = status;
memset(cb_params.set_past_params.addr, 0, sizeof(BD_ADDR));
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params);
return;
}{...}
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE);
if (!p_lcb) {
BTM_TRACE_ERROR("%s, invalid parameters", __func__);
status = BTM_ILLEGAL_VALUE;
}{...}
if (status != BTM_SUCCESS) {
cb_params.set_past_params.status = status;
memcpy(cb_params.set_past_params.addr, bd_addr, sizeof(BD_ADDR));
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params);
return;
}{...}
btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type);
}{...}
void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params)
{
tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0};
if (!params) {
BTM_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}{...}
memcpy(&cb_params.past_recv, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV));
BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, &cb_params);
}{...}
/* ... */#endif