| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- /******************************************************************************
- *
- * Copyright (C) 2014 Broadcom Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
- #include <string.h>
- #include "common/bt_target.h"
- #include "device/controller.h"
- #if (BLE_INCLUDED == TRUE)
- #include "stack/bt_types.h"
- #include "stack/hcimsgs.h"
- #include "stack/btu.h"
- #include "btm_int.h"
- //#include "bt_utils.h"
- #include "stack/hcidefs.h"
- #include "stack/btm_ble_api.h"
- /************************************************************************************
- ** Constants & Macros
- ************************************************************************************/
- /* length of each multi adv sub command */
- #define BTM_BLE_MULTI_ADV_ENB_LEN 3
- #define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24
- #define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
- #define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
- #define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
- #define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
- /************************************************************************************
- ** Static variables
- ************************************************************************************/
- #if BTM_DYNAMIC_MEMORY == FALSE
- tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
- tBTM_BLE_MULTI_ADV_INST_IDX_Q btm_multi_adv_idx_q;
- #else
- tBTM_BLE_MULTI_ADV_CB *btm_multi_adv_cb_ptr;
- tBTM_BLE_MULTI_ADV_INST_IDX_Q *btm_multi_adv_idx_q_ptr;
- #define btm_multi_adv_cb (*btm_multi_adv_cb_ptr)
- #define btm_multi_adv_idx_q (*btm_multi_adv_idx_q_ptr)
- #endif
- /************************************************************************************
- ** Externs
- ************************************************************************************/
- extern void btm_ble_update_dmt_flag_bits(UINT8 *flag_value,
- const UINT16 connect_mode, const UINT16 disc_mode);
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_enq_op_q
- **
- ** Description enqueue a multi adv operation in q to check command complete
- ** status.
- **
- ** Returns void
- **
- *******************************************************************************/
- void btm_ble_multi_adv_enq_op_q(UINT8 opcode, UINT8 inst_id, UINT8 cb_evt)
- {
- tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
- p_op_q->p_inst_id[p_op_q->next_idx] = inst_id;
- p_op_q->p_sub_code[p_op_q->next_idx] = (opcode | (cb_evt << 4));
- p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_deq_op_q
- **
- ** Description dequeue a multi adv operation from q when command complete
- ** is received.
- **
- ** Returns void
- **
- *******************************************************************************/
- void btm_ble_multi_adv_deq_op_q(UINT8 *p_opcode, UINT8 *p_inst_id, UINT8 *p_cb_evt)
- {
- tBTM_BLE_MULTI_ADV_OPQ *p_op_q = &btm_multi_adv_cb.op_q;
- *p_inst_id = p_op_q->p_inst_id[p_op_q->pending_idx] & 0x7F;
- *p_cb_evt = (p_op_q->p_sub_code[p_op_q->pending_idx] >> 4);
- *p_opcode = (p_op_q->p_sub_code[p_op_q->pending_idx] & BTM_BLE_MULTI_ADV_SUBCODE_MASK);
- p_op_q->pending_idx = (p_op_q->pending_idx + 1) % BTM_BleMaxMultiAdvInstanceCount();
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_vsc_cmpl_cback
- **
- ** Description Multi adv VSC complete callback
- **
- ** Parameters
- **
- ** Returns void
- **
- *******************************************************************************/
- void btm_ble_multi_adv_vsc_cmpl_cback (tBTM_VSC_CMPL *p_params)
- {
- UINT8 status, subcode;
- UINT8 *p = p_params->p_param_buf, inst_id;
- UINT16 len = p_params->param_len;
- tBTM_BLE_MULTI_ADV_INST *p_inst ;
- UINT8 cb_evt = 0, opcode;
- if (len < 2) {
- BTM_TRACE_ERROR("wrong length for btm_ble_multi_adv_vsc_cmpl_cback");
- return;
- }
- STREAM_TO_UINT8(status, p);
- STREAM_TO_UINT8(subcode, p);
- btm_ble_multi_adv_deq_op_q(&opcode, &inst_id, &cb_evt);
- BTM_TRACE_DEBUG("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
- if (opcode != subcode || inst_id == 0) {
- BTM_TRACE_ERROR("get unexpected VSC cmpl, expect: %d get: %d", subcode, opcode);
- return;
- }
- p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
- switch (subcode) {
- case BTM_BLE_MULTI_ADV_ENB: {
- BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_ENB status = %d", status);
- /* Mark as not in use here, if instance cannot be enabled */
- if (HCI_SUCCESS != status && BTM_BLE_MULTI_ADV_ENB_EVT == cb_evt) {
- btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
- }
- break;
- }
- case BTM_BLE_MULTI_ADV_SET_PARAM: {
- BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
- break;
- }
- case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA: {
- BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
- break;
- }
- case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA: {
- BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
- break;
- }
- case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR: {
- BTM_TRACE_DEBUG("BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR status = %d", status);
- break;
- }
- default:
- break;
- }
- if (cb_evt != 0 && p_inst->p_cback != NULL) {
- (p_inst->p_cback)(cb_evt, inst_id, p_inst->p_ref, status);
- }
- return;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_enable_multi_adv
- **
- ** Description This function enable the customer specific feature in controller
- **
- ** Parameters enable: enable or disable
- ** inst_id: adv instance ID, can not be 0
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS btm_ble_enable_multi_adv (BOOLEAN enable, UINT8 inst_id, UINT8 cb_evt)
- {
- UINT8 param[BTM_BLE_MULTI_ADV_ENB_LEN], *pp;
- UINT8 enb = enable ? 1 : 0;
- tBTM_STATUS rt;
- pp = param;
- memset(param, 0, BTM_BLE_MULTI_ADV_ENB_LEN);
- UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_ENB);
- UINT8_TO_STREAM (pp, enb);
- UINT8_TO_STREAM (pp, inst_id);
- BTM_TRACE_EVENT (" btm_ble_enable_multi_adv: enb %d, Inst ID %d", enb, inst_id);
- if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
- BTM_BLE_MULTI_ADV_ENB_LEN,
- param,
- btm_ble_multi_adv_vsc_cmpl_cback))
- == BTM_CMD_STARTED) {
- btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_ENB, inst_id, cb_evt);
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_map_adv_tx_power
- **
- ** Description return the actual power in dBm based on the mapping in config file
- **
- ** Parameters advertise parameters used for this instance.
- **
- ** Returns tx power in dBm
- **
- *******************************************************************************/
- static const int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1] = BTM_BLE_ADV_TX_POWER;
- char btm_ble_map_adv_tx_power(int tx_power_index)
- {
- if (0 <= tx_power_index && tx_power_index <= BTM_BLE_ADV_TX_POWER_MAX) {
- return (char)btm_ble_tx_power[tx_power_index];
- }
- return 0;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_set_params
- **
- ** Description This function enable the customer specific feature in controller
- **
- ** Parameters advertise parameters used for this instance.
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS btm_ble_multi_adv_set_params (tBTM_BLE_MULTI_ADV_INST *p_inst,
- tBTM_BLE_ADV_PARAMS *p_params,
- UINT8 cb_evt)
- {
- UINT8 param[BTM_BLE_MULTI_ADV_SET_PARAM_LEN], *pp;
- tBTM_STATUS rt;
- BD_ADDR dummy = {0, 0, 0, 0, 0, 0};
- pp = param;
- memset(param, 0, BTM_BLE_MULTI_ADV_SET_PARAM_LEN);
- UINT8_TO_STREAM(pp, BTM_BLE_MULTI_ADV_SET_PARAM);
- UINT16_TO_STREAM (pp, p_params->adv_int_min);
- UINT16_TO_STREAM (pp, p_params->adv_int_max);
- UINT8_TO_STREAM (pp, p_params->adv_type);
- #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
- if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
- UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM);
- BDADDR_TO_STREAM (pp, p_inst->rpa);
- } else
- #endif
- {
- UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
- BDADDR_TO_STREAM (pp, controller_get_interface()->get_address()->address);
- }
- BTM_TRACE_EVENT (" btm_ble_multi_adv_set_params,Min %d, Max %d,adv_type %d",
- p_params->adv_int_min, p_params->adv_int_max, p_params->adv_type);
- UINT8_TO_STREAM (pp, 0);
- BDADDR_TO_STREAM (pp, dummy);
- if (p_params->channel_map == 0 || p_params->channel_map > BTM_BLE_DEFAULT_ADV_CHNL_MAP) {
- p_params->channel_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP;
- }
- UINT8_TO_STREAM (pp, p_params->channel_map);
- if (p_params->adv_filter_policy >= AP_SCAN_CONN_POLICY_MAX) {
- p_params->adv_filter_policy = AP_SCAN_CONN_ALL;
- }
- UINT8_TO_STREAM (pp, p_params->adv_filter_policy);
- UINT8_TO_STREAM (pp, p_inst->inst_id);
- if (p_params->tx_power > BTM_BLE_ADV_TX_POWER_MAX) {
- p_params->tx_power = BTM_BLE_ADV_TX_POWER_MAX;
- }
- UINT8_TO_STREAM (pp, btm_ble_map_adv_tx_power(p_params->tx_power));
- BTM_TRACE_EVENT("set_params:Chnl Map %d,adv_fltr policy %d,ID:%d, TX Power%d",
- p_params->channel_map, p_params->adv_filter_policy, p_inst->inst_id, p_params->tx_power);
- if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
- BTM_BLE_MULTI_ADV_SET_PARAM_LEN,
- param,
- btm_ble_multi_adv_vsc_cmpl_cback))
- == BTM_CMD_STARTED) {
- p_inst->adv_evt = p_params->adv_type;
- #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
- if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
- /* start timer */
- p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
- btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
- BTM_BLE_PRIVATE_ADDR_INT);
- }
- #endif
- btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_PARAM, p_inst->inst_id, cb_evt);
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_write_rpa
- **
- ** Description This function write the random address for the adv instance into
- ** controller
- **
- ** Parameters
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS btm_ble_multi_adv_write_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst, BD_ADDR random_addr)
- {
- UINT8 param[BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN], *pp = param;
- tBTM_STATUS rt;
- BTM_TRACE_EVENT ("%s-BD_ADDR:%02x-%02x-%02x-%02x-%02x-%02x,inst_id:%d",
- __FUNCTION__, random_addr[5], random_addr[4], random_addr[3], random_addr[2],
- random_addr[1], random_addr[0], p_inst->inst_id);
- memset(param, 0, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN);
- UINT8_TO_STREAM (pp, BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR);
- BDADDR_TO_STREAM(pp, random_addr);
- UINT8_TO_STREAM(pp, p_inst->inst_id);
- if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
- BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN,
- param,
- btm_ble_multi_adv_vsc_cmpl_cback)) == BTM_CMD_STARTED) {
- /* start a periodical timer to refresh random addr */
- btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
- p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
- btu_start_timer_oneshot(&p_inst->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
- BTM_BLE_PRIVATE_ADDR_INT);
- btm_ble_multi_adv_enq_op_q(BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR, p_inst->inst_id, 0);
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_gen_rpa_cmpl
- **
- ** Description RPA generation completion callback for each adv instance. Will
- ** continue write the new RPA into controller.
- **
- ** Returns none.
- **
- *******************************************************************************/
- void btm_ble_multi_adv_gen_rpa_cmpl(tBTM_RAND_ENC *p)
- {
- #if (SMP_INCLUDED == TRUE)
- tSMP_ENC output;
- UINT8 index = 0;
- tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
- /* Retrieve the index of adv instance from stored Q */
- if (btm_multi_adv_idx_q.front == -1) {
- BTM_TRACE_ERROR(" %s can't locate advertise instance", __FUNCTION__);
- return;
- } else {
- index = btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.front];
- if (btm_multi_adv_idx_q.front == btm_multi_adv_idx_q.rear) {
- btm_multi_adv_idx_q.front = -1;
- btm_multi_adv_idx_q.rear = -1;
- } else {
- btm_multi_adv_idx_q.front = (btm_multi_adv_idx_q.front + 1) % BTM_BLE_MULTI_ADV_MAX;
- }
- }
- p_inst = &(btm_multi_adv_cb.p_adv_inst[index]);
- BTM_TRACE_EVENT ("btm_ble_multi_adv_gen_rpa_cmpl inst_id = %d", p_inst->inst_id);
- if (p) {
- p->param_buf[2] &= (~BLE_RESOLVE_ADDR_MASK);
- p->param_buf[2] |= BLE_RESOLVE_ADDR_MSB;
- p_inst->rpa[2] = p->param_buf[0];
- p_inst->rpa[1] = p->param_buf[1];
- p_inst->rpa[0] = p->param_buf[2];
- if (!SMP_Encrypt(btm_cb.devcb.id_keys.irk, BT_OCTET16_LEN, p->param_buf, 3, &output)) {
- BTM_TRACE_DEBUG("generate random address failed");
- } else {
- /* set hash to be LSB of rpAddress */
- p_inst->rpa[5] = output.param_buf[0];
- p_inst->rpa[4] = output.param_buf[1];
- p_inst->rpa[3] = output.param_buf[2];
- }
- if (p_inst->inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
- p_inst->inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
- /* set it to controller */
- btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
- }
- }
- #endif
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_configure_rpa
- **
- ** Description This function set the random address for the adv instance
- **
- ** Parameters advertise parameters used for this instance.
- **
- ** Returns none
- **
- *******************************************************************************/
- void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst)
- {
- if (btm_multi_adv_idx_q.front == (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX) {
- BTM_TRACE_ERROR("outstanding rand generation exceeded max allowed ");
- return;
- } else {
- if (btm_multi_adv_idx_q.front == -1) {
- btm_multi_adv_idx_q.front = 0;
- btm_multi_adv_idx_q.rear = 0;
- } else {
- btm_multi_adv_idx_q.rear = (btm_multi_adv_idx_q.rear + 1) % BTM_BLE_MULTI_ADV_MAX;
- }
- btm_multi_adv_idx_q.inst_index_queue[btm_multi_adv_idx_q.rear] = p_inst->index;
- }
- btm_gen_resolvable_private_addr((void *)btm_ble_multi_adv_gen_rpa_cmpl);
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_reenable
- **
- ** Description This function re-enable adv instance upon a connection establishment.
- **
- ** Parameters advertise parameters used for this instance.
- **
- ** Returns none.
- **
- *******************************************************************************/
- void btm_ble_multi_adv_reenable(UINT8 inst_id)
- {
- tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
- if (TRUE == p_inst->in_use) {
- if (p_inst->adv_evt != BTM_BLE_CONNECT_DIR_EVT) {
- btm_ble_enable_multi_adv (TRUE, p_inst->inst_id, 0);
- } else
- /* mark directed adv as disabled if adv has been stopped */
- {
- (p_inst->p_cback)(BTM_BLE_MULTI_ADV_DISABLE_EVT, p_inst->inst_id, p_inst->p_ref, 0);
- p_inst->in_use = FALSE;
- }
- }
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_enb_privacy
- **
- ** Description This function enable/disable privacy setting in multi adv
- **
- ** Parameters enable: enable or disable the adv instance.
- **
- ** Returns none.
- **
- *******************************************************************************/
- void btm_ble_multi_adv_enb_privacy(BOOLEAN enable)
- {
- UINT8 i;
- tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
- for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
- p_inst->in_use = FALSE;
- if (enable) {
- btm_ble_multi_adv_configure_rpa (p_inst);
- } else {
- btu_stop_timer_oneshot(&p_inst->raddr_timer_ent);
- }
- }
- }
- /*******************************************************************************
- **
- ** Function BTM_BleEnableAdvInstance
- **
- ** Description This function enable a Multi-ADV instance with the specified
- ** adv parameters
- **
- ** Parameters p_params: pointer to the adv parameter structure, set as default
- ** adv parameter when the instance is enabled.
- ** p_cback: callback function for the adv instance.
- ** p_ref: reference data attach to the adv instance to be enabled.
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
- tBTM_BLE_MULTI_ADV_CBACK *p_cback, void *p_ref)
- {
- UINT8 i;
- tBTM_STATUS rt = BTM_NO_RESOURCES;
- tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[0];
- BTM_TRACE_EVENT("BTM_BleEnableAdvInstance called");
- if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
- BTM_TRACE_ERROR("Controller does not support Multi ADV");
- return BTM_ERR_PROCESSING;
- }
- if (NULL == p_inst) {
- BTM_TRACE_ERROR("Invalid instance in BTM_BleEnableAdvInstance");
- return BTM_ERR_PROCESSING;
- }
- for (i = 0; i < BTM_BleMaxMultiAdvInstanceCount() - 1; i ++, p_inst++) {
- if (FALSE == p_inst->in_use) {
- p_inst->in_use = TRUE;
- /* configure adv parameter */
- if (p_params) {
- rt = btm_ble_multi_adv_set_params(p_inst, p_params, 0);
- } else {
- rt = BTM_CMD_STARTED;
- }
- /* enable adv */
- BTM_TRACE_EVENT("btm_ble_enable_multi_adv being called with inst_id:%d",
- p_inst->inst_id);
- if (BTM_CMD_STARTED == rt) {
- if ((rt = btm_ble_enable_multi_adv (TRUE, p_inst->inst_id,
- BTM_BLE_MULTI_ADV_ENB_EVT)) == BTM_CMD_STARTED) {
- p_inst->p_cback = p_cback;
- p_inst->p_ref = p_ref;
- }
- }
- if (BTM_CMD_STARTED != rt) {
- p_inst->in_use = FALSE;
- BTM_TRACE_ERROR("BTM_BleEnableAdvInstance failed");
- }
- break;
- }
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function BTM_BleUpdateAdvInstParam
- **
- ** Description This function update a Multi-ADV instance with the specified
- ** adv parameters.
- **
- ** Parameters inst_id: adv instance ID
- ** p_params: pointer to the adv parameter structure.
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params)
- {
- tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
- tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
- BTM_TRACE_EVENT("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
- if (0 == btm_cb.cmn_ble_vsc_cb.adv_inst_max) {
- BTM_TRACE_ERROR("Controller does not support Multi ADV");
- return BTM_ERR_PROCESSING;
- }
- if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
- inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
- p_params != NULL) {
- if (FALSE == p_inst->in_use) {
- BTM_TRACE_DEBUG("adv instance %d is not active", inst_id);
- return BTM_WRONG_MODE;
- } else {
- btm_ble_enable_multi_adv(FALSE, inst_id, 0);
- }
- if (BTM_CMD_STARTED == btm_ble_multi_adv_set_params(p_inst, p_params, 0)) {
- rt = btm_ble_enable_multi_adv(TRUE, inst_id, BTM_BLE_MULTI_ADV_PARAM_EVT);
- }
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function BTM_BleCfgAdvInstData
- **
- ** Description This function configure a Multi-ADV instance with the specified
- ** adv data or scan response data.
- **
- ** Parameters inst_id: adv instance ID
- ** is_scan_rsp: is this scan response. if no, set as adv data.
- ** data_mask: adv data mask.
- ** p_data: pointer to the adv data structure.
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
- tBTM_BLE_AD_MASK data_mask,
- tBTM_BLE_ADV_DATA *p_data)
- {
- UINT8 param[BTM_BLE_MULTI_ADV_WRITE_DATA_LEN], *pp = param;
- UINT8 sub_code = (is_scan_rsp) ?
- BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA : BTM_BLE_MULTI_ADV_WRITE_ADV_DATA;
- UINT8 *p_len;
- tBTM_STATUS rt;
- UINT8 *pp_temp = (UINT8 *)(param + BTM_BLE_MULTI_ADV_WRITE_DATA_LEN - 1);
- tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
- BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
- if (0 == cmn_ble_vsc_cb.adv_inst_max) {
- BTM_TRACE_ERROR("Controller does not support Multi ADV");
- return BTM_ERR_PROCESSING;
- }
- btm_ble_update_dmt_flag_bits(&p_data->flag, btm_cb.btm_inq_vars.connectable_mode,
- btm_cb.btm_inq_vars.discoverable_mode);
- BTM_TRACE_EVENT("BTM_BleCfgAdvInstData called with inst_id:%d", inst_id);
- if (inst_id > BTM_BLE_MULTI_ADV_MAX || inst_id == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
- return BTM_ILLEGAL_VALUE;
- }
- memset(param, 0, BTM_BLE_MULTI_ADV_WRITE_DATA_LEN);
- UINT8_TO_STREAM(pp, sub_code);
- p_len = pp ++;
- btm_ble_build_adv_data(&data_mask, &pp, p_data);
- *p_len = (UINT8)(pp - param - 2);
- UINT8_TO_STREAM(pp_temp, inst_id);
- if ((rt = BTM_VendorSpecificCommand (HCI_BLE_MULTI_ADV_OCF,
- (UINT8)BTM_BLE_MULTI_ADV_WRITE_DATA_LEN,
- param,
- btm_ble_multi_adv_vsc_cmpl_cback))
- == BTM_CMD_STARTED) {
- btm_ble_multi_adv_enq_op_q(sub_code, inst_id, BTM_BLE_MULTI_ADV_DATA_EVT);
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function BTM_BleDisableAdvInstance
- **
- ** Description This function disables a Multi-ADV instance.
- **
- ** Parameters inst_id: adv instance ID
- **
- ** Returns status
- **
- *******************************************************************************/
- tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id)
- {
- tBTM_STATUS rt = BTM_ILLEGAL_VALUE;
- tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
- BTM_TRACE_EVENT("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
- BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
- if (0 == cmn_ble_vsc_cb.adv_inst_max) {
- BTM_TRACE_ERROR("Controller does not support Multi ADV");
- return BTM_ERR_PROCESSING;
- }
- if (inst_id < BTM_BleMaxMultiAdvInstanceCount() &&
- inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
- if ((rt = btm_ble_enable_multi_adv(FALSE, inst_id, BTM_BLE_MULTI_ADV_DISABLE_EVT))
- == BTM_CMD_STARTED) {
- btm_ble_multi_adv_configure_rpa(&btm_multi_adv_cb.p_adv_inst[inst_id - 1]);
- btu_stop_timer_oneshot(&btm_multi_adv_cb.p_adv_inst[inst_id - 1].raddr_timer_ent);
- btm_multi_adv_cb.p_adv_inst[inst_id - 1].in_use = FALSE;
- }
- }
- return rt;
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_vse_cback
- **
- ** Description VSE callback for multi adv events.
- **
- ** Returns
- **
- *******************************************************************************/
- void btm_ble_multi_adv_vse_cback(UINT8 len, UINT8 *p)
- {
- UINT8 sub_event;
- UINT8 adv_inst;
- UINT16 conn_handle;
- tACL_CONN *p_acl_cb = NULL;
- /* Check if this is a BLE RSSI vendor specific event */
- STREAM_TO_UINT8(sub_event, p);
- len--;
- BTM_TRACE_EVENT("btm_ble_multi_adv_vse_cback called with event:%d", sub_event);
- if ((sub_event == HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG) && (len >= 4)) {
- STREAM_TO_UINT8(adv_inst, p);
- ++p;
- STREAM_TO_UINT16(conn_handle, p);
- if ((p_acl_cb = btm_handle_to_acl(conn_handle)) != NULL) {
- #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
- if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE &&
- adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
- memcpy(p_acl_cb->conn_addr, btm_multi_adv_cb.p_adv_inst[adv_inst - 1].rpa,
- BD_ADDR_LEN);
- }
- #endif
- }
- if (adv_inst < BTM_BleMaxMultiAdvInstanceCount() &&
- adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD) {
- BTM_TRACE_EVENT("btm_ble_multi_adv_reenable called");
- btm_ble_multi_adv_reenable(adv_inst);
- }
- /* re-enable connectibility */
- else if (adv_inst == BTM_BLE_MULTI_ADV_DEFAULT_STD) {
- if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE) {
- btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode );
- }
- }
- }
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_init
- **
- ** Description This function initialize the multi adv control block.
- **
- ** Parameters None
- **
- ** Returns void
- **
- *******************************************************************************/
- void btm_ble_multi_adv_init(void)
- {
- #if BTM_DYNAMIC_MEMORY == TRUE
- btm_multi_adv_cb_ptr = (tBTM_BLE_MULTI_ADV_CB *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_CB));
- btm_multi_adv_idx_q_ptr = (tBTM_BLE_MULTI_ADV_INST_IDX_Q *)osi_malloc(sizeof(tBTM_BLE_MULTI_ADV_INST_IDX_Q));
- if (btm_multi_adv_cb_ptr == NULL || btm_multi_adv_idx_q_ptr == NULL) {
- BTM_TRACE_ERROR("%s malloc failed", __func__);
- return;
- }
- #endif
- UINT8 i = 0;
- memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
- memset (&btm_multi_adv_idx_q, 0, sizeof (tBTM_BLE_MULTI_ADV_INST_IDX_Q));
- btm_multi_adv_idx_q.front = -1;
- btm_multi_adv_idx_q.rear = -1;
- if (btm_cb.cmn_ble_vsc_cb.adv_inst_max > 0) {
- btm_multi_adv_cb.p_adv_inst = osi_malloc( sizeof(tBTM_BLE_MULTI_ADV_INST) *
- (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- memset(btm_multi_adv_cb.p_adv_inst, 0, sizeof(tBTM_BLE_MULTI_ADV_INST) *
- (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- btm_multi_adv_cb.op_q.p_sub_code = osi_malloc( sizeof(UINT8) *
- (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- memset(btm_multi_adv_cb.op_q.p_sub_code, 0,
- sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- btm_multi_adv_cb.op_q.p_inst_id = osi_malloc( sizeof(UINT8) *
- (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- memset(btm_multi_adv_cb.op_q.p_inst_id, 0,
- sizeof(UINT8) * (btm_cb.cmn_ble_vsc_cb.adv_inst_max));
- }
- /* Initialize adv instance indices and IDs. */
- for (i = 0; i < btm_cb.cmn_ble_vsc_cb.adv_inst_max; i++) {
- btm_multi_adv_cb.p_adv_inst[i].index = i;
- btm_multi_adv_cb.p_adv_inst[i].inst_id = i + 1;
- }
- BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_cleanup
- **
- ** Description This function cleans up multi adv control block.
- **
- ** Parameters
- ** Returns void
- **
- *******************************************************************************/
- void btm_ble_multi_adv_cleanup(void)
- {
- if (btm_multi_adv_cb.p_adv_inst) {
- osi_free(btm_multi_adv_cb.p_adv_inst);
- btm_multi_adv_cb.p_adv_inst = NULL;
- }
- if (btm_multi_adv_cb.op_q.p_sub_code) {
- osi_free(btm_multi_adv_cb.op_q.p_sub_code);
- btm_multi_adv_cb.op_q.p_sub_code = NULL;
- }
- if (btm_multi_adv_cb.op_q.p_inst_id) {
- osi_free(btm_multi_adv_cb.op_q.p_inst_id);
- btm_multi_adv_cb.op_q.p_inst_id = NULL;
- }
- #if BTM_DYNAMIC_MEMORY == TRUE
- if(btm_multi_adv_cb_ptr) {
- osi_free(btm_multi_adv_cb_ptr);
- btm_multi_adv_cb_ptr = NULL;
- }
- if(btm_multi_adv_idx_q_ptr) {
- osi_free(btm_multi_adv_idx_q_ptr);
- btm_multi_adv_idx_q_ptr = NULL;
- }
- #endif
- }
- /*******************************************************************************
- **
- ** Function btm_ble_multi_adv_get_ref
- **
- ** Description This function obtains the reference pointer for the instance ID provided
- **
- ** Parameters inst_id - Instance ID
- **
- ** Returns void*
- **
- *******************************************************************************/
- void *btm_ble_multi_adv_get_ref(UINT8 inst_id)
- {
- tBTM_BLE_MULTI_ADV_INST *p_inst = NULL;
- if (inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
- p_inst = &btm_multi_adv_cb.p_adv_inst[inst_id - 1];
- if (NULL != p_inst) {
- return p_inst->p_ref;
- }
- }
- return NULL;
- }
- #endif
|