** Static functions
********************************************************************************/
+static bt_status_t btif_gattc_multi_adv_disable(int client_if);
+static void btif_multi_adv_stop_cb(void *data)
+{
+ int client_if = (int)data;
+ btif_gattc_multi_adv_disable(client_if); // Does context switch
+}
+
static void btapp_gattc_req_data(UINT16 event, char *p_dest, char *p_src)
{
tBTA_GATTC *p_dest_data = (tBTA_GATTC*) p_dest;
, p_btif_cb->client_if
, p_btif_cb->status
);
+ btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
+ (p_btif_cb->status==0 ? btif_multi_adv_stop_cb : NULL));
break;
}
, p_btif_cb->client_if
, p_btif_cb->status
);
+ btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
+ (p_btif_cb->status==0 ? btif_multi_adv_stop_cb : NULL));
break;
}
break;
case BTIF_GATTC_UNREGISTER_APP:
+ btif_gattc_clear_clientif(p_cb->client_if);
btif_gattc_destroy_multi_adv_cb();
BTA_GATTC_AppDeregister(p_cb->client_if);
break;
}
static bt_status_t btif_gattc_multi_adv_enable(int client_if, int min_interval, int max_interval,
- int adv_type, int chnl_map, int tx_power)
+ int adv_type, int chnl_map, int tx_power, int timeout_s)
{
CHECK_BTGATT_INIT();
btgatt_multi_adv_inst_cb adv_cb;
adv_cb.param.channel_map = chnl_map;
adv_cb.param.adv_filter_policy = 0;
adv_cb.param.tx_power = tx_power;
+ adv_cb.timeout_s = timeout_s;
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_ENABLE,
(char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
}
static bt_status_t btif_gattc_multi_adv_update(int client_if, int min_interval, int max_interval,
- int adv_type, int chnl_map,int tx_power)
+ int adv_type, int chnl_map,int tx_power, int timeout_s)
{
CHECK_BTGATT_INIT();
btgatt_multi_adv_inst_cb adv_cb;
adv_cb.param.channel_map = chnl_map;
adv_cb.param.adv_filter_policy = 0;
adv_cb.param.tx_power = tx_power;
+ adv_cb.timeout_s = timeout_s;
return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_UPDATE,
(char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
}
static bt_status_t btif_gattc_multi_adv_setdata(int client_if, bool set_scan_rsp,
- bool include_name, bool incl_txpower,
- int appearance, uint16_t manufacturer_len,
- char* manufacturer_data,
- uint16_t service_data_len,
- char* service_data, uint16_t service_uuid_len,
- char* service_uuid)
+ bool include_name, bool incl_txpower, int appearance,
+ int manufacturer_len, char* manufacturer_data,
+ int service_data_len, char* service_data,
+ int service_uuid_len, char* service_uuid)
{
CHECK_BTGATT_INIT();
p_multi_adv_com_data_cb = GKI_getbuf(sizeof(btgatt_multi_adv_common_data));
if (NULL != p_multi_adv_com_data_cb)
{
- memset(p_multi_adv_com_data_cb, 0, sizeof(btgatt_multi_adv_common_data));
+ memset(p_multi_adv_com_data_cb, 0, sizeof(btgatt_multi_adv_common_data));
- /* Storing both client_if and inst_id details */
- p_multi_adv_com_data_cb->clntif_map =
+ /* Storing both client_if and inst_id details */
+ p_multi_adv_com_data_cb->clntif_map =
GKI_getbuf(( BTM_BleMaxMultiAdvInstanceCount() * INST_ID_IDX_MAX)* sizeof(INT8));
- memset(p_multi_adv_com_data_cb->clntif_map, 0 ,
+ memset(p_multi_adv_com_data_cb->clntif_map, 0 ,
( BTM_BleMaxMultiAdvInstanceCount() * INST_ID_IDX_MAX)* sizeof(INT8));
- p_multi_adv_com_data_cb->inst_cb = GKI_getbuf(( BTM_BleMaxMultiAdvInstanceCount() + 1 )
+ p_multi_adv_com_data_cb->inst_cb = GKI_getbuf(( BTM_BleMaxMultiAdvInstanceCount() + 1 )
* sizeof(btgatt_multi_adv_inst_cb));
- memset(p_multi_adv_com_data_cb->inst_cb, 0 ,
+ memset(p_multi_adv_com_data_cb->inst_cb, 0 ,
( BTM_BleMaxMultiAdvInstanceCount() + 1) * sizeof(btgatt_multi_adv_inst_cb));
+
+ for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount(); i += 2)
+ for (int i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
+ p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
+ }
}
}
void btif_gattc_init_multi_adv_cb(void)
{
- int i;
- btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
-
- if (NULL == p_multi_adv_data_cb)
- return;
-
- if (0 == multi_adv_enable_count)
- {
- for (i=0; i < BTM_BleMaxMultiAdvInstanceCount(); i++)
- {
- p_multi_adv_data_cb->clntif_map[i + i] = INVALID_ADV_INST;
- p_multi_adv_data_cb->clntif_map[i + (i + 1)] = INVALID_ADV_INST;
- }
- }
- multi_adv_enable_count++;
+ // TODO: Instead of using a fragile reference counter here, one could
+ // simply track the client_if instances that are in the map.
+ ++multi_adv_enable_count;
}
-void btif_gattc_destroy_multi_adv_cb()
+void btif_gattc_destroy_multi_adv_cb(int client_if)
{
if (multi_adv_enable_count > 0)
multi_adv_enable_count --;
- if (0 == multi_adv_enable_count)
+ if(multi_adv_enable_count == 0 && p_multi_adv_com_data_cb != 0)
{
if (NULL != p_multi_adv_com_data_cb)
{
int i=1;
btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
-
if (NULL == p_multi_adv_data_cb)
return INVALID_ADV_INST;
void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
bool include_name, bool include_txpower, int min_interval, int max_interval,
- int appearance, uint16_t manufacturer_len, char* manufacturer_data,
- uint16_t service_data_len, char* service_data, uint16_t service_uuid_len,
+ int appearance, int manufacturer_len, char* manufacturer_data,
+ int service_data_len, char* service_data, int service_uuid_len,
char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
{
memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
if (!p_adv_data->set_scan_rsp)
{
p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
- p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
+ if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
+ p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
}
if (p_adv_data->include_name)
void btif_gattc_clear_clientif(int client_if)
{
- int i=0;
-
btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
-
if (NULL == p_multi_adv_data_cb)
return;
// Clear both the inst_id and client_if values
- for (i=0; i < BTM_BleMaxMultiAdvInstanceCount(); i++)
+ for (i=0; i < BTM_BleMaxMultiAdvInstanceCount(); i+=2)
{
- if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
- {
- p_multi_adv_data_cb->clntif_map[i + (i + 1)] = INVALID_ADV_INST;
- p_multi_adv_data_cb->clntif_map[i + i] = INVALID_ADV_INST;
- BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i, client_if);
- break;
- }
+ if (client_if == p_multi_adv_data_cb->clntif_map[i])
+ {
+ btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1]);
+ p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
+ p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
+ BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i, client_if);
+ break;
+ }
}
}
return;
btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
-
if (NULL == p_multi_adv_data_cb)
return;
cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
if (cbindex < 0)
return;
+ } else {
+ if (STD_ADV_INSTID == inst_id)
+ cbindex = STD_ADV_INSTID;
}
- else
- if (STD_ADV_INSTID == inst_id)
- cbindex = STD_ADV_INSTID;
- BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
- btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex]);
+ if (inst_id != INVALID_ADV_INST)
+ {
+ BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
+ btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex]);
+ p_multi_adv_data_cb->inst_cb[cbindex].inst_id = INVALID_ADV_INST;
+ }
}
void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb)
{
+ // Discoverability timer cleanup
+ alarm_free(p_multi_inst_cb->limited_timer);
+ p_multi_inst_cb->limited_timer = NULL;
+
// Manufacturer data cleanup
if (p_multi_inst_cb->data.p_manu != NULL)
{
GKI_freebuf(p_multi_inst_cb->data.p_sol_service_128b);
}
+void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb)
+{
+ int inst_id = btif_multi_adv_instid_for_clientif(client_if);
+ if (inst_id == INVALID_ADV_INST)
+ return;
+
+ int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
+ if (cbindex == INVALID_ADV_INST)
+ return;
+
+ btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
+ if (p_multi_adv_data_cb == NULL)
+ return;
+
+ if (cb == NULL)
+ {
+ alarm_free(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer);
+ p_multi_adv_data_cb->inst_cb[cbindex].limited_timer = NULL;
+ } else {
+ if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s != 0)
+ {
+ if (p_multi_adv_data_cb->inst_cb[cbindex].limited_timer == NULL)
+ p_multi_adv_data_cb->inst_cb[cbindex].limited_timer = alarm_new();
+ else
+ alarm_cancel(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer);
+
+ if (p_multi_adv_data_cb->inst_cb[cbindex].limited_timer)
+ {
+ alarm_set(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer,
+ p_multi_adv_data_cb->inst_cb[cbindex].timeout_s * 1000,
+ cb, (void*)inst_id);
+ }
+ }
+ }
+}
+
#endif