1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
36
37
44
45
48
49
51
52
56
57
58
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
129
130
131
132
133
134
135
136
137
141
142
143
144
145
146
147
148
149
152
153
154
155
160
165
170
175
177
178
179
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
273
278
279
280
281
282
283
284
285
288
289
290
293
294
295
296
297
300
301
302
303
304
305
306
307
308
309
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
397
398
399
400
401
402
403
404
405
406
407
408
409
417
418
419
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
454
455
456
457
458
459
460
461
462
463
464
465
466
481
482
483
484
485
486
487
488
489
490
491
492
493
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
536
537
541
542
543
544
545
546
551
552
553
554
555
556
563
564
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
598
599
600
601
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
648
649
650
651
652
653
656
657
658
659
660
661
662
663
664
665
666
667
668
669
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
699
700
701
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
745
746
747
751
752
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
834
838
839
843
844
848
849
850
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
882
883
884
885
/* ... */
#include <string.h>
#include "common/bt_target.h"
#include "device/controller.h"
#if (BLE_INCLUDED == TRUE)
#include "stack/bt_types.h"
#include "stack/hcimsgs.h"
#include "stack/btu.h"
#include "btm_int.h"
#include "stack/hcidefs.h"
#include "stack/btm_ble_api.h"6 includes
/* ... */
#define BTM_BLE_MULTI_ADV_ENB_LEN 3
#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F6 defines
/* ... */
#if BTM_DYNAMIC_MEMORY == FALSE
tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q;/* ... */
#else
tBTM_BLE_MULTI_ADV_CB *btm_multi_adv_cb_ptr;
tBTM_BLE_MULTI_ADV_INST_IDX_Q *btm_multi_adv_idx_q_ptr;
#define btm_multi_adv_cb (*btm_multi_adv_cb_ptr)
#define btm_multi_adv_idx_q (*btm_multi_adv_idx_q_ptr)/* ... */
#endif
/* ... */
extern void btm_ble_update_dmt_flag_bits(UINT8 *flag_value,
const UINT16 connect_mode, const UINT16 disc_mode);
/* ... */
void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt)
{
tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
p_op_q->p_inst_id[p_op_q->next_idx] = inst_id;
p_op_q->p_sub_code[p_op_q->next_idx] = (opcode | (cb_evt << 4));
p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
}{ ... }
/* ... */
void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt)
{
tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
*p_inst_id = p_op_q->p_inst_id[p_op_q->pending_idx] & 0x7F;
*p_cb_evt = (p_op_q->p_sub_code[p_op_q->pending_idx] >> 4);
*p_opcode = (p_op_q->p_sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK);
p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
}{ ... }
/* ... */
void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params)
{
UINT8 status, subcode;
UINT8 *p = p_params->p_param_buf, inst_id;
UINT16 len = p_params->param_len;
tBTM_BLE_MULTI_ADV_INST *p_inst ;
UINT8 cb_evt = 0, opcode;
if (len < 2) {
BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback");
return;
}{...}
STREAM_TO_UINT8(status, p);
STREAM_TO_UINT8(subcode, p);
btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt);
BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
if (opcode != subcode || inst_id == 0) {
BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d", subcode, opcode);
return;
}{...}
p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
switch (subcode) {
case BTM_BLE_MULTI_ADV_ENB: {
BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status);
if (HCI_SUCCESS != status && BTM_BLE_MULTI_ADV_ENB_EVT == cb_evt) {
btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
}{...}
break;
}{...}
...
case BTM_BLE_MULTI_ADV_SET_PARAM: {
BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
break;
}{...}
...
case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA: {
BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
break;
}{...}
...
case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA: {
BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
break;
}{...}
...
case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR: {
BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status);
break;
}{...}
...
default:
break;...
}{...}
if (cb_evt != 0 && p_inst->p_cback != NULL) {
(p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status);
}{...}
return;
}{ ... }
/* ... */
tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt)
{
UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp;
UINT8 enb = enable ? 1 : 0;
tBTM_STATUS rt;
pp = param;
memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB);
UINT8_TO_STREAM (pp, enb);
UINT8_TO_STREAM (pp, inst_id);
BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d", enb, inst_id);
if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
BTM_BLE_MULTI_ADV_ENB_LEN,
param,
btm_ble_multi_adv_vsc_cmpl_cback))
== BTM_CMD_STARTED) {
btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt);
}{...}
return rt;
}{ ... }
/* ... */
static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
char btm_ble_map_adv_tx_power(int tx_power_index)
{
if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) {
return (char)btm_ble_tx_power[tx_power_index];
}{...}
return 0;
}{ ... }
/* ... */
tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst,
tBTM_BLE_ADV_PARAMS *p_params,
UINT8 cb_evt)
{
UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp;
tBTM_STATUS rt;
BD_ADDR dummy = {0, 0, 0, 0, 0, 0};
pp = param;
memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
UINT16_TO_STREAM (pp, p_params->adv_int_min);
UINT16_TO_STREAM (pp, p_params->adv_int_max);
UINT8_TO_STREAM (pp, p_params->adv_type);
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM);
BDADDR_TO_STREAM (pp, p_inst->rpa);
}{...} else
#endif
{
UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
BDADDR_TO_STREAM (pp, controller_get_interface()->get_address()->address);
}{...}
BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d",
p_params->adv_int_min, p_params->adv_int_max, p_params->adv_type);
UINT8_TO_STREAM (pp, 0);
BDADDR_TO_STREAM (pp, dummy);
if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP) {
p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
}{...}
UINT8_TO_STREAM (pp, p_params->channel_map);
if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX) {
p_params->adv_filter_policy = AP_SCAN_CONN_ALL;
}{...}
UINT8_TO_STREAM (pp, p_params->adv_filter_policy);
UINT8_TO_STREAM (pp, p_inst->inst_id);
if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX) {
p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX;
}{...}
UINT8_TO_STREAM (pp, btm_ble_map_adv_tx_power(p_params->tx_power));
BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d",
p_params->channel_map, p_params->adv_filter_policy, p_inst->inst_id, p_params->tx_power);
if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
BTM_BLE_MULTI_ADV_SET_PARAM_LEN,
param,
btm_ble_multi_adv_vsc_cmpl_cback))
== BTM_CMD_STARTED) {
p_inst->adv_evt = p_params->adv_type;
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
BTM_BLE_PRIVATE_ADDR_INT);
}{...}
#endif/* ... */
btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt);
}{...}
return rt;
}{ ... }
/* ... */
tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr)
{
UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param;
tBTM_STATUS rt;
BTM_TRACE_EVENT ("%s-BD_ADDR:%02x-%02x-%02x-%02x-%02x-%02x,inst_id:%d",
__FUNCTION__, random_addr[5], random_addr[4], random_addr[3], random_addr[2],
random_addr[1], random_addr[0], p_inst->inst_id);
memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
BDADDR_TO_STREAM(pp, random_addr);
UINT8_TO_STREAM(pp, p_inst->inst_id);
if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN,
param,
btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED) {
btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
BTM_BLE_PRIVATE_ADDR_INT);
btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0);
}{...}
return rt;
}{ ... }
/* ... */
void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p)
{
#if (SMP_INCLUDED == TRUE)
tSMP_ENC output;
UINT8 index = 0;
tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
if (btm_multi_adv_idx_q.front == -1) {
BTM_TRACE_ERROR(" %s can't locate advertise instance", __FUNCTION__);
return;
}{...} else {
index = btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.front];
if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear) {
btm_multi_adv_idx_q.front = -1;
btm_multi_adv_idx_q.rear = -1;
}{...} else {
btm_multi_adv_idx_q.front = (btm_multi_adv_idx_q.front + 1) % BTM_BLE_MULTI_ADV_MAX;
}{...}
}{...}
p_inst = &(btm_multi_adv_cb.p_adv_inst[index]);
BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id);
if (p) {
p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
p_inst->rpa[2] = p->param_buf[0];
p_inst->rpa[1] = p->param_buf[1];
p_inst->rpa[0] = p->param_buf[2];
if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output)) {
BTM_TRACE_DEBUG("generate random address failed");
}{...} else {
p_inst->rpa[5] = output.param_buf[0];
p_inst->rpa[4] = output.param_buf[1];
p_inst->rpa[3] = output.param_buf[2];
}{...}
if (p_inst->inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
p_inst->inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
}{...}
}{...}
/* ... */#endif
}{ ... }
/* ... */
void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst)
{
if (btm_multi_adv_idx_q.front == (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX) {
BTM_TRACE_ERROR("outstanding rand generation exceeded max allowed ");
return;
}{...} else {
if (btm_multi_adv_idx_q.front == -1) {
btm_multi_adv_idx_q.front = 0;
btm_multi_adv_idx_q.rear = 0;
}{...} else {
btm_multi_adv_idx_q.rear = (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX;
}{...}
btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.rear] = p_inst->index;
}{...}
btm_gen_resolvable_private_addr((void *)btm_ble_multi_adv_gen_rpa_cmpl);
}{ ... }
/* ... */
void btm_ble_multi_adv_reenable(UINT8 inst_id)
{
tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
if (TRUE == p_inst->in_use) {
if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT) {
btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0);
}{...} else
{
(p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT, p_inst->inst_id, p_inst->p_ref, 0);
p_inst->in_use = FALSE;
}{...}
}{...}
}{ ... }
/* ... */
void btm_ble_multi_adv_enb_privacy(BOOLEAN enable)
{
UINT8 i;
tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
p_inst->in_use = FALSE;
if (enable) {
btm_ble_multi_adv_configure_rpa (p_inst);
}{...} else {
btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
}{...}
}{...}
}{ ... }
/* ... */
tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
tBTM_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref)
{
UINT8 i;
tBTM_STATUS rt = BTM_NO_RESOURCES;
tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called");
if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
BTM_TRACE_ERROR("Controller does not support Multi ADV");
return BTM_ERR_PROCESSING;
}{...}
if (NULL == p_inst) {
BTM_TRACE_ERROR("Invalid instance in BTM_BleEnableAdvInstance");
return BTM_ERR_PROCESSING;
}{...}
for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
if (FALSE == p_inst->in_use) {
p_inst->in_use = TRUE;
if (p_params) {
rt = btm_ble_multi_adv_set_params(p_inst, p_params, 0);
}{...} else {
rt = BTM_CMD_STARTED;
}{...}
BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d",
p_inst->inst_id);
if (BTM_CMD_STARTED == rt) {
if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id,
BTM_BLE_MULTI_ADV_ENB_EVT)) == BTM_CMD_STARTED) {
p_inst->p_cback = p_cback;
p_inst->p_ref = p_ref;
}{...}
}{...}
if (BTM_CMD_STARTED != rt) {
p_inst->in_use = FALSE;
BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed");
}{...}
break;
}{...}
}{...}
return rt;
}{ ... }
/* ... */
tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params)
{
tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
BTM_TRACE_ERROR("Controller does not support Multi ADV");
return BTM_ERR_PROCESSING;
}{...}
if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
p_params != NULL) {
if (FALSE == p_inst->in_use) {
BTM_TRACE_DEBUG("adv instance %d is not active", inst_id);
return BTM_WRONG_MODE;
}{...} else {
btm_ble_enable_multi_adv(FALSE, inst_id, 0);
}{...}
if (BTM_CMD_STARTED == btm_ble_multi_adv_set_params(p_inst, p_params, 0)) {
rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT);
}{...}
}{...}
return rt;
}{ ... }
/* ... */
tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
tBTM_BLE_AD_MASK data_mask,
tBTM_BLE_ADV_DATA *p_data)
{
UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param;
UINT8 sub_code = (is_scan_rsp) ?
BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA;
UINT8 *p_len;
tBTM_STATUS rt;
UINT8 *pp_temp = (UINT8 *)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1);
tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
if (0 == cmn_ble_vsc_cb.adv_inst_max) {
BTM_TRACE_ERROR("Controller does not support Multi ADV");
return BTM_ERR_PROCESSING;
}{...}
btm_ble_update_dmt_flag_bits(&p_data->flag, btm_cb.btm_inq_vars.connectable_mode,
btm_cb.btm_inq_vars.discoverable_mode);
BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id);
if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
return BTM_ILLEGAL_VALUE;
}{...}
memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
UINT8_TO_STREAM(pp, sub_code);
p_len = pp ++;
btm_ble_build_adv_data(&data_mask, &pp, p_data);
*p_len = (UINT8)(pp - param - 2);
UINT8_TO_STREAM(pp_temp, inst_id);
if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
(UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
param,
btm_ble_multi_adv_vsc_cmpl_cback))
== BTM_CMD_STARTED) {
btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT);
}{...}
return rt;
}{ ... }
/* ... */
tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id)
{
tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
if (0 == cmn_ble_vsc_cb.adv_inst_max) {
BTM_TRACE_ERROR("Controller does not support Multi ADV");
return BTM_ERR_PROCESSING;
}{...}
if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT))
== BTM_CMD_STARTED) {
btm_ble_multi_adv_configure_rpa(&btm_multi_adv_cb.p_adv_inst[inst_id - 1]);
btu_stop_timer_oneshot(&btm_multi_adv_cb.p_adv_inst[inst_id - 1].raddr_timer_ent);
btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
}{...}
}{...}
return rt;
}{ ... }
/* ... */
void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
{
UINT8 sub_event;
UINT8 adv_inst;
UINT16 conn_handle;
tACL_CONN *p_acl_cb = NULL;
STREAM_TO_UINT8(sub_event, p);
len--;
BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event);
if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len >= 4)) {
STREAM_TO_UINT8(adv_inst, p);
++p;
STREAM_TO_UINT16(conn_handle, p);
if ((p_acl_cb = btm_handle_to_acl(conn_handle)) != NULL) {
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE &&
adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
memcpy(p_acl_cb->conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa,
BD_ADDR_LEN);
}{...}
#endif/* ... */
}{...}
if (adv_inst < BTM_BleMaxMultiAdvInstanceCount() &&
adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
btm_ble_multi_adv_reenable(adv_inst);
}{...}
else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) {
btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
}{...}
}{...}
}{...}
}{ ... }
/* ... */
void btm_ble_multi_adv_init(void)
{
#if BTM_DYNAMIC_MEMORY == TRUE
btm_multi_adv_cb_ptr = (tBTM_BLE_MULTI_ADV_CB *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_CB));
btm_multi_adv_idx_q_ptr = (tBTM_BLE_MULTI_ADV_INST_IDX_Q *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_INST_IDX_Q));
if (btm_multi_adv_cb_ptr == NULL || btm_multi_adv_idx_q_ptr == NULL) {
BTM_TRACE_ERROR("%s malloc failed", __func__);
return;
}{...}
#endif/* ... */
UINT8 i = 0;
memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
memset (&btm_multi_adv_idx_q, 0, sizeof (tBTM_BLE_MULTI_ADV_INST_IDX_Q));
btm_multi_adv_idx_q.front = -1;
btm_multi_adv_idx_q.rear = -1;
if (btm_cb.cmn_ble_vsc_cb.adv_inst_max > 0) {
btm_multi_adv_cb.p_adv_inst = osi_malloc( sizeof(tBTM_BLE_MULTI_ADV_INST) *
(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
memset(btm_multi_adv_cb.p_adv_inst, 0, sizeof(tBTM_BLE_MULTI_ADV_INST) *
(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
btm_multi_adv_cb.op_q.p_sub_code = osi_malloc( sizeof(UINT8) *
(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
memset(btm_multi_adv_cb.op_q.p_sub_code, 0,
sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
btm_multi_adv_cb.op_q.p_inst_id = osi_malloc( sizeof(UINT8) *
(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
memset(btm_multi_adv_cb.op_q.p_inst_id, 0,
sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
}{...}
for (i = 0; i < btm_cb.cmn_ble_vsc_cb.adv_inst_max; i++) {
btm_multi_adv_cb.p_adv_inst[i].index = i;
btm_multi_adv_cb.p_adv_inst[i].inst_id = i + 1;
}{...}
BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
}{ ... }
/* ... */
void btm_ble_multi_adv_cleanup(void)
{
#if BTM_DYNAMIC_MEMORY == TRUE
if (btm_multi_adv_cb_ptr == NULL)
{
BTM_TRACE_WARNING("%s memory has been freed", __func__);
return;
}{...}
#endif/* ... */
if (btm_multi_adv_cb.p_adv_inst) {
osi_free(btm_multi_adv_cb.p_adv_inst);
btm_multi_adv_cb.p_adv_inst = NULL;
}{...}
if (btm_multi_adv_cb.op_q.p_sub_code) {
osi_free(btm_multi_adv_cb.op_q.p_sub_code);
btm_multi_adv_cb.op_q.p_sub_code = NULL;
}{...}
if (btm_multi_adv_cb.op_q.p_inst_id) {
osi_free(btm_multi_adv_cb.op_q.p_inst_id);
btm_multi_adv_cb.op_q.p_inst_id = NULL;
}{...}
#if BTM_DYNAMIC_MEMORY == TRUE
if(btm_multi_adv_cb_ptr) {
osi_free(btm_multi_adv_cb_ptr);
btm_multi_adv_cb_ptr = NULL;
}{...}
if(btm_multi_adv_idx_q_ptr) {
osi_free(btm_multi_adv_idx_q_ptr);
btm_multi_adv_idx_q_ptr = NULL;
}{...}
#endif/* ... */
}{ ... }
/* ... */
void *btm_ble_multi_adv_get_ref(UINT8 inst_id)
{
tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
if (inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
if (NULL != p_inst) {
return p_inst->p_ref;
}{...}
}{...}
return NULL;
}{ ... }
#endif/* ... */