summaryrefslogtreecommitdiffstats
path: root/btif/src
diff options
context:
space:
mode:
authorKausik Sinnaswamy <kausik@broadcom.com>2012-03-06 17:08:42 -0800
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:11 -0700
commitb23905722d8a1c714d66aaee2da5712694596426 (patch)
treebb7ff539fa94fa219d87415253f56c147dac7876 /btif/src
parent3d576de19430085695937c04dffb2f0c8daf38e5 (diff)
downloadexternal_bluetooth_bluedroid-b23905722d8a1c714d66aaee2da5712694596426.zip
external_bluetooth_bluedroid-b23905722d8a1c714d66aaee2da5712694596426.tar.gz
external_bluetooth_bluedroid-b23905722d8a1c714d66aaee2da5712694596426.tar.bz2
Dynamic enable/disable profiles using the profile's init/cleanup APIs
Change-Id: I40ed55ada7aad0cc0e017cae16049472ef318542
Diffstat (limited to 'btif/src')
-rw-r--r--btif/src/btif_core.c65
-rw-r--r--btif/src/btif_dm.c67
-rw-r--r--btif/src/btif_hf.c42
-rw-r--r--btif/src/btif_storage.c31
4 files changed, 187 insertions, 18 deletions
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 570a7c5..022e1f4 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -83,7 +83,7 @@ static UINT32 btif_task_stack[(BTIF_TASK_STACK_SIZE + 3) / 4];
/* checks whether any HAL operation other than enable is permitted */
static int btif_enabled = 0;
static int btif_shutdown_pending = 0;
-
+static tBTA_SERVICE_MASK btif_enabled_services = 0;
/************************************************************************************
** Local type definitions
************************************************************************************/
@@ -129,6 +129,7 @@ void bte_main_shutdown(void);
void bte_main_enable_lpm(BOOLEAN enable);
#endif
void bte_main_postload_cfg(void);
+void btif_dm_execute_service_request(UINT16 event, char *p_param);
/************************************************************************************
** Functions
@@ -1036,3 +1037,65 @@ bt_status_t btif_get_remote_service_record(bt_bdaddr_t *remote_addr,
return btif_dm_get_remote_service_record(remote_addr, uuid);
}
+tBTA_SERVICE_MASK btif_get_enabled_services_mask(void)
+{
+ return btif_enabled_services;
+}
+
+/*******************************************************************************
+**
+** Function btif_enable_service
+**
+** Description Enables the service 'service_ID' to the service_mask.
+** Upon BT enable, BTIF core shall invoke the BTA APIs to
+** enable the profiles
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id)
+{
+ tBTA_SERVICE_ID *p_id = &service_id;
+ /* If BT is enabled, we need to switch to BTIF context and trigger the
+ * enable for that profile
+ *
+ * Otherwise, we just set the flag. On BT_Enable, the DM will trigger
+ * enable for the profiles that have been enabled */
+ btif_enabled_services |= (1 << service_id);
+ BTIF_TRACE_ERROR2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services);
+ if (btif_enabled == TRUE)
+ {
+ btif_transfer_context(btif_dm_execute_service_request,
+ BTIF_DM_ENABLE_SERVICE,
+ (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL);
+ }
+ return BT_STATUS_SUCCESS;
+}
+/*******************************************************************************
+**
+** Function btif_disable_service
+**
+** Description Disables the service 'service_ID' to the service_mask.
+** Upon BT disable, BTIF core shall invoke the BTA APIs to
+** disable the profiles
+**
+** Returns bt_status_t
+**
+*******************************************************************************/
+bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id)
+{
+ tBTA_SERVICE_ID *p_id = &service_id;
+ /* If BT is enabled, we need to switch to BTIF context and trigger the
+ * disable for that profile so that the appropriate uuid_property_changed will
+ * be triggerred. Otherwise, we just need to clear the service_id in the mask
+ */
+ btif_enabled_services &= (tBTA_SERVICE_MASK)(~(1<<service_id));
+ BTIF_TRACE_ERROR2("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services);
+ if (btif_enabled == TRUE)
+ {
+ btif_transfer_context(btif_dm_execute_service_request,
+ BTIF_DM_DISABLE_SERVICE,
+ (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL);
+ }
+ return BT_STATUS_SUCCESS;
+}
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index 750bb76..8fbc31d 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -96,11 +96,29 @@ static bt_status_t btif_dm_get_remote_services(bt_bdaddr_t *remote_addr);
** Externs
******************************************************************************/
extern UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID];
+extern bt_status_t btif_hf_execute_service(BOOLEAN b_enable);
/******************************************************************************
** Functions
******************************************************************************/
+bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
+ BOOLEAN b_enable)
+{
+ /* Check the service_ID and invoke the profile's BT state changed API */
+ switch (service_id)
+ {
+ case BTA_HFP_SERVICE_ID:
+ {
+ btif_hf_execute_service(b_enable);
+ }break;
+ default:
+ BTIF_TRACE_ERROR1("%s: Unknown service being enabled", __FUNCTION__);
+ return BT_STATUS_FAIL;
+ }
+ return BT_STATUS_SUCCESS;
+}
+
/*******************************************************************************
**
** Function check_eir_remote_name
@@ -659,6 +677,8 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
{
tBTA_DM_SEC_EVT dm_event = (tBTA_DM_SEC_EVT)event;
tBTA_DM_SEC *p_data = (tBTA_DM_SEC*)p_param;
+ tBTA_SERVICE_MASK service_mask;
+ uint32_t i;
BTIF_TRACE_EVENT1("btif_dm_upstreams_cback ev: %d", event);
@@ -688,15 +708,39 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
/* A name exists in the storage. Make this the device name */
BTA_DmSetDeviceName((char*)prop.val);
}
+
+ /* for each of the enabled services in the mask, trigger the profile
+ * enable */
+ service_mask = btif_get_enabled_services_mask();
+ for (i=0; i <= BTA_MAX_SERVICE_ID; i++)
+ {
+ if (service_mask &
+ (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i)))
+ {
+ btif_in_execute_service_request(i, TRUE);
+ }
+ }
/* This function will also trigger the adapter_properties_cb
** and bonded_devices_info_cb
*/
btif_storage_load_bonded_devices();
+
btif_enable_bluetooth_evt(p_data->enable.status, p_data->enable.bd_addr);
}
break;
case BTA_DM_DISABLE_EVT:
+ /* for each of the enabled services in the mask, trigger the profile
+ * disable */
+ service_mask = btif_get_enabled_services_mask();
+ for (i=0; i <= BTA_MAX_SERVICE_ID; i++)
+ {
+ if (service_mask &
+ (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(i)))
+ {
+ btif_in_execute_service_request(i, FALSE);
+ }
+ }
btif_disable_bluetooth_evt();
break;
@@ -1168,3 +1212,26 @@ bt_status_t btif_dm_get_remote_service_record(bt_bdaddr_t *remote_addr,
return BT_STATUS_SUCCESS;
}
+
+void btif_dm_execute_service_request(UINT16 event, char *p_param)
+{
+ BOOLEAN b_enable = FALSE;
+ bt_status_t status;
+ if (event == BTIF_DM_ENABLE_SERVICE)
+ {
+ b_enable = TRUE;
+ }
+ status = btif_in_execute_service_request(*((tBTA_SERVICE_ID*)p_param), b_enable);
+ if (status == BT_STATUS_SUCCESS)
+ {
+ bt_property_t property;
+ bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS];
+ /* Now send the UUID_PROPERTY_CHANGED event to the upper layer */
+ BTIF_STORAGE_FILL_PROPERTY(&property, BT_PROPERTY_UUIDS,
+ sizeof(local_uuids), local_uuids);
+ btif_storage_get_adapter_property(&property);
+ CHECK_CALL_CBACK(bt_hal_cbacks, adapter_properties_cb,
+ BT_STATUS_SUCCESS, 1, &property);
+ }
+ return;
+}
diff --git a/btif/src/btif_hf.c b/btif/src/btif_hf.c
index 7f0e6bc..06e7fe3 100644
--- a/btif/src/btif_hf.c
+++ b/btif/src/btif_hf.c
@@ -422,16 +422,13 @@ static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
*******************************************************************************/
static bt_status_t init( bthf_callbacks_t* callbacks )
{
- char * p_service_names[] = {BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME};
-
BTIF_TRACE_EVENT1("%s", __FUNCTION__);
bt_hf_callbacks = callbacks;
- /* Enable and register with BTA-AG */
- BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
- BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, BTIF_HF_FEATURES,
- p_service_names, BTIF_HF_ID_1);
+ /* Invoke the enable service API to the core to set the appropriate service_id
+ * Internally, the HSP_SERVICE_ID shall also be enabled */
+ btif_enable_service(BTA_HFP_SERVICE_ID);
return BT_STATUS_SUCCESS;
}
@@ -966,10 +963,7 @@ static void cleanup( void )
if (bt_hf_callbacks)
{
- /* De-register AG */
- BTA_AgDeregister(btif_hf_cb.handle);
- /* Disable AG */
- BTA_AgDisable();
+ btif_disable_service(BTA_HFP_SERVICE_ID);
bt_hf_callbacks = NULL;
}
}
@@ -996,6 +990,34 @@ static const bthf_interface_t bthfInterface = {
/*******************************************************************************
**
+** Function btif_hf_execute_service
+**
+** Description Initializes/Shuts down the service
+**
+** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
+**
+*******************************************************************************/
+bt_status_t btif_hf_execute_service(BOOLEAN b_enable)
+{
+ char * p_service_names[] = {BTIF_HSAG_SERVICE_NAME, BTIF_HFAG_SERVICE_NAME};
+ if (b_enable)
+ {
+ /* Enable and register with BTA-AG */
+ BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
+ BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY, BTIF_HF_FEATURES,
+ p_service_names, BTIF_HF_ID_1);
+ }
+ else {
+ /* De-register AG */
+ BTA_AgDeregister(btif_hf_cb.handle);
+ /* Disable AG */
+ BTA_AgDisable();
+ }
+ return BT_STATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
** Function btif_hf_get_interface
**
** Description Get the hf callback interface
diff --git a/btif/src/btif_storage.c b/btif/src/btif_storage.c
index a55821d..6c0c337 100644
--- a/btif/src/btif_storage.c
+++ b/btif/src/btif_storage.c
@@ -170,6 +170,11 @@ typedef struct {
} btif_bonded_devices_t;
/************************************************************************************
+** Extern variables
+************************************************************************************/
+extern UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID];
+
+/************************************************************************************
** Static variables
************************************************************************************/
@@ -589,14 +594,26 @@ bt_status_t btif_storage_get_adapter_property(bt_property_t *property)
/* publish list of local supported services */
bt_uuid_t *p_uuid = (bt_uuid_t*)property->val;
uint32_t num_uuids = 0;
+ uint32_t i;
-#if BTA_AG_INCLUDED == TRUE
- uuid16_to_uuid128(UUID_SERVCLASS_AG_HANDSFREE, p_uuid + num_uuids);
- num_uuids++;
- uuid16_to_uuid128(UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, p_uuid + num_uuids);
- num_uuids++;
-#endif
-
+ tBTA_SERVICE_MASK service_mask = btif_get_enabled_services_mask();
+ BTIF_TRACE_ERROR2("%s service_mask:0x%x", __FUNCTION__, service_mask);
+ for (i=0; i < BTA_MAX_SERVICE_ID; i++)
+ {
+ if(service_mask
+ &(tBTA_SERVICE_MASK)(1 << i))
+ {
+ uuid16_to_uuid128(bta_service_id_to_uuid_lkup_tbl[i], p_uuid+num_uuids);
+ num_uuids++;
+ /* BTA_HSP_SERVICE_ID is a special case and gets enabled automatically
+ * when BTA_HFP_SERVICE_ID is enabled */
+ if (i == BTA_HFP_SERVICE_ID) {
+ uuid16_to_uuid128(bta_service_id_to_uuid_lkup_tbl[BTA_HSP_SERVICE_ID],
+ p_uuid+num_uuids);
+ num_uuids++;
+ }
+ }
+ }
property->len = (num_uuids)*sizeof(bt_uuid_t);
return BT_STATUS_SUCCESS;
}