blob: 116232892369fbcffe5d9987057e95f3a5340191 [file] [log] [blame]
Satya Callojiffb39602014-04-30 15:55:39 -07001/******************************************************************************
2 *
3 * Copyright (C) 2014 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19#include <string.h>
20#include "bt_target.h"
21
22#if (BLE_INCLUDED == TRUE)
23#if BLE_MULTI_ADV_INCLUDED == TRUE
24#include "bt_types.h"
25#include "hcimsgs.h"
26#include "btu.h"
27#include "btm_int.h"
28#include "bt_utils.h"
29#include "hcidefs.h"
30#include "btm_ble_api.h"
31
32/* length of each multi adv sub command */
33#define BTM_BLE_MULTI_ADV_ENB_LEN 3
Satya Calloji0943c102014-05-12 09:13:02 -070034#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
Satya Callojiffb39602014-04-30 15:55:39 -070035#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
36#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
37
38#ifndef BTM_BLE_MULTI_ADV_INST_MAX
39#define BTM_BLE_MULTI_ADV_INST_MAX 5
40#endif
41
42tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
43
44static void btm_ble_multi_adv_gen_rpa_cmpl_1(tBTM_RAND_ENC *p);
45static void btm_ble_multi_adv_gen_rpa_cmpl_2(tBTM_RAND_ENC *p);
46static void btm_ble_multi_adv_gen_rpa_cmpl_3(tBTM_RAND_ENC *p);
47static void btm_ble_multi_adv_gen_rpa_cmpl_4(tBTM_RAND_ENC *p);
48
49typedef void (*tBTM_MULTI_ADV_RPA_CMPL)(tBTM_RAND_ENC *p);
50const tBTM_MULTI_ADV_RPA_CMPL btm_ble_multi_adv_rpa_cmpl [] =
51{
52 btm_ble_multi_adv_gen_rpa_cmpl_1,
53 btm_ble_multi_adv_gen_rpa_cmpl_2,
54 btm_ble_multi_adv_gen_rpa_cmpl_3,
55 btm_ble_multi_adv_gen_rpa_cmpl_4
56};
57
58#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
59#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
60
61/*******************************************************************************
62**
63** Function btm_ble_multi_adv_enq_op_q
64**
65** Description enqueue a multi adv operation in q to check command complete
66** status.
67**
68** Returns void
69**
70*******************************************************************************/
71void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt)
72{
73 tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
74
75 p_op_q->inst_id[p_op_q->next_idx] = inst_id;
76
77 p_op_q->sub_code[p_op_q->next_idx] = (opcode |(cb_evt << 4));
78
79 p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BLE_MULTI_ADV_MAX;
80}
81
82/*******************************************************************************
83**
84** Function btm_ble_multi_adv_deq_op_q
85**
86** Description dequeue a multi adv operation from q when command complete
87** is received.
88**
89** Returns void
90**
91*******************************************************************************/
92void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt)
93{
94 tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
95
96 *p_inst_id = p_op_q->inst_id[p_op_q->pending_idx] & 0x7F;
97 *p_cb_evt = (p_op_q->sub_code[p_op_q->pending_idx] >> 4);
98 *p_opcode = (p_op_q->sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK);
99
100 p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BLE_MULTI_ADV_MAX;
101}
102
103/*******************************************************************************
104**
105** Function btm_ble_multi_adv_vsc_cmpl_cback
106**
107** Description Multi adv VSC complete callback
108**
109** Parameters
110**
111** Returns void
112**
113*******************************************************************************/
114void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params)
115{
116 UINT8 status, subcode;
117 UINT8 *p = p_params->p_param_buf, inst_id;
118 UINT16 len = p_params->param_len;
119 tBTM_BLE_MULTI_ADV_INST *p_inst ;
120 UINT8 cb_evt = 0, opcode;
121
122 if (len < 2)
123 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700124 BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback");
Satya Callojiffb39602014-04-30 15:55:39 -0700125 return;
126 }
127
128 STREAM_TO_UINT8(status, p);
129 STREAM_TO_UINT8(subcode, p);
130
131 btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt);
132
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700133 BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
Satya Callojiffb39602014-04-30 15:55:39 -0700134
135 if (opcode != subcode || inst_id == 0)
136 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700137 BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d",subcode,opcode);
Satya Callojiffb39602014-04-30 15:55:39 -0700138 return;
139 }
140
141 p_inst = &btm_multi_adv_cb.adv_inst[inst_id - 1];
142
143 switch (subcode)
144 {
145 case BTM_BLE_MULTI_ADV_ENB:
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700146 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700147 if (status != HCI_SUCCESS)
148 {
149 btm_multi_adv_cb.adv_inst[inst_id-1].inst_id = 0;
150 }
151 break;
152
153 case BTM_BLE_MULTI_ADV_SET_PARAM:
154 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700155 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700156 break;
157 }
158
159 case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA:
160 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700161 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700162 break;
163 }
164
165 case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA:
166 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700167 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700168 break;
169 }
170
171 case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR:
172 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700173 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700174 break;
175 }
176
177 default:
178 break;
179 }
180
181 if (cb_evt != 0 && p_inst->p_cback != NULL)
182 {
183 (p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status);
184 }
185 return;
186}
187
188/*******************************************************************************
189**
190** Function btm_ble_enable_multi_adv
191**
192** Description This function enable the customer specific feature in controller
193**
194** Parameters enable: enable or disable
195** inst_id: adv instance ID, can not be 0
196**
197** Returns status
198**
199*******************************************************************************/
200tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt)
201{
202 UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp;
203 UINT8 enb = enable ? 1: 0;
204 tBTM_STATUS rt;
205
206 pp = param;
207 memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
208
209 UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB);
210 UINT8_TO_STREAM (pp, enb);
211 UINT8_TO_STREAM (pp, inst_id);
212
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700213 BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d",enb,inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700214
215 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
216 BTM_BLE_MULTI_ADV_ENB_LEN,
217 param,
218 btm_ble_multi_adv_vsc_cmpl_cback))
219 == BTM_CMD_STARTED)
220 {
221 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt);
222 }
223 return rt;
224}
225
226/*******************************************************************************
227**
228** Function btm_ble_multi_adv_set_params
229**
230** Description This function enable the customer specific feature in controller
231**
232** Parameters advertise parameters used for this instance.
233**
234** Returns status
235**
236*******************************************************************************/
237tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst,
238 tBTM_BLE_ADV_PARAMS *p_params,
239 UINT8 cb_evt)
240{
241 UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp;
242 tBTM_STATUS rt;
243 BD_ADDR dummy ={0,0,0,0,0,0};
244
245 pp = param;
246 memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
247
248 UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
249
250 UINT16_TO_STREAM (pp, p_params->adv_int_min);
251 UINT16_TO_STREAM (pp, p_params->adv_int_max);
252 UINT8_TO_STREAM (pp, p_params->adv_type);
253
254 if (btm_cb.ble_ctr_cb.privacy)
255 {
256 UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM);
257 BDADDR_TO_STREAM (pp, p_inst->rpa);
258 }
259 else
260 {
261 UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
262 BDADDR_TO_STREAM (pp, btm_cb.devcb.local_addr);
263 }
264
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700265 BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d",
Satya Callojiffb39602014-04-30 15:55:39 -0700266 p_params->adv_int_min,p_params->adv_int_max,p_params->adv_type);
267
268 UINT8_TO_STREAM (pp, 0);
269 BDADDR_TO_STREAM (pp, dummy);
270
271 if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP)
272 p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
273 UINT8_TO_STREAM (pp, p_params->channel_map);
274
275 if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX)
276 p_params->adv_filter_policy = AP_SCAN_CONN_ALL;
277 UINT8_TO_STREAM (pp, p_params->adv_filter_policy);
278
279 UINT8_TO_STREAM (pp, p_inst->inst_id);
280
281 if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX)
282 p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX;
283 UINT8_TO_STREAM (pp, p_params->tx_power);
284
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700285 BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d",
Satya Callojiffb39602014-04-30 15:55:39 -0700286 p_params->channel_map,p_params->adv_filter_policy,p_inst->inst_id,p_params->tx_power);
287
288 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
289 BTM_BLE_MULTI_ADV_SET_PARAM_LEN,
290 param,
291 btm_ble_multi_adv_vsc_cmpl_cback))
292 == BTM_CMD_STARTED)
293 {
294 p_inst->adv_evt = p_params->adv_type;
295
296 if (btm_cb.ble_ctr_cb.privacy)
297 {
298 /* start timer */
299 p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
300 btu_start_timer (&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
301 BTM_BLE_PRIVATE_ADDR_INT);
302 }
303 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt);
304 }
305 return rt;
306}
307
308/*******************************************************************************
309**
310** Function btm_ble_multi_adv_write_rpa
311**
312** Description This function write the random address for the adv instance into
313** controller
314**
315** Parameters
316**
317** Returns status
318**
319*******************************************************************************/
320tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr)
321{
322 UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param;
323 tBTM_STATUS rt;
324
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700325 BTM_TRACE_EVENT (" btm_ble_multi_adv_set_random_addr");
Satya Callojiffb39602014-04-30 15:55:39 -0700326
327 memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
328
329 UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
330 BDADDR_TO_STREAM(pp, random_addr);
331 UINT8_TO_STREAM(pp, p_inst->inst_id);
332
333 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
334 BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN,
335 param,
336 btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED)
337 {
338 /* start a periodical timer to refresh random addr */
339 btu_stop_timer(&p_inst->raddr_timer_ent);
340 p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
341 btu_start_timer (&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
342 BTM_BLE_PRIVATE_ADDR_INT);
343
344 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0);
345 }
346 return rt;
347}
348
349/*******************************************************************************
350**
351** Function btm_ble_multi_adv_gen_rpa_cmpl
352**
353** Description RPA generation completion callback for each adv instance. Will
354** continue write the new RPA into controller.
355**
356** Returns none.
357**
358*******************************************************************************/
359void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p, tBTM_BLE_MULTI_ADV_INST *p_inst )
360{
361#if (SMP_INCLUDED == TRUE)
362 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
363 tSMP_ENC output;
364
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700365 BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700366 if (p)
367 {
368 p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
369 p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
370
371 p_inst->rpa[2] = p->param_buf[0];
372 p_inst->rpa[1] = p->param_buf[1];
373 p_inst->rpa[0] = p->param_buf[2];
374
375 if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output))
376 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700377 BTM_TRACE_DEBUG("generate random address failed");
Satya Callojiffb39602014-04-30 15:55:39 -0700378 }
379 else
380 {
381 /* set hash to be LSB of rpAddress */
382 p_inst->rpa[5] = output.param_buf[0];
383 p_inst->rpa[4] = output.param_buf[1];
384 p_inst->rpa[3] = output.param_buf[2];
385
386 if (p_inst->inst_id != 0)
387 {
388 /* set it to controller */
389 btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
390 }
391 }
392 }
393#endif
394}
395
396/*******************************************************************************
397**
398** Function btm_ble_multi_adv_gen_rpa_cmpl1
399**
400** Description RPA generation completion callback for each adv instance. Will
401** continue write the new RPA into controller.
402**
403** Returns none.
404**
405*******************************************************************************/
406static void btm_ble_multi_adv_gen_rpa_cmpl_1(tBTM_RAND_ENC *p)
407{
408 btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[0]);
409}
410
411/*******************************************************************************
412**
413** Function btm_ble_multi_adv_gen_rpa_cmpl2
414**
415** Description RPA generation completion callback for each adv instance. Will
416** continue write the new RPA into controller.
417**
418** Returns none.
419**
420*******************************************************************************/
421static void btm_ble_multi_adv_gen_rpa_cmpl_2(tBTM_RAND_ENC *p)
422{
423 btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[1]);
424}
425
426/*******************************************************************************
427**
428** Function btm_ble_multi_adv_gen_rpa_cmpl3
429**
430** Description RPA generation completion callback for each adv instance. Will
431** continue write the new RPA into controller.
432**
433** Returns none.
434**
435*******************************************************************************/
436static void btm_ble_multi_adv_gen_rpa_cmpl_3(tBTM_RAND_ENC *p)
437{
438 btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[2]);
439}
440
441/*******************************************************************************
442**
443** Function btm_ble_multi_adv_gen_rpa_cmpl4
444**
445** Description RPA generation completion callback for each adv instance. Will
446** continue write the new RPA into controller.
447**
448** Returns none.
449**
450*******************************************************************************/
451static void btm_ble_multi_adv_gen_rpa_cmpl_4(tBTM_RAND_ENC *p)
452{
453 btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[3]);
454}
455/*******************************************************************************
456**
457** Function btm_ble_multi_adv_configure_rpa
458**
459** Description This function set the random address for the adv instance
460**
461** Parameters advertise parameters used for this instance.
462**
463** Returns none
464**
465*******************************************************************************/
466void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst)
467{
468 btm_gen_resolvable_private_addr((void *)p_inst->p_rpa_cback);
469}
470
471/*******************************************************************************
472**
473** Function btm_ble_multi_adv_reenable
474**
475** Description This function re-enable adv instance upon a connection establishment.
476**
477** Parameters advertise parameters used for this instance.
478**
479** Returns none.
480**
481*******************************************************************************/
482void btm_ble_multi_adv_reenable(UINT8 inst_id)
483{
484 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[inst_id - 1];
485
486 if (p_inst->inst_id != 0)
487 {
488 if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT)
489 btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0);
490 else
491 /* mark directed adv as disabled if adv has been stopped */
492 {
493 (p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT,p_inst->inst_id,p_inst->p_ref,0);
494 p_inst->inst_id = 0;
495 }
496 }
497}
498
499/*******************************************************************************
500**
Satya Calloji0943c102014-05-12 09:13:02 -0700501** Function btm_ble_multi_adv_enb_privacy
502**
503** Description This function enable/disable privacy setting in multi adv
504**
505** Parameters enable: enable or disable the adv instance.
506**
507** Returns none.
508**
509*******************************************************************************/
510void btm_ble_multi_adv_enb_privacy(BOOLEAN enable)
511{
512 UINT8 i;
513 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[0];
514
515 for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++, p_inst++)
516 {
517 if (enable)
518 btm_ble_multi_adv_configure_rpa (p_inst);
519 else
520 btu_stop_timer(&p_inst->raddr_timer_ent);
521 }
522}
523
524/*******************************************************************************
525**
Satya Callojiffb39602014-04-30 15:55:39 -0700526** Function BTM_BleEnableAdvInstance
527**
528** Description This function enable a Multi-ADV instance with the specified
529** adv parameters
530**
531** Parameters p_params: pointer to the adv parameter structure, set as default
532** adv parameter when the instance is enabled.
533** p_cback: callback function for the adv instance.
534** p_ref: reference data attach to the adv instance to be enabled.
535**
536** Returns status
537**
538*******************************************************************************/
539tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
540 tBTM_BLE_MULTI_ADV_CBACK *p_cback,void *p_ref)
541{
542 UINT8 i;
543 tBTM_STATUS rt = BTM_NO_RESOURCES;
544 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[0];
545
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700546 BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called");
Satya Callojiffb39602014-04-30 15:55:39 -0700547
548 if (btm_multi_adv_cb.adv_inst_max == 0)
549 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700550 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700551 return BTM_ERR_PROCESSING;
552 }
553
554 for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++, p_inst++)
555 {
556 if (p_inst->inst_id == 0)
557 {
558 p_inst->inst_id = i + 1;
559
560 /* configure adv parameter */
561 if (p_params)
562 btm_ble_multi_adv_set_params(p_inst, p_params, 0);
563
564 /* enable adv */
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700565 BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d",
Satya Callojiffb39602014-04-30 15:55:39 -0700566 p_inst->inst_id);
567 if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, BTM_BLE_MULTI_ADV_ENB_EVT))
568 == BTM_CMD_STARTED)
569 {
570 p_inst->p_cback = p_cback;
571 p_inst->p_ref = p_ref;
572 }
573 else
574 {
575 p_inst->inst_id = 0;
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700576 BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed, no resources");
Satya Callojiffb39602014-04-30 15:55:39 -0700577 }
578 break;
579 }
580 }
581 return rt;
582}
583
584/*******************************************************************************
585**
586** Function BTM_BleUpdateAdvInstParam
587**
588** Description This function update a Multi-ADV instance with the specified
589** adv parameters.
590**
591** Parameters inst_id: adv instance ID
592** p_params: pointer to the adv parameter structure.
593**
594** Returns status
595**
596*******************************************************************************/
597tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params)
598{
599 tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
600 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[inst_id - 1];
601
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700602 BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700603
604 if (btm_multi_adv_cb.adv_inst_max == 0)
605 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700606 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700607 return BTM_ERR_PROCESSING;
608 }
609
610 if (inst_id <= BTM_BLE_MULTI_ADV_MAX &&
611 inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
612 p_params != NULL)
613 {
614 if (p_inst->inst_id == 0)
615 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700616 BTM_TRACE_DEBUG("adv instance %d is not active", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700617 return BTM_WRONG_MODE;
618 }
619 else
620 btm_ble_enable_multi_adv(FALSE, inst_id, 0);
621
622 btm_ble_multi_adv_set_params(p_inst, p_params, 0);
623
624 rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT);
625 }
626 return rt;
627}
628
629/*******************************************************************************
630**
631** Function BTM_BleCfgAdvInstData
632**
633** Description This function configure a Multi-ADV instance with the specified
634** adv data or scan response data.
635**
636** Parameters inst_id: adv instance ID
637** is_scan_rsp: is this scacn response, if no set as adv data.
638** data_mask: adv data mask.
639** p_data: pointer to the adv data structure.
640**
641** Returns status
642**
643*******************************************************************************/
644tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
645 tBTM_BLE_AD_MASK data_mask,
646 tBTM_BLE_ADV_DATA *p_data)
647{
648 UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param;
649 UINT8 sub_code = (is_scan_rsp) ?
650 BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA;
651 UINT8 *p_len;
652 tBTM_STATUS rt;
653 UINT8 *pp_temp = (UINT8*)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN -1);
654
655 if (btm_multi_adv_cb.adv_inst_max == 0)
656 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700657 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700658 return BTM_ERR_PROCESSING;
659 }
660
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700661 BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700662 if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD)
663 return BTM_ILLEGAL_VALUE;
664
665 memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
666
667 UINT8_TO_STREAM(pp, sub_code);
668 p_len = pp ++;
669 btm_ble_build_adv_data(&data_mask, &pp, p_data);
670 *p_len = (UINT8)(pp - param - 2);
671 UINT8_TO_STREAM(pp_temp, inst_id);
672
673 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
674 (UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
675 param,
676 btm_ble_multi_adv_vsc_cmpl_cback))
677 == BTM_CMD_STARTED)
678 {
679 btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT);
680 }
681 return rt;
682}
683
684/*******************************************************************************
685**
686** Function BTM_BleDisableAdvInstance
687**
688** Description This function disables a Multi-ADV instance.
689**
690** Parameters inst_id: adv instance ID
691**
692** Returns status
693**
694*******************************************************************************/
695tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id)
696{
697 tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
698
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700699 BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700700
701 if (btm_multi_adv_cb.adv_inst_max == 0)
702 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700703 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700704 return BTM_ERR_PROCESSING;
705 }
706
707 if (inst_id <= BTM_BLE_MULTI_ADV_MAX && inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD)
708 {
709 if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT))
710 == BTM_CMD_STARTED)
711 {
712 btu_stop_timer(&btm_multi_adv_cb.adv_inst[inst_id-1].raddr_timer_ent);
713
714 btm_multi_adv_cb.adv_inst[inst_id-1].inst_id = 0;
715 }
716 }
717 return rt;
718}
719/*******************************************************************************
720**
721** Function btm_ble_multi_adv_vse_cback
722**
723** Description VSE callback for multi adv events.
724**
725** Returns
726**
727*******************************************************************************/
728void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
729{
730 UINT8 sub_event;
731 UINT8 adv_inst, reason, conn_handle;
732
733 /* Check if this is a BLE RSSI vendor specific event */
734 STREAM_TO_UINT8(sub_event, p);
735 len--;
736
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700737 BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event);
Satya Callojiffb39602014-04-30 15:55:39 -0700738 if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len>=4))
739 {
740 STREAM_TO_UINT8(adv_inst, p);
741 STREAM_TO_UINT8(reason, p);
742 STREAM_TO_UINT16(conn_handle, p);
743
744 if (adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD)
745 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700746 BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
Satya Callojiffb39602014-04-30 15:55:39 -0700747 btm_ble_multi_adv_reenable(adv_inst);
748 }
749 /* re-enable connectibility */
750 else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD)
751 {
752 if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE)
753 {
754 btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
755
756 }
757 }
758
759 }
760
761}
762/*******************************************************************************
763**
764** Function btm_ble_multi_adv_init
765**
766** Description This function initialize the multi adv control block.
767**
768** Parameters
769**
770** Returns status
771**
772*******************************************************************************/
773void btm_ble_multi_adv_init(void)
774{
775 UINT8 i;
776
777 memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
778
779 for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++)
780 btm_multi_adv_cb.adv_inst[i].p_rpa_cback = btm_ble_multi_adv_rpa_cmpl[i];
781
782 BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
783}
784#endif
785#endif
786