btm_ble_multi_adv.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /******************************************************************************
  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. #include <string.h>
  19. #include "bt_target.h"
  20. #include "controller.h"
  21. #if (BLE_INCLUDED == TRUE)
  22. #include "bt_types.h"
  23. #include "hcimsgs.h"
  24. #include "btu.h"
  25. #include "btm_int.h"
  26. //#include "bt_utils.h"
  27. #include "hcidefs.h"
  28. #include "btm_ble_api.h"
  29. /************************************************************************************
  30. ** Constants & Macros
  31. ************************************************************************************/
  32. /* length of each multi adv sub command */
  33. #define BTM_BLE_MULTI_ADV_ENB_LEN 3
  34. #define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
  35. #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. #define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
  38. #define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
  39. /************************************************************************************
  40. ** Static variables
  41. ************************************************************************************/
  42. tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
  43. tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q;
  44. /************************************************************************************
  45. ** Externs
  46. ************************************************************************************/
  47. extern void btm_ble_update_dmt_flag_bits(UINT8 *flag_value,
  48. const UINT16 connect_mode, const UINT16 disc_mode);
  49. /*******************************************************************************
  50. **
  51. ** Function btm_ble_multi_adv_enq_op_q
  52. **
  53. ** Description enqueue a multi adv operation in q to check command complete
  54. ** status.
  55. **
  56. ** Returns void
  57. **
  58. *******************************************************************************/
  59. void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt)
  60. {
  61. tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
  62. p_op_q->p_inst_id[p_op_q->next_idx] = inst_id;
  63. p_op_q->p_sub_code[p_op_q->next_idx] = (opcode | (cb_evt << 4));
  64. p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
  65. }
  66. /*******************************************************************************
  67. **
  68. ** Function btm_ble_multi_adv_deq_op_q
  69. **
  70. ** Description dequeue a multi adv operation from q when command complete
  71. ** is received.
  72. **
  73. ** Returns void
  74. **
  75. *******************************************************************************/
  76. void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt)
  77. {
  78. tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
  79. *p_inst_id = p_op_q->p_inst_id[p_op_q->pending_idx] & 0x7F;
  80. *p_cb_evt = (p_op_q->p_sub_code[p_op_q->pending_idx] >> 4);
  81. *p_opcode = (p_op_q->p_sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK);
  82. p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
  83. }
  84. /*******************************************************************************
  85. **
  86. ** Function btm_ble_multi_adv_vsc_cmpl_cback
  87. **
  88. ** Description Multi adv VSC complete callback
  89. **
  90. ** Parameters
  91. **
  92. ** Returns void
  93. **
  94. *******************************************************************************/
  95. void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params)
  96. {
  97. UINT8 status, subcode;
  98. UINT8 *p = p_params->p_param_buf, inst_id;
  99. UINT16 len = p_params->param_len;
  100. tBTM_BLE_MULTI_ADV_INST *p_inst ;
  101. UINT8 cb_evt = 0, opcode;
  102. if (len < 2) {
  103. BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback");
  104. return;
  105. }
  106. STREAM_TO_UINT8(status, p);
  107. STREAM_TO_UINT8(subcode, p);
  108. btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt);
  109. BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
  110. if (opcode != subcode || inst_id == 0) {
  111. BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d", subcode, opcode);
  112. return;
  113. }
  114. p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
  115. switch (subcode) {
  116. case BTM_BLE_MULTI_ADV_ENB: {
  117. BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status);
  118. /* Mark as not in use here, if instance cannot be enabled */
  119. if (HCI_SUCCESS != status && BTM_BLE_MULTI_ADV_ENB_EVT == cb_evt) {
  120. btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
  121. }
  122. break;
  123. }
  124. case BTM_BLE_MULTI_ADV_SET_PARAM: {
  125. BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
  126. break;
  127. }
  128. case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA: {
  129. BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
  130. break;
  131. }
  132. case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA: {
  133. BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
  134. break;
  135. }
  136. case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR: {
  137. BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status);
  138. break;
  139. }
  140. default:
  141. break;
  142. }
  143. if (cb_evt != 0 && p_inst->p_cback != NULL) {
  144. (p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status);
  145. }
  146. return;
  147. }
  148. /*******************************************************************************
  149. **
  150. ** Function btm_ble_enable_multi_adv
  151. **
  152. ** Description This function enable the customer specific feature in controller
  153. **
  154. ** Parameters enable: enable or disable
  155. ** inst_id: adv instance ID, can not be 0
  156. **
  157. ** Returns status
  158. **
  159. *******************************************************************************/
  160. tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt)
  161. {
  162. UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp;
  163. UINT8 enb = enable ? 1 : 0;
  164. tBTM_STATUS rt;
  165. pp = param;
  166. memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
  167. UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB);
  168. UINT8_TO_STREAM (pp, enb);
  169. UINT8_TO_STREAM (pp, inst_id);
  170. BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d", enb, inst_id);
  171. if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
  172. BTM_BLE_MULTI_ADV_ENB_LEN,
  173. param,
  174. btm_ble_multi_adv_vsc_cmpl_cback))
  175. == BTM_CMD_STARTED) {
  176. btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt);
  177. }
  178. return rt;
  179. }
  180. /*******************************************************************************
  181. **
  182. ** Function btm_ble_map_adv_tx_power
  183. **
  184. ** Description return the actual power in dBm based on the mapping in config file
  185. **
  186. ** Parameters advertise parameters used for this instance.
  187. **
  188. ** Returns tx power in dBm
  189. **
  190. *******************************************************************************/
  191. int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
  192. char btm_ble_map_adv_tx_power(int tx_power_index)
  193. {
  194. if (0 <= tx_power_index && tx_power_index < BTM_BLE_ADV_TX_POWER_MAX) {
  195. return (char)btm_ble_tx_power[tx_power_index];
  196. }
  197. return 0;
  198. }
  199. /*******************************************************************************
  200. **
  201. ** Function btm_ble_multi_adv_set_params
  202. **
  203. ** Description This function enable the customer specific feature in controller
  204. **
  205. ** Parameters advertise parameters used for this instance.
  206. **
  207. ** Returns status
  208. **
  209. *******************************************************************************/
  210. tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst,
  211. tBTM_BLE_ADV_PARAMS *p_params,
  212. UINT8 cb_evt)
  213. {
  214. UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp;
  215. tBTM_STATUS rt;
  216. BD_ADDR dummy = {0, 0, 0, 0, 0, 0};
  217. pp = param;
  218. memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
  219. UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
  220. UINT16_TO_STREAM (pp, p_params->adv_int_min);
  221. UINT16_TO_STREAM (pp, p_params->adv_int_max);
  222. UINT8_TO_STREAM (pp, p_params->adv_type);
  223. #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
  224. if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
  225. UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM);
  226. BDADDR_TO_STREAM (pp, p_inst->rpa);
  227. } else
  228. #endif
  229. {
  230. UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
  231. BDADDR_TO_STREAM (pp, controller_get_interface()->get_address()->address);
  232. }
  233. BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d",
  234. p_params->adv_int_min, p_params->adv_int_max, p_params->adv_type);
  235. UINT8_TO_STREAM (pp, 0);
  236. BDADDR_TO_STREAM (pp, dummy);
  237. if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP) {
  238. p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
  239. }
  240. UINT8_TO_STREAM (pp, p_params->channel_map);
  241. if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX) {
  242. p_params->adv_filter_policy = AP_SCAN_CONN_ALL;
  243. }
  244. UINT8_TO_STREAM (pp, p_params->adv_filter_policy);
  245. UINT8_TO_STREAM (pp, p_inst->inst_id);
  246. if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX) {
  247. p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX;
  248. }
  249. UINT8_TO_STREAM (pp, btm_ble_map_adv_tx_power(p_params->tx_power));
  250. BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d",
  251. p_params->channel_map, p_params->adv_filter_policy, p_inst->inst_id, p_params->tx_power);
  252. if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
  253. BTM_BLE_MULTI_ADV_SET_PARAM_LEN,
  254. param,
  255. btm_ble_multi_adv_vsc_cmpl_cback))
  256. == BTM_CMD_STARTED) {
  257. p_inst->adv_evt = p_params->adv_type;
  258. #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
  259. if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
  260. /* start timer */
  261. p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
  262. btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
  263. BTM_BLE_PRIVATE_ADDR_INT);
  264. }
  265. #endif
  266. btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt);
  267. }
  268. return rt;
  269. }
  270. /*******************************************************************************
  271. **
  272. ** Function btm_ble_multi_adv_write_rpa
  273. **
  274. ** Description This function write the random address for the adv instance into
  275. ** controller
  276. **
  277. ** Parameters
  278. **
  279. ** Returns status
  280. **
  281. *******************************************************************************/
  282. tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr)
  283. {
  284. UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param;
  285. tBTM_STATUS rt;
  286. BTM_TRACE_EVENT ("%s-BD_ADDR:%02x-%02x-%02x-%02x-%02x-%02x,inst_id:%d",
  287. __FUNCTION__, random_addr[5], random_addr[4], random_addr[3], random_addr[2],
  288. random_addr[1], random_addr[0], p_inst->inst_id);
  289. memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
  290. UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
  291. BDADDR_TO_STREAM(pp, random_addr);
  292. UINT8_TO_STREAM(pp, p_inst->inst_id);
  293. if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
  294. BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN,
  295. param,
  296. btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED) {
  297. /* start a periodical timer to refresh random addr */
  298. btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
  299. p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
  300. btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
  301. BTM_BLE_PRIVATE_ADDR_INT);
  302. btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0);
  303. }
  304. return rt;
  305. }
  306. /*******************************************************************************
  307. **
  308. ** Function btm_ble_multi_adv_gen_rpa_cmpl
  309. **
  310. ** Description RPA generation completion callback for each adv instance. Will
  311. ** continue write the new RPA into controller.
  312. **
  313. ** Returns none.
  314. **
  315. *******************************************************************************/
  316. void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p)
  317. {
  318. #if (SMP_INCLUDED == TRUE)
  319. tSMP_ENC output;
  320. UINT8 index = 0;
  321. tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
  322. /* Retrieve the index of adv instance from stored Q */
  323. if (btm_multi_adv_idx_q.front == -1) {
  324. BTM_TRACE_ERROR(" %s can't locate advertise instance", __FUNCTION__);
  325. return;
  326. } else {
  327. index = btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.front];
  328. if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear) {
  329. btm_multi_adv_idx_q.front = -1;
  330. btm_multi_adv_idx_q.rear = -1;
  331. } else {
  332. btm_multi_adv_idx_q.front = (btm_multi_adv_idx_q.front + 1) % BTM_BLE_MULTI_ADV_MAX;
  333. }
  334. }
  335. p_inst = &(btm_multi_adv_cb.p_adv_inst[index]);
  336. BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id);
  337. if (p) {
  338. p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
  339. p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
  340. p_inst->rpa[2] = p->param_buf[0];
  341. p_inst->rpa[1] = p->param_buf[1];
  342. p_inst->rpa[0] = p->param_buf[2];
  343. if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output)) {
  344. BTM_TRACE_DEBUG("generate random address failed");
  345. } else {
  346. /* set hash to be LSB of rpAddress */
  347. p_inst->rpa[5] = output.param_buf[0];
  348. p_inst->rpa[4] = output.param_buf[1];
  349. p_inst->rpa[3] = output.param_buf[2];
  350. }
  351. if (p_inst->inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
  352. p_inst->inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
  353. /* set it to controller */
  354. btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
  355. }
  356. }
  357. #endif
  358. }
  359. /*******************************************************************************
  360. **
  361. ** Function btm_ble_multi_adv_configure_rpa
  362. **
  363. ** Description This function set the random address for the adv instance
  364. **
  365. ** Parameters advertise parameters used for this instance.
  366. **
  367. ** Returns none
  368. **
  369. *******************************************************************************/
  370. void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst)
  371. {
  372. if (btm_multi_adv_idx_q.front == (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX) {
  373. BTM_TRACE_ERROR("outstanding rand generation exceeded max allowed ");
  374. return;
  375. } else {
  376. if (btm_multi_adv_idx_q.front == -1) {
  377. btm_multi_adv_idx_q.front = 0;
  378. btm_multi_adv_idx_q.rear = 0;
  379. } else {
  380. btm_multi_adv_idx_q.rear = (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX;
  381. }
  382. btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.rear] = p_inst->index;
  383. }
  384. btm_gen_resolvable_private_addr((void *)btm_ble_multi_adv_gen_rpa_cmpl);
  385. }
  386. /*******************************************************************************
  387. **
  388. ** Function btm_ble_multi_adv_reenable
  389. **
  390. ** Description This function re-enable adv instance upon a connection establishment.
  391. **
  392. ** Parameters advertise parameters used for this instance.
  393. **
  394. ** Returns none.
  395. **
  396. *******************************************************************************/
  397. void btm_ble_multi_adv_reenable(UINT8 inst_id)
  398. {
  399. tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
  400. if (TRUE == p_inst->in_use) {
  401. if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT) {
  402. btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0);
  403. } else
  404. /* mark directed adv as disabled if adv has been stopped */
  405. {
  406. (p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT, p_inst->inst_id, p_inst->p_ref, 0);
  407. p_inst->in_use = FALSE;
  408. }
  409. }
  410. }
  411. /*******************************************************************************
  412. **
  413. ** Function btm_ble_multi_adv_enb_privacy
  414. **
  415. ** Description This function enable/disable privacy setting in multi adv
  416. **
  417. ** Parameters enable: enable or disable the adv instance.
  418. **
  419. ** Returns none.
  420. **
  421. *******************************************************************************/
  422. void btm_ble_multi_adv_enb_privacy(BOOLEAN enable)
  423. {
  424. UINT8 i;
  425. tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
  426. for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
  427. p_inst->in_use = FALSE;
  428. if (enable) {
  429. btm_ble_multi_adv_configure_rpa (p_inst);
  430. } else {
  431. btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
  432. }
  433. }
  434. }
  435. /*******************************************************************************
  436. **
  437. ** Function BTM_BleEnableAdvInstance
  438. **
  439. ** Description This function enable a Multi-ADV instance with the specified
  440. ** adv parameters
  441. **
  442. ** Parameters p_params: pointer to the adv parameter structure, set as default
  443. ** adv parameter when the instance is enabled.
  444. ** p_cback: callback function for the adv instance.
  445. ** p_ref: reference data attach to the adv instance to be enabled.
  446. **
  447. ** Returns status
  448. **
  449. *******************************************************************************/
  450. tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
  451. tBTM_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref)
  452. {
  453. UINT8 i;
  454. tBTM_STATUS rt = BTM_NO_RESOURCES;
  455. tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
  456. BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called");
  457. if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
  458. BTM_TRACE_ERROR("Controller does not support Multi ADV");
  459. return BTM_ERR_PROCESSING;
  460. }
  461. if (NULL == p_inst) {
  462. BTM_TRACE_ERROR("Invalid instance in BTM_BleEnableAdvInstance");
  463. return BTM_ERR_PROCESSING;
  464. }
  465. for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
  466. if (FALSE == p_inst->in_use) {
  467. p_inst->in_use = TRUE;
  468. /* configure adv parameter */
  469. if (p_params) {
  470. rt = btm_ble_multi_adv_set_params(p_inst, p_params, 0);
  471. } else {
  472. rt = BTM_CMD_STARTED;
  473. }
  474. /* enable adv */
  475. BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d",
  476. p_inst->inst_id);
  477. if (BTM_CMD_STARTED == rt) {
  478. if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id,
  479. BTM_BLE_MULTI_ADV_ENB_EVT)) == BTM_CMD_STARTED) {
  480. p_inst->p_cback = p_cback;
  481. p_inst->p_ref = p_ref;
  482. }
  483. }
  484. if (BTM_CMD_STARTED != rt) {
  485. p_inst->in_use = FALSE;
  486. BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed");
  487. }
  488. break;
  489. }
  490. }
  491. return rt;
  492. }
  493. /*******************************************************************************
  494. **
  495. ** Function BTM_BleUpdateAdvInstParam
  496. **
  497. ** Description This function update a Multi-ADV instance with the specified
  498. ** adv parameters.
  499. **
  500. ** Parameters inst_id: adv instance ID
  501. ** p_params: pointer to the adv parameter structure.
  502. **
  503. ** Returns status
  504. **
  505. *******************************************************************************/
  506. tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params)
  507. {
  508. tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
  509. tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
  510. BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
  511. if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
  512. BTM_TRACE_ERROR("Controller does not support Multi ADV");
  513. return BTM_ERR_PROCESSING;
  514. }
  515. if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
  516. inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
  517. p_params != NULL) {
  518. if (FALSE == p_inst->in_use) {
  519. BTM_TRACE_DEBUG("adv instance %d is not active", inst_id);
  520. return BTM_WRONG_MODE;
  521. } else {
  522. btm_ble_enable_multi_adv(FALSE, inst_id, 0);
  523. }
  524. if (BTM_CMD_STARTED == btm_ble_multi_adv_set_params(p_inst, p_params, 0)) {
  525. rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT);
  526. }
  527. }
  528. return rt;
  529. }
  530. /*******************************************************************************
  531. **
  532. ** Function BTM_BleCfgAdvInstData
  533. **
  534. ** Description This function configure a Multi-ADV instance with the specified
  535. ** adv data or scan response data.
  536. **
  537. ** Parameters inst_id: adv instance ID
  538. ** is_scan_rsp: is this scan response. if no, set as adv data.
  539. ** data_mask: adv data mask.
  540. ** p_data: pointer to the adv data structure.
  541. **
  542. ** Returns status
  543. **
  544. *******************************************************************************/
  545. tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
  546. tBTM_BLE_AD_MASK data_mask,
  547. tBTM_BLE_ADV_DATA *p_data)
  548. {
  549. UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param;
  550. UINT8 sub_code = (is_scan_rsp) ?
  551. BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA;
  552. UINT8 *p_len;
  553. tBTM_STATUS rt;
  554. UINT8 *pp_temp = (UINT8 *)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1);
  555. tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
  556. BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
  557. if (0 == cmn_ble_vsc_cb.adv_inst_max) {
  558. BTM_TRACE_ERROR("Controller does not support Multi ADV");
  559. return BTM_ERR_PROCESSING;
  560. }
  561. btm_ble_update_dmt_flag_bits(&p_data->flag, btm_cb.btm_inq_vars.connectable_mode,
  562. btm_cb.btm_inq_vars.discoverable_mode);
  563. BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id);
  564. if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
  565. return BTM_ILLEGAL_VALUE;
  566. }
  567. memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
  568. UINT8_TO_STREAM(pp, sub_code);
  569. p_len = pp ++;
  570. btm_ble_build_adv_data(&data_mask, &pp, p_data);
  571. *p_len = (UINT8)(pp - param - 2);
  572. UINT8_TO_STREAM(pp_temp, inst_id);
  573. if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
  574. (UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
  575. param,
  576. btm_ble_multi_adv_vsc_cmpl_cback))
  577. == BTM_CMD_STARTED) {
  578. btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT);
  579. }
  580. return rt;
  581. }
  582. /*******************************************************************************
  583. **
  584. ** Function BTM_BleDisableAdvInstance
  585. **
  586. ** Description This function disables a Multi-ADV instance.
  587. **
  588. ** Parameters inst_id: adv instance ID
  589. **
  590. ** Returns status
  591. **
  592. *******************************************************************************/
  593. tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id)
  594. {
  595. tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
  596. tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
  597. BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
  598. BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
  599. if (0 == cmn_ble_vsc_cb.adv_inst_max) {
  600. BTM_TRACE_ERROR("Controller does not support Multi ADV");
  601. return BTM_ERR_PROCESSING;
  602. }
  603. if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
  604. inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
  605. if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT))
  606. == BTM_CMD_STARTED) {
  607. btm_ble_multi_adv_configure_rpa(&btm_multi_adv_cb.p_adv_inst[inst_id - 1]);
  608. btu_stop_timer_oneshot(&btm_multi_adv_cb.p_adv_inst[inst_id - 1].raddr_timer_ent);
  609. btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
  610. }
  611. }
  612. return rt;
  613. }
  614. /*******************************************************************************
  615. **
  616. ** Function btm_ble_multi_adv_vse_cback
  617. **
  618. ** Description VSE callback for multi adv events.
  619. **
  620. ** Returns
  621. **
  622. *******************************************************************************/
  623. void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
  624. {
  625. UINT8 sub_event;
  626. UINT8 adv_inst, idx;
  627. UINT16 conn_handle;
  628. /* Check if this is a BLE RSSI vendor specific event */
  629. STREAM_TO_UINT8(sub_event, p);
  630. len--;
  631. BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event);
  632. if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len >= 4)) {
  633. STREAM_TO_UINT8(adv_inst, p);
  634. ++p;
  635. STREAM_TO_UINT16(conn_handle, p);
  636. if ((idx = btm_handle_to_acl_index(conn_handle)) != MAX_L2CAP_LINKS) {
  637. #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
  638. if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE &&
  639. adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
  640. memcpy(btm_cb.acl_db[idx].conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa,
  641. BD_ADDR_LEN);
  642. }
  643. #endif
  644. }
  645. if (adv_inst < BTM_BleMaxMultiAdvInstanceCount() &&
  646. adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
  647. BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
  648. btm_ble_multi_adv_reenable(adv_inst);
  649. }
  650. /* re-enable connectibility */
  651. else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
  652. if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) {
  653. btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
  654. }
  655. }
  656. }
  657. }
  658. /*******************************************************************************
  659. **
  660. ** Function btm_ble_multi_adv_init
  661. **
  662. ** Description This function initialize the multi adv control block.
  663. **
  664. ** Parameters None
  665. **
  666. ** Returns void
  667. **
  668. *******************************************************************************/
  669. void btm_ble_multi_adv_init()
  670. {
  671. UINT8 i = 0;
  672. memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
  673. memset (&btm_multi_adv_idx_q, 0, sizeof (tBTM_BLE_MULTI_ADV_INST_IDX_Q));
  674. btm_multi_adv_idx_q.front = -1;
  675. btm_multi_adv_idx_q.rear = -1;
  676. if (btm_cb.cmn_ble_vsc_cb.adv_inst_max > 0) {
  677. btm_multi_adv_cb.p_adv_inst = GKI_getbuf( sizeof(tBTM_BLE_MULTI_ADV_INST) *
  678. (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  679. memset(btm_multi_adv_cb.p_adv_inst, 0, sizeof(tBTM_BLE_MULTI_ADV_INST) *
  680. (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  681. btm_multi_adv_cb.op_q.p_sub_code = GKI_getbuf( sizeof(UINT8) *
  682. (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  683. memset(btm_multi_adv_cb.op_q.p_sub_code, 0,
  684. sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  685. btm_multi_adv_cb.op_q.p_inst_id = GKI_getbuf( sizeof(UINT8) *
  686. (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  687. memset(btm_multi_adv_cb.op_q.p_inst_id, 0,
  688. sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
  689. }
  690. /* Initialize adv instance indices and IDs. */
  691. for (i = 0; i < btm_cb.cmn_ble_vsc_cb.adv_inst_max; i++) {
  692. btm_multi_adv_cb.p_adv_inst[i].index = i;
  693. btm_multi_adv_cb.p_adv_inst[i].inst_id = i + 1;
  694. }
  695. BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
  696. }
  697. /*******************************************************************************
  698. **
  699. ** Function btm_ble_multi_adv_cleanup
  700. **
  701. ** Description This function cleans up multi adv control block.
  702. **
  703. ** Parameters
  704. ** Returns void
  705. **
  706. *******************************************************************************/
  707. void btm_ble_multi_adv_cleanup(void)
  708. {
  709. if (btm_multi_adv_cb.p_adv_inst) {
  710. GKI_freebuf(btm_multi_adv_cb.p_adv_inst);
  711. }
  712. if (btm_multi_adv_cb.op_q.p_sub_code) {
  713. GKI_freebuf(btm_multi_adv_cb.op_q.p_sub_code);
  714. }
  715. if (btm_multi_adv_cb.op_q.p_inst_id) {
  716. GKI_freebuf(btm_multi_adv_cb.op_q.p_inst_id);
  717. }
  718. }
  719. /*******************************************************************************
  720. **
  721. ** Function btm_ble_multi_adv_get_ref
  722. **
  723. ** Description This function obtains the reference pointer for the instance ID provided
  724. **
  725. ** Parameters inst_id - Instance ID
  726. **
  727. ** Returns void*
  728. **
  729. *******************************************************************************/
  730. void *btm_ble_multi_adv_get_ref(UINT8 inst_id)
  731. {
  732. tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
  733. if (inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
  734. p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
  735. if (NULL != p_inst) {
  736. return p_inst->p_ref;
  737. }
  738. }
  739. return NULL;
  740. }
  741. #endif