blob: b2838a7dba4c352462bb215e54b4e5cc0b2b0f87 [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)
Satya Callojiffb39602014-04-30 15:55:39 -070023#include "bt_types.h"
24#include "hcimsgs.h"
25#include "btu.h"
26#include "btm_int.h"
27#include "bt_utils.h"
28#include "hcidefs.h"
29#include "btm_ble_api.h"
30
31/* length of each multi adv sub command */
32#define BTM_BLE_MULTI_ADV_ENB_LEN 3
Satya Calloji0943c102014-05-12 09:13:02 -070033#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
Satya Callojiffb39602014-04-30 15:55:39 -070034#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
35#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
36
Satya Callojiffb39602014-04-30 15:55:39 -070037tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070038tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q;
Satya Callojiffb39602014-04-30 15:55:39 -070039
40#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
41#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
42
43/*******************************************************************************
44**
45** Function btm_ble_multi_adv_enq_op_q
46**
47** Description enqueue a multi adv operation in q to check command complete
48** status.
49**
50** Returns void
51**
52*******************************************************************************/
53void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt)
54{
55 tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
56
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070057 p_op_q->p_inst_id[p_op_q->next_idx] = inst_id;
Satya Callojiffb39602014-04-30 15:55:39 -070058
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070059 p_op_q->p_sub_code[p_op_q->next_idx] = (opcode |(cb_evt << 4));
Satya Callojiffb39602014-04-30 15:55:39 -070060
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070061 p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
Satya Callojiffb39602014-04-30 15:55:39 -070062}
63
64/*******************************************************************************
65**
66** Function btm_ble_multi_adv_deq_op_q
67**
68** Description dequeue a multi adv operation from q when command complete
69** is received.
70**
71** Returns void
72**
73*******************************************************************************/
74void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt)
75{
76 tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
77
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070078 *p_inst_id = p_op_q->p_inst_id[p_op_q->pending_idx] & 0x7F;
79 *p_cb_evt = (p_op_q->p_sub_code[p_op_q->pending_idx] >> 4);
80 *p_opcode = (p_op_q->p_sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK);
Satya Callojiffb39602014-04-30 15:55:39 -070081
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -070082 p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
Satya Callojiffb39602014-04-30 15:55:39 -070083}
84
85/*******************************************************************************
86**
87** Function btm_ble_multi_adv_vsc_cmpl_cback
88**
89** Description Multi adv VSC complete callback
90**
91** Parameters
92**
93** Returns void
94**
95*******************************************************************************/
96void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params)
97{
98 UINT8 status, subcode;
99 UINT8 *p = p_params->p_param_buf, inst_id;
100 UINT16 len = p_params->param_len;
101 tBTM_BLE_MULTI_ADV_INST *p_inst ;
102 UINT8 cb_evt = 0, opcode;
103
104 if (len < 2)
105 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700106 BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback");
Satya Callojiffb39602014-04-30 15:55:39 -0700107 return;
108 }
109
110 STREAM_TO_UINT8(status, p);
111 STREAM_TO_UINT8(subcode, p);
112
113 btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt);
114
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700115 BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
Satya Callojiffb39602014-04-30 15:55:39 -0700116
117 if (opcode != subcode || inst_id == 0)
118 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700119 BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d",subcode,opcode);
Satya Callojiffb39602014-04-30 15:55:39 -0700120 return;
121 }
122
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700123 p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
Satya Callojiffb39602014-04-30 15:55:39 -0700124
125 switch (subcode)
126 {
127 case BTM_BLE_MULTI_ADV_ENB:
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700128 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700129 if (status != HCI_SUCCESS)
130 {
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700131 btm_multi_adv_cb.p_adv_inst[inst_id-1].inst_id = 0;
Satya Callojiffb39602014-04-30 15:55:39 -0700132 }
133 break;
134
135 case BTM_BLE_MULTI_ADV_SET_PARAM:
136 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700137 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700138 break;
139 }
140
141 case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA:
142 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700143 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700144 break;
145 }
146
147 case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA:
148 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700149 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700150 break;
151 }
152
153 case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR:
154 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700155 BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status);
Satya Callojiffb39602014-04-30 15:55:39 -0700156 break;
157 }
158
159 default:
160 break;
161 }
162
163 if (cb_evt != 0 && p_inst->p_cback != NULL)
164 {
165 (p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status);
166 }
167 return;
168}
169
170/*******************************************************************************
171**
172** Function btm_ble_enable_multi_adv
173**
174** Description This function enable the customer specific feature in controller
175**
176** Parameters enable: enable or disable
177** inst_id: adv instance ID, can not be 0
178**
179** Returns status
180**
181*******************************************************************************/
182tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt)
183{
184 UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp;
185 UINT8 enb = enable ? 1: 0;
186 tBTM_STATUS rt;
187
188 pp = param;
189 memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
190
191 UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB);
192 UINT8_TO_STREAM (pp, enb);
193 UINT8_TO_STREAM (pp, inst_id);
194
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700195 BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d",enb,inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700196
197 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
198 BTM_BLE_MULTI_ADV_ENB_LEN,
199 param,
200 btm_ble_multi_adv_vsc_cmpl_cback))
201 == BTM_CMD_STARTED)
202 {
203 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt);
204 }
205 return rt;
206}
Prerepa Viswanadham4c94c5f2014-07-18 15:20:54 -0700207/*******************************************************************************
208**
209** Function btm_ble_map_adv_tx_power
210**
211** Description return the actual power in dBm based on the mapping in config file
212**
213** Parameters advertise parameters used for this instance.
214**
215** Returns tx power in dBm
216**
217*******************************************************************************/
218int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
Satya Calloji4a7ad9b2014-07-29 15:32:51 -0700219char btm_ble_map_adv_tx_power(int tx_power_index)
Prerepa Viswanadham4c94c5f2014-07-18 15:20:54 -0700220{
221 if(0 <= tx_power_index && tx_power_index < BTM_BLE_ADV_TX_POWER_MAX)
222 return (char)btm_ble_tx_power[tx_power_index];
223 return 0;
224}
Satya Callojiffb39602014-04-30 15:55:39 -0700225/*******************************************************************************
226**
227** Function btm_ble_multi_adv_set_params
228**
229** Description This function enable the customer specific feature in controller
230**
231** Parameters advertise parameters used for this instance.
232**
233** Returns status
234**
235*******************************************************************************/
236tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst,
237 tBTM_BLE_ADV_PARAMS *p_params,
238 UINT8 cb_evt)
239{
240 UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp;
241 tBTM_STATUS rt;
242 BD_ADDR dummy ={0,0,0,0,0,0};
243
244 pp = param;
245 memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
246
247 UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
248
249 UINT16_TO_STREAM (pp, p_params->adv_int_min);
250 UINT16_TO_STREAM (pp, p_params->adv_int_max);
251 UINT8_TO_STREAM (pp, p_params->adv_type);
252
Sharvil Nanavati88e76452014-06-01 22:38:46 -0700253#if BLE_PRIVACY_SPT
Satya Callojiffb39602014-04-30 15:55:39 -0700254 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
Sharvil Nanavati88e76452014-06-01 22:38:46 -0700260#endif
Satya Callojiffb39602014-04-30 15:55:39 -0700261 {
262 UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
263 BDADDR_TO_STREAM (pp, btm_cb.devcb.local_addr);
264 }
265
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700266 BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d",
Satya Callojiffb39602014-04-30 15:55:39 -0700267 p_params->adv_int_min,p_params->adv_int_max,p_params->adv_type);
268
269 UINT8_TO_STREAM (pp, 0);
270 BDADDR_TO_STREAM (pp, dummy);
271
272 if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP)
273 p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
274 UINT8_TO_STREAM (pp, p_params->channel_map);
275
276 if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX)
277 p_params->adv_filter_policy = AP_SCAN_CONN_ALL;
278 UINT8_TO_STREAM (pp, p_params->adv_filter_policy);
279
280 UINT8_TO_STREAM (pp, p_inst->inst_id);
281
282 if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX)
283 p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX;
Prerepa Viswanadham4c94c5f2014-07-18 15:20:54 -0700284 UINT8_TO_STREAM (pp, btm_ble_map_adv_tx_power(p_params->tx_power));
Satya Callojiffb39602014-04-30 15:55:39 -0700285
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700286 BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d",
Satya Callojiffb39602014-04-30 15:55:39 -0700287 p_params->channel_map,p_params->adv_filter_policy,p_inst->inst_id,p_params->tx_power);
288
289 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
290 BTM_BLE_MULTI_ADV_SET_PARAM_LEN,
291 param,
292 btm_ble_multi_adv_vsc_cmpl_cback))
293 == BTM_CMD_STARTED)
294 {
295 p_inst->adv_evt = p_params->adv_type;
296
Sharvil Nanavati88e76452014-06-01 22:38:46 -0700297#if BLE_PRIVACY_SPT
Satya Callojiffb39602014-04-30 15:55:39 -0700298 if (btm_cb.ble_ctr_cb.privacy)
299 {
300 /* start timer */
301 p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
Chris Manton0aee3312014-06-12 12:52:33 -0700302 btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
Satya Callojiffb39602014-04-30 15:55:39 -0700303 BTM_BLE_PRIVATE_ADDR_INT);
304 }
Sharvil Nanavati88e76452014-06-01 22:38:46 -0700305#endif
Satya Callojiffb39602014-04-30 15:55:39 -0700306 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt);
307 }
308 return rt;
309}
310
311/*******************************************************************************
312**
313** Function btm_ble_multi_adv_write_rpa
314**
315** Description This function write the random address for the adv instance into
316** controller
317**
318** Parameters
319**
320** Returns status
321**
322*******************************************************************************/
323tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr)
324{
325 UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param;
326 tBTM_STATUS rt;
327
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700328 BTM_TRACE_EVENT (" btm_ble_multi_adv_set_random_addr");
Satya Callojiffb39602014-04-30 15:55:39 -0700329
330 memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
331
332 UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
333 BDADDR_TO_STREAM(pp, random_addr);
334 UINT8_TO_STREAM(pp, p_inst->inst_id);
335
336 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
337 BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN,
338 param,
339 btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED)
340 {
341 /* start a periodical timer to refresh random addr */
342 btu_stop_timer(&p_inst->raddr_timer_ent);
343 p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
Andre Eisenbache0da8bb2014-08-08 20:14:46 -0700344 btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
Satya Callojiffb39602014-04-30 15:55:39 -0700345 BTM_BLE_PRIVATE_ADDR_INT);
346
347 btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0);
348 }
349 return rt;
350}
351
352/*******************************************************************************
353**
354** Function btm_ble_multi_adv_gen_rpa_cmpl
355**
356** Description RPA generation completion callback for each adv instance. Will
357** continue write the new RPA into controller.
358**
359** Returns none.
360**
361*******************************************************************************/
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700362void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p)
Satya Callojiffb39602014-04-30 15:55:39 -0700363{
364#if (SMP_INCLUDED == TRUE)
365 tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
366 tSMP_ENC output;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700367 UINT8 index = 0;
368 tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
369
370 /* Retrieve the index of adv instance from stored Q */
371 if (btm_multi_adv_idx_q.front == -1)
372 {
373 BTM_TRACE_ERROR(" %s can't locate advertise instance", __FUNCTION__);
374 return;
375 }
376 else
377 {
378 index = btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.front];
379 if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear)
380 {
381 btm_multi_adv_idx_q.front = -1;
382 btm_multi_adv_idx_q.rear = -1;
383 }
384 else
385 {
386 btm_multi_adv_idx_q.front = btm_multi_adv_idx_q.front +1 % BTM_BLE_MULTI_ADV_MAX;
387 }
388 }
389
390 p_inst = &(btm_multi_adv_cb.p_adv_inst[index]);
Satya Callojiffb39602014-04-30 15:55:39 -0700391
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700392 BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700393 if (p)
394 {
395 p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
396 p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
397
398 p_inst->rpa[2] = p->param_buf[0];
399 p_inst->rpa[1] = p->param_buf[1];
400 p_inst->rpa[0] = p->param_buf[2];
401
402 if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output))
403 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700404 BTM_TRACE_DEBUG("generate random address failed");
Satya Callojiffb39602014-04-30 15:55:39 -0700405 }
406 else
407 {
408 /* set hash to be LSB of rpAddress */
409 p_inst->rpa[5] = output.param_buf[0];
410 p_inst->rpa[4] = output.param_buf[1];
411 p_inst->rpa[3] = output.param_buf[2];
412
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700413 if (p_inst->inst_id != 0 && (p_inst->inst_id < BTM_BleMaxMultiAdvInstanceCount()))
Satya Callojiffb39602014-04-30 15:55:39 -0700414 {
415 /* set it to controller */
416 btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
417 }
418 }
419 }
420#endif
421}
422
423/*******************************************************************************
424**
Satya Callojiffb39602014-04-30 15:55:39 -0700425** Function btm_ble_multi_adv_configure_rpa
426**
427** Description This function set the random address for the adv instance
428**
429** Parameters advertise parameters used for this instance.
430**
431** Returns none
432**
433*******************************************************************************/
434void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst)
435{
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700436 if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear +1 % BTM_BLE_MULTI_ADV_MAX)
437 {
438 BTM_TRACE_ERROR("outstanding rand generation exceeded max allowed ");
439 return;
440 }
441 else
442 {
443 if (btm_multi_adv_idx_q.front == -1)
444 {
445 btm_multi_adv_idx_q.front = 0;
446 btm_multi_adv_idx_q.rear = 0;
447 }
448 else
449 {
450 btm_multi_adv_idx_q.rear = btm_multi_adv_idx_q.rear +1 % BTM_BLE_MULTI_ADV_MAX;
451 }
452 btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.rear] = p_inst->index;
453 }
454 btm_gen_resolvable_private_addr((void *)btm_ble_multi_adv_gen_rpa_cmpl);
Satya Callojiffb39602014-04-30 15:55:39 -0700455}
456
457/*******************************************************************************
458**
459** Function btm_ble_multi_adv_reenable
460**
461** Description This function re-enable adv instance upon a connection establishment.
462**
463** Parameters advertise parameters used for this instance.
464**
465** Returns none.
466**
467*******************************************************************************/
468void btm_ble_multi_adv_reenable(UINT8 inst_id)
469{
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700470 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
Satya Callojiffb39602014-04-30 15:55:39 -0700471
472 if (p_inst->inst_id != 0)
473 {
474 if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT)
475 btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0);
476 else
477 /* mark directed adv as disabled if adv has been stopped */
478 {
479 (p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT,p_inst->inst_id,p_inst->p_ref,0);
480 p_inst->inst_id = 0;
481 }
482 }
483}
484
485/*******************************************************************************
486**
Satya Calloji0943c102014-05-12 09:13:02 -0700487** Function btm_ble_multi_adv_enb_privacy
488**
489** Description This function enable/disable privacy setting in multi adv
490**
491** Parameters enable: enable or disable the adv instance.
492**
493** Returns none.
494**
495*******************************************************************************/
496void btm_ble_multi_adv_enb_privacy(BOOLEAN enable)
497{
498 UINT8 i;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700499 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
Satya Calloji0943c102014-05-12 09:13:02 -0700500
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700501 for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++)
Satya Calloji0943c102014-05-12 09:13:02 -0700502 {
503 if (enable)
504 btm_ble_multi_adv_configure_rpa (p_inst);
505 else
Chris Manton0aee3312014-06-12 12:52:33 -0700506 btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
Satya Calloji0943c102014-05-12 09:13:02 -0700507 }
508}
509
510/*******************************************************************************
511**
Satya Callojiffb39602014-04-30 15:55:39 -0700512** Function BTM_BleEnableAdvInstance
513**
514** Description This function enable a Multi-ADV instance with the specified
515** adv parameters
516**
517** Parameters p_params: pointer to the adv parameter structure, set as default
518** adv parameter when the instance is enabled.
519** p_cback: callback function for the adv instance.
520** p_ref: reference data attach to the adv instance to be enabled.
521**
522** Returns status
523**
524*******************************************************************************/
525tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
526 tBTM_BLE_MULTI_ADV_CBACK *p_cback,void *p_ref)
527{
528 UINT8 i;
529 tBTM_STATUS rt = BTM_NO_RESOURCES;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700530 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
Satya Callojiffb39602014-04-30 15:55:39 -0700531
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700532 BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called");
Satya Callojiffb39602014-04-30 15:55:39 -0700533
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700534 if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max)
Satya Callojiffb39602014-04-30 15:55:39 -0700535 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700536 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700537 return BTM_ERR_PROCESSING;
538 }
539
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700540 if (NULL == p_inst)
541 {
542 BTM_TRACE_ERROR("Invalid instance in BTM_BleEnableAdvInstance");
543 return BTM_ERR_PROCESSING;
544 }
545
546 for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++)
Satya Callojiffb39602014-04-30 15:55:39 -0700547 {
548 if (p_inst->inst_id == 0)
549 {
550 p_inst->inst_id = i + 1;
551
552 /* configure adv parameter */
553 if (p_params)
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700554 rt = btm_ble_multi_adv_set_params(p_inst, p_params, 0);
555 else
556 rt = BTM_CMD_STARTED;
Satya Callojiffb39602014-04-30 15:55:39 -0700557
558 /* enable adv */
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700559 BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d",
Satya Callojiffb39602014-04-30 15:55:39 -0700560 p_inst->inst_id);
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700561
562 if (BTM_CMD_STARTED == rt)
Satya Callojiffb39602014-04-30 15:55:39 -0700563 {
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700564 if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id,
565 BTM_BLE_MULTI_ADV_ENB_EVT)) == BTM_CMD_STARTED)
566 {
567 p_inst->p_cback = p_cback;
568 p_inst->p_ref = p_ref;
569 }
Satya Callojiffb39602014-04-30 15:55:39 -0700570 }
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700571
572 if (BTM_CMD_STARTED != rt)
Satya Callojiffb39602014-04-30 15:55:39 -0700573 {
574 p_inst->inst_id = 0;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700575 BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed");
Satya Callojiffb39602014-04-30 15:55:39 -0700576 }
577 break;
578 }
579 }
580 return rt;
581}
582
583/*******************************************************************************
584**
585** Function BTM_BleUpdateAdvInstParam
586**
587** Description This function update a Multi-ADV instance with the specified
588** adv parameters.
589**
590** Parameters inst_id: adv instance ID
591** p_params: pointer to the adv parameter structure.
592**
593** Returns status
594**
595*******************************************************************************/
596tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params)
597{
598 tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700599 tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
Satya Callojiffb39602014-04-30 15:55:39 -0700600
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700601 BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700602
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700603 if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max)
Satya Callojiffb39602014-04-30 15:55:39 -0700604 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700605 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700606 return BTM_ERR_PROCESSING;
607 }
608
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700609 if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
Satya Callojiffb39602014-04-30 15:55:39 -0700610 inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
611 p_params != NULL)
612 {
613 if (p_inst->inst_id == 0)
614 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700615 BTM_TRACE_DEBUG("adv instance %d is not active", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700616 return BTM_WRONG_MODE;
617 }
618 else
619 btm_ble_enable_multi_adv(FALSE, inst_id, 0);
620
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700621 if (BTM_CMD_STARTED == btm_ble_multi_adv_set_params(p_inst, p_params, 0))
622 rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT);
Satya Callojiffb39602014-04-30 15:55:39 -0700623 }
624 return rt;
625}
626
627/*******************************************************************************
628**
629** Function BTM_BleCfgAdvInstData
630**
631** Description This function configure a Multi-ADV instance with the specified
632** adv data or scan response data.
633**
634** Parameters inst_id: adv instance ID
635** is_scan_rsp: is this scacn response, if no set as adv data.
636** data_mask: adv data mask.
637** p_data: pointer to the adv data structure.
638**
639** Returns status
640**
641*******************************************************************************/
642tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
643 tBTM_BLE_AD_MASK data_mask,
644 tBTM_BLE_ADV_DATA *p_data)
645{
646 UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param;
647 UINT8 sub_code = (is_scan_rsp) ?
648 BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA;
649 UINT8 *p_len;
650 tBTM_STATUS rt;
651 UINT8 *pp_temp = (UINT8*)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN -1);
Satya Callojic4e25962014-05-10 23:46:24 -0700652 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
Satya Callojiffb39602014-04-30 15:55:39 -0700653
Satya Callojic4e25962014-05-10 23:46:24 -0700654 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
655 if (0 == cmn_ble_vsc_cb.adv_inst_max)
Satya Callojiffb39602014-04-30 15:55:39 -0700656 {
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
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700661
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700662 BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700663 if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD)
664 return BTM_ILLEGAL_VALUE;
665
666 memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
667
668 UINT8_TO_STREAM(pp, sub_code);
669 p_len = pp ++;
670 btm_ble_build_adv_data(&data_mask, &pp, p_data);
671 *p_len = (UINT8)(pp - param - 2);
672 UINT8_TO_STREAM(pp_temp, inst_id);
673
674 if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
675 (UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
676 param,
677 btm_ble_multi_adv_vsc_cmpl_cback))
678 == BTM_CMD_STARTED)
679 {
680 btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT);
681 }
682 return rt;
683}
684
685/*******************************************************************************
686**
687** Function BTM_BleDisableAdvInstance
688**
689** Description This function disables a Multi-ADV instance.
690**
691** Parameters inst_id: adv instance ID
692**
693** Returns status
694**
695*******************************************************************************/
696tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id)
697{
698 tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
Satya Callojic4e25962014-05-10 23:46:24 -0700699 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
Satya Callojiffb39602014-04-30 15:55:39 -0700700
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700701 BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
Satya Callojiffb39602014-04-30 15:55:39 -0700702
Satya Callojic4e25962014-05-10 23:46:24 -0700703 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
704
705 if (0 == cmn_ble_vsc_cb.adv_inst_max)
Satya Callojiffb39602014-04-30 15:55:39 -0700706 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700707 BTM_TRACE_ERROR("Controller does not support Multi ADV");
Satya Callojiffb39602014-04-30 15:55:39 -0700708 return BTM_ERR_PROCESSING;
709 }
710
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700711 if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
712 inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD)
Satya Callojiffb39602014-04-30 15:55:39 -0700713 {
714 if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT))
715 == BTM_CMD_STARTED)
716 {
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700717 btm_ble_multi_adv_configure_rpa(&btm_multi_adv_cb.p_adv_inst[inst_id-1]);
718 btu_stop_timer(&btm_multi_adv_cb.p_adv_inst[inst_id-1].raddr_timer_ent);
719 btm_multi_adv_cb.p_adv_inst[inst_id-1].inst_id = 0;
Satya Callojiffb39602014-04-30 15:55:39 -0700720 }
721 }
722 return rt;
723}
724/*******************************************************************************
725**
726** Function btm_ble_multi_adv_vse_cback
727**
728** Description VSE callback for multi adv events.
729**
730** Returns
731**
732*******************************************************************************/
733void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
734{
735 UINT8 sub_event;
Priti Aghera817eec22014-08-12 14:31:28 -0700736 UINT8 adv_inst, reason, conn_handle, idx;
Satya Callojiffb39602014-04-30 15:55:39 -0700737
738 /* Check if this is a BLE RSSI vendor specific event */
739 STREAM_TO_UINT8(sub_event, p);
740 len--;
741
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700742 BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event);
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700743 if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len >= 4))
Satya Callojiffb39602014-04-30 15:55:39 -0700744 {
745 STREAM_TO_UINT8(adv_inst, p);
746 STREAM_TO_UINT8(reason, p);
747 STREAM_TO_UINT16(conn_handle, p);
748
Priti Aghera817eec22014-08-12 14:31:28 -0700749 if ((idx = btm_handle_to_acl_index(conn_handle)) != MAX_L2CAP_LINKS)
750 {
751 if (btm_cb.ble_ctr_cb.privacy &&
752 adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD)
753 {
754 memcpy(btm_cb.acl_db[idx].conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa,
755 BD_ADDR_LEN);
756 }
757 }
758
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700759 if (adv_inst < BTM_BleMaxMultiAdvInstanceCount() &&
760 adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD)
Satya Callojiffb39602014-04-30 15:55:39 -0700761 {
Sharvil Nanavati83c52562014-05-04 00:46:57 -0700762 BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
Satya Callojiffb39602014-04-30 15:55:39 -0700763 btm_ble_multi_adv_reenable(adv_inst);
764 }
765 /* re-enable connectibility */
766 else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD)
767 {
768 if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE)
769 {
770 btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
Satya Callojiffb39602014-04-30 15:55:39 -0700771 }
772 }
773
774 }
775
776}
777/*******************************************************************************
778**
779** Function btm_ble_multi_adv_init
780**
781** Description This function initialize the multi adv control block.
782**
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700783** Parameters None
Satya Callojiffb39602014-04-30 15:55:39 -0700784**
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700785** Returns void
Satya Callojiffb39602014-04-30 15:55:39 -0700786**
787*******************************************************************************/
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700788void btm_ble_multi_adv_init()
Satya Callojiffb39602014-04-30 15:55:39 -0700789{
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700790 UINT8 i = 0;
Satya Callojiffb39602014-04-30 15:55:39 -0700791 memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700792 memset (&btm_multi_adv_idx_q,0, sizeof (tBTM_BLE_MULTI_ADV_INST_IDX_Q));
793 btm_multi_adv_idx_q.front = -1;
794 btm_multi_adv_idx_q.rear = -1;
Satya Callojiffb39602014-04-30 15:55:39 -0700795
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700796 if (btm_cb.cmn_ble_vsc_cb.adv_inst_max > 0)
797 {
798 btm_multi_adv_cb.p_adv_inst = GKI_getbuf( sizeof(tBTM_BLE_MULTI_ADV_INST)*
799 (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
800 memset(btm_multi_adv_cb.p_adv_inst, 0, sizeof(tBTM_BLE_MULTI_ADV_INST)*
801 (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
802
803 btm_multi_adv_cb.op_q.p_sub_code = GKI_getbuf( sizeof(UINT8) *
804 (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
805 memset(btm_multi_adv_cb.op_q.p_sub_code, 0,
806 sizeof(UINT8)*(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
807
808 btm_multi_adv_cb.op_q.p_inst_id = GKI_getbuf( sizeof(UINT8) *
809 (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
810 memset(btm_multi_adv_cb.op_q.p_inst_id, 0,
811 sizeof(UINT8)*(btm_cb.cmn_ble_vsc_cb.adv_inst_max));
812 }
813
814 for (i = 0; i < btm_cb.cmn_ble_vsc_cb.adv_inst_max ; i ++)
815 btm_multi_adv_cb.p_adv_inst[i].index = i;
Satya Callojiffb39602014-04-30 15:55:39 -0700816
817 BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
818}
Prerepa Viswanadham16fe0822014-08-07 11:38:06 -0700819
820/*******************************************************************************
821**
822** Function btm_ble_multi_adv_cleanup
823**
824** Description This function cleans up multi adv control block.
825**
826** Parameters
827** Returns void
828**
829*******************************************************************************/
830void btm_ble_multi_adv_cleanup(void)
831{
832 if (btm_multi_adv_cb.p_adv_inst)
833 GKI_freebuf(btm_multi_adv_cb.p_adv_inst);
834
835 if (btm_multi_adv_cb.op_q.p_sub_code)
836 GKI_freebuf(btm_multi_adv_cb.op_q.p_sub_code);
837
838 if (btm_multi_adv_cb.op_q.p_inst_id)
839 GKI_freebuf(btm_multi_adv_cb.op_q.p_inst_id);
840
841}
842
843/*******************************************************************************
844**
845** Function btm_ble_multi_adv_get_ref
846**
847** Description This function obtains the reference pointer for the instance ID provided
848**
849** Parameters inst_id - Instance ID
850**
851** Returns void*
852**
853*******************************************************************************/
854void* btm_ble_multi_adv_get_ref(UINT8 inst_id)
855{
856 tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
857
858 if (inst_id < BTM_BleMaxMultiAdvInstanceCount())
859 {
860 p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
861 if (NULL != p_inst)
862 return p_inst->p_ref;
863 }
864
865 return NULL;
866}
Satya Callojiffb39602014-04-30 15:55:39 -0700867#endif
868