btm_ble_multi_adv.c 31 KB

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