*******************************************************************************/
void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
{
- BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
- (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
+ tBTA_STATUS status = BTA_FAILURE;
+
+ if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
+ (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+ {
+ status = BTA_SUCCESS;
+ }
+
+ if (p_data->ble_set_adv_data.p_adv_data_cback)
+ (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
}
/*******************************************************************************
*******************************************************************************/
void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
{
- BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
- (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg);
+ tBTA_STATUS status = BTA_FAILURE;
+
+ if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
+ (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS)
+ {
+ status = BTA_SUCCESS;
+ }
+
+ if (p_data->ble_set_adv_data.p_adv_data_cback)
+ (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
}
/*******************************************************************************
BTM_BleBroadcast(p_data->ble_observe.start);
}
+/*******************************************************************************
+**
+** Function bta_dm_ble_multi_adv_enb
+**
+** Description This function enables a single advertising instance
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
+{
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_enb.p_params,
+ p_data->ble_multi_adv_enb.p_cback,p_data->ble_multi_adv_enb.p_ref);
+#endif
+}
+/*******************************************************************************
+**
+** Function bta_dm_ble_multi_adv_param_upd
+**
+** Description This function updates multiple advertising instance parameters
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
+{
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
+ (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params);
+#endif
+}
+/*******************************************************************************
+**
+** Function bta_dm_ble_multi_adv_data
+**
+** Description This function write multiple advertising instance adv data
+** or scan response data
+**
+** Parameters:
+**
+*******************************************************************************/
+void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
+{
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,p_data->ble_multi_adv_data.is_scan_rsp,
+ p_data->ble_multi_adv_data.data_mask,(tBTM_BLE_ADV_DATA*)p_data->ble_multi_adv_data.p_data);
+#endif
+}
+/*******************************************************************************
+**
+** Function btm_dm_ble_multi_adv_disable
+**
+** Description This function disable a single adv instance
+**
+** Parameters:
+**
+*******************************************************************************/
+void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
+{
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
+#endif
+}
+
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
**
** Description This function is called to override the BTA default ADV parameters.
**
-** Parameters Pointer to User defined ADV data structure
+** Parameters data_mask: adv data mask.
+** p_adv_cfg: Pointer to User defined ADV data structure. This
+** memory space can not be freed until p_adv_data_cback
+** is received.
+** p_adv_data_cback: set adv data complete callback.
**
** Returns None
**
*******************************************************************************/
-void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
+ tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
{
tBTA_DM_API_SET_ADV_CONFIG *p_msg;
- if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
+ if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
+ GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
{
p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_EVT;
p_msg->data_mask = data_mask;
+ p_msg->p_adv_data_cback = p_adv_data_cback;
p_msg->p_adv_cfg = p_adv_cfg;
bta_sys_sendmsg(p_msg);
** Returns None
**
*******************************************************************************/
-BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg)
+BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_adv_cfg,
+ tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
{
tBTA_DM_API_SET_ADV_CONFIG *p_msg;
- if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *) GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
+ if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG *)
+ GKI_getbuf(sizeof(tBTA_DM_API_SET_ADV_CONFIG))) != NULL)
{
p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_EVT;
p_msg->data_mask = data_mask;
+ p_msg->p_adv_data_cback = p_adv_data_cback;
p_msg->p_adv_cfg = p_adv_cfg;
bta_sys_sendmsg(p_msg);
}
#endif
+#if BLE_INCLUDED == TRUE
+/*******************************************************************************
+**
+** Function BTA_BleEnableAdvInstance
+**
+** Description This function enable a Multi-ADV instance with the specififed
+** adv parameters
+**
+** Parameters p_params: pointer to the adv parameter structure.
+** p_cback: callback function associated to this adv instance.
+** p_ref: reference data pointer to this adv instance.
+**
+** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+tBTA_STATUS BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params,
+ tBTA_BLE_MULTI_ADV_CBACK *p_cback,
+ void *p_ref)
+{
+ tBTA_DM_API_BLE_MULTI_ADV_ENB *p_msg;
+ UINT16 len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB);
+
+ APPL_TRACE_API0 ("BTA_BleEnableAdvInstance");
+
+ if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_ENB *) GKI_getbuf(len)) != NULL)
+ {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_ENB));
+
+ p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_ENB_EVT;
+ p_msg->p_cback = (void *)p_cback;
+ if (p_params != NULL)
+ {
+ p_msg->p_params = (void *)(p_msg + 1);
+ memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS));
+ }
+ p_msg->p_ref = p_ref;
+
+ bta_sys_sendmsg(p_msg);
+
+ return BTA_SUCCESS;
+ }
+ return BTA_FAILURE;
+}
+
+/*******************************************************************************
+**
+** Function BTA_BleUpdateAdvInstParam
+**
+** Description This function update a Multi-ADV instance with the specififed
+** adv parameters.
+**
+** Parameters inst_id: Adv instance to update the parameter.
+** p_params: pointer to the adv parameter structure.
+**
+** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+tBTA_STATUS BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params)
+{
+ tBTA_DM_API_BLE_MULTI_ADV_PARAM *p_msg;
+ UINT16 len = sizeof(tBTA_BLE_ADV_PARAMS) + sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM);
+
+ APPL_TRACE_API0 ("BTA_BleUpdateAdvInstParam");
+ if (inst_id <= BTM_BLE_MULTI_ADV_MAX && inst_id != BTA_BLE_MULTI_ADV_ILLEGAL)
+ {
+ if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_PARAM *) GKI_getbuf(len)) != NULL)
+ {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_PARAM));
+
+ p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT;
+ p_msg->inst_id = inst_id;
+ p_msg->p_params = (void *)(p_msg + 1);
+ memcpy(p_msg->p_params, p_params, sizeof(tBTA_BLE_ADV_PARAMS));
+
+ bta_sys_sendmsg(p_msg);
+
+ return BTA_SUCCESS;
+ }
+ }
+ return BTA_FAILURE;
+}
+
+/*******************************************************************************
+**
+** Function BTA_BleCfgAdvInstData
+**
+** Description This function configure a Multi-ADV instance with the specififed
+** adv data or scan response data.
+**
+** Parameter inst_id: Adv instance to configure the adv data or scan response.
+** is_scan_rsp: is the data scan response or adv data.
+** data_mask: adv data type as bit mask.
+** p_data: pointer to the ADV data structure tBTA_BLE_ADV_DATA. This
+** memory space can not be freed until BTA_BLE_MULTI_ADV_DATA_EVT
+** is sent to application.
+**
+** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+tBTA_STATUS BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
+ tBTA_BLE_AD_MASK data_mask,
+ tBTA_BLE_ADV_DATA *p_data)
+{
+ tBTA_DM_API_BLE_MULTI_ADV_DATA *p_msg;
+ UINT16 len = sizeof(tBTA_DM_API_BLE_MULTI_ADV_DATA) ;
+
+ APPL_TRACE_API0 ("BTA_BleCfgAdvInstData");
+
+ if (inst_id <= BTM_BLE_MULTI_ADV_MAX && inst_id != BTA_BLE_MULTI_ADV_ILLEGAL)
+ {
+ if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DATA *) GKI_getbuf(len)) != NULL)
+ {
+ memset(p_msg, 0, len);
+
+ p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_DATA_EVT;
+ p_msg->inst_id = inst_id;
+ p_msg->is_scan_rsp = is_scan_rsp;
+ p_msg->data_mask = data_mask;
+ p_msg->p_data = p_data;
+
+ bta_sys_sendmsg(p_msg);
+
+ return BTA_SUCCESS;
+ }
+ }
+ return BTA_FAILURE;
+}
+
+/*******************************************************************************
+**
+** Function BTA_BleDisableAdvInstance
+**
+** Description This function disable a Multi-ADV instance.
+**
+** Parameter inst_id: instance ID to disable.
+**
+** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
+**
+*******************************************************************************/
+tBTA_STATUS BTA_BleDisableAdvInstance (UINT8 inst_id)
+{
+ tBTA_DM_API_BLE_MULTI_ADV_DISABLE *p_msg;
+
+ APPL_TRACE_API1 ("BTA_BleDisableAdvInstance: %d", inst_id);
+
+ if (inst_id <= BTM_BLE_MULTI_ADV_MAX && inst_id != BTA_BLE_MULTI_ADV_ILLEGAL)
+ {
+ if ((p_msg = (tBTA_DM_API_BLE_MULTI_ADV_DISABLE *)
+ GKI_getbuf(sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE))) != NULL)
+ {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_MULTI_ADV_DISABLE));
+ p_msg->hdr.event = BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT;
+ p_msg->inst_id = inst_id;
+ bta_sys_sendmsg(p_msg);
+ return BTA_SUCCESS;
+ }
+ }
+ return BTA_FAILURE;
+}
+
/*******************************************************************************
**
** Function BTA_DmBleUpdateConnectionParams
void BTA_DmBleUpdateConnectionParams(BD_ADDR bd_addr, UINT16 min_int, UINT16 max_int,
UINT16 latency, UINT16 timeout)
{
-#if BLE_INCLUDED == TRUE
tBTA_DM_API_UPDATE_CONN_PARAM *p_msg;
if ((p_msg = (tBTA_DM_API_UPDATE_CONN_PARAM *) GKI_getbuf(sizeof(tBTA_DM_API_UPDATE_CONN_PARAM))) != NULL)
bta_sys_sendmsg(p_msg);
}
-#endif
}
+#endif
/*******************************************************************************
**
BTA_API extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration,
tBTA_DM_SEARCH_CBACK *p_results_cb)
{
-#if BLE_INCLUDED == TRUE
-
tBTA_DM_API_BLE_OBSERVE *p_msg;
APPL_TRACE_API1("BTA_DmBleObserve:start = %d ", start);
bta_sys_sendmsg(p_msg);
}
-#endif
}
#endif
BTA_DM_API_BLE_SCAN_PARAM_EVT,
BTA_DM_API_BLE_OBSERVE_EVT,
BTA_DM_API_UPDATE_CONN_PARAM_EVT,
+
+#if BLE_PRIVACY_SPT == TRUE
+ BTA_DM_API_LOCAL_PRIVACY_EVT,
+#endif
+
BTA_DM_API_BLE_ADV_PARAM_EVT,
BTA_DM_API_BLE_SET_ADV_CONFIG_EVT,
BTA_DM_API_BLE_SET_SCAN_RSP_EVT,
BTA_DM_API_CFG_FILTER_COND_EVT,
BTA_DM_API_ENABLE_SCAN_FILTER_EVT,
#endif
+ BTA_DM_API_BLE_MULTI_ADV_ENB_EVT,
+ BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT,
+ BTA_DM_API_BLE_MULTI_ADV_DATA_EVT,
+ BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT,
#endif
#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
typedef struct
{
BT_HDR hdr;
+ BOOLEAN enable;
+
+}tBTA_DM_API_BLE_FEATURE;
+
+/* multi adv data structure */
+typedef struct
+{
+ BT_HDR hdr;
+ void *p_cback;
+ void *p_ref;
+ tBTA_BLE_ADV_PARAMS *p_params;
+}tBTA_DM_API_BLE_MULTI_ADV_ENB;
+
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 inst_id;
+ tBTA_BLE_ADV_PARAMS *p_params;
+}tBTA_DM_API_BLE_MULTI_ADV_PARAM;
+
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 inst_id;
+ BOOLEAN is_scan_rsp;
+ tBTA_BLE_AD_MASK data_mask;
+ tBTA_BLE_ADV_DATA *p_data;
+}tBTA_DM_API_BLE_MULTI_ADV_DATA;
+
+typedef struct
+{
+ BT_HDR hdr;
+ UINT8 inst_id;
+}tBTA_DM_API_BLE_MULTI_ADV_DISABLE;
+
+
+typedef struct
+{
+ BT_HDR hdr;
UINT16 data_mask;
tBTA_BLE_ADV_DATA *p_adv_cfg;
+ tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback;
}tBTA_DM_API_SET_ADV_CONFIG;
-#endif
+#endif /* BLE_INCLUDED */
typedef struct
{
tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond;
#endif
tBTA_DM_API_UPDATE_CONN_PARAM ble_update_conn_params;
+ tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb;
+ tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param;
+ tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data;
+ tBTA_DM_API_BLE_MULTI_ADV_DISABLE ble_multi_adv_disable;
#endif
tBTA_DM_API_SET_AFH_CHANNEL_ASSESSMENT set_afh_channel_assessment;
extern void bta_dm_enable_scan_filter (tBTA_DM_MSG *p_data);
extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data);
#endif
+extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data);
#endif
extern void bta_dm_set_encryption(tBTA_DM_MSG *p_data);
bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */
bta_dm_enable_scan_filter, /* BTA_DM_API_ENABLE_SCAN_FILTER_EVT */
#endif
+ bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/
+ bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */
+ bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */
+ btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */
#endif
#if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
#define BTA_DM_BLE_AD_BIT_SERVICE_128SOL BTM_BLE_AD_BIT_SERVICE_128SOL
#define BTA_DM_BLE_AD_BIT_PUBLIC_ADDR BTM_BLE_AD_BIT_PUBLIC_ADDR
#define BTA_DM_BLE_AD_BIT_RANDOM_ADDR BTM_BLE_AD_BIT_RANDOM_ADDR
+#define BTA_DM_BLE_AD_BIT_SERVICE_128 BTM_BLE_AD_BIT_SERVICE_128 /*128-bit Service UUIDs*/
-typedef UINT16 tBTA_BLE_AD_MASK;
+typedef tBTM_BLE_AD_MASK tBTA_BLE_AD_MASK;
/* slave preferred connection interval range */
typedef struct
typedef struct
{
- tBTA_BLE_MANU manu; /* manufactuer data */
- tBTA_BLE_INT_RANGE int_range; /* slave prefered conn interval range */
- tBTA_BLE_SERVICE services; /* services */
- UINT16 appearance; /* appearance data */
- UINT8 flag;
- tBTA_BLE_PROPRIETARY *p_proprietary;
+ tBT_UUID service_uuid;
+ UINT8 len;
+ UINT8 *p_val;
+}tBTA_BLE_SERVICE_DATA;
+
+typedef tBTM_BLE_128SERVICE tBTA_BLE_128SERVICE;
+typedef tBTM_BLE_32SERVICE tBTA_BLE_32SERVICE;
+typedef struct
+{
+ tBTA_BLE_INT_RANGE int_range; /* slave prefered conn interval range */
+ tBTA_BLE_MANU *p_manu; /* manufacturer data */
+ tBTA_BLE_SERVICE *p_services; /* 16 bits services */
+ tBTA_BLE_128SERVICE *p_services_128b; /* 128 bits service */
+ tBTA_BLE_32SERVICE *p_service_32b; /* 32 bits Service UUID */
+ tBTA_BLE_SERVICE *p_sol_services; /* 16 bits services Solicitation UUIDs */
+ tBTA_BLE_32SERVICE *p_sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
+ tBTA_BLE_128SERVICE *p_sol_service_128b;/* List of 128 bit Service Solicitation UUIDs */
+ tBTA_BLE_PROPRIETARY *p_proprietary; /* proprietary data */
+ tBTA_BLE_SERVICE_DATA *p_service_data; /* service data */
+ UINT16 appearance; /* appearance data */
+ UINT8 flag;
+ UINT8 tx_power;
}tBTA_BLE_ADV_DATA;
+typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status);
+
+/* advertising channel map */
+#define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37
+#define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38
+#define BTA_BLE_ADV_CHNL_39 BTM_BLE_ADV_CHNL_39
+typedef tBTM_BLE_ADV_CHNL_MAP tBTA_BLE_ADV_CHNL_MAP; /* use as a bit mask */
+
+/* advertising filter policy */
+typedef tBTM_BLE_AFP tBTA_BLE_AFP;
+
+/* adv event type */
+#define BTA_BLE_CONNECT_EVT BTM_BLE_CONNECT_EVT /* Connectable undirected advertising */
+#define BTA_BLE_CONNECT_DIR_EVT BTM_BLE_CONNECT_DIR_EVT /* Connectable directed advertising */
+#define BTA_BLE_DISCOVER_EVT BTM_BLE_DISCOVER_EVT /* Scannable undirected advertising */
+#define BTA_BLE_NON_CONNECT_EVT BTM_BLE_NON_CONNECT_EVT /* Non connectable undirected advertising */
+typedef UINT8 tBTA_BLE_ADV_EVT;
+
+/* adv tx power level */
+#define BTA_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */
+#define BTA_BLE_ADV_TX_POWER_LOW 1 /* low tx power */
+#define BTA_BLE_ADV_TX_POWER_MID 2 /* middle tx power */
+#define BTA_BLE_ADV_TX_POWER_UPPER 3 /* upper tx power */
+#define BTA_BLE_ADV_TX_POWER_MAX 4 /* maximum tx power */
+typedef UINT8 tBTA_BLE_ADV_TX_POWER;
+
+/* advertising instance parameters */
+typedef struct
+{
+ UINT16 adv_int_min; /* minimum adv interval */
+ UINT16 adv_int_max; /* maximum adv interval */
+ tBTA_BLE_ADV_EVT adv_type; /* adv event type */
+ tBTA_BLE_ADV_CHNL_MAP channel_map; /* adv channel map */
+ tBTA_BLE_AFP adv_filter_policy; /* advertising filter policy */
+ tBTA_BLE_ADV_TX_POWER tx_power; /* adv tx power */
+}tBTA_BLE_ADV_PARAMS;
+
/* These are the fields returned in each device adv packet. It
** is returned in the results callback if registered.
*/
/* Security callback */
typedef void (tBTA_DM_SEC_CBACK)(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data);
+#define BTA_BLE_MULTI_ADV_MAX BTM_BLE_MULTI_ADV_MAX
+#define BTA_BLE_MULTI_ADV_ILLEGAL 0
+
+/* multi adv callback event */
+#define BTA_BLE_MULTI_ADV_ENB_EVT 1
+#define BTA_BLE_MULTI_ADV_DISABLE_EVT 2
+#define BTA_BLE_MULTI_ADV_PARAM_EVT 3
+#define BTA_BLE_MULTI_ADV_DATA_EVT 4
+
+typedef UINT8 tBTA_BLE_MULTI_ADV_EVT;
+
+/* multi adv callback */
+typedef void (tBTA_BLE_MULTI_ADV_CBACK)(tBTA_BLE_MULTI_ADV_EVT event,
+ UINT8 inst_id, void *p_ref, tBTA_STATUS status);
+
/* Vendor Specific Command Callback */
typedef tBTM_VSC_CMPL_CB tBTA_VENDOR_CMPL_CBACK;
**
*******************************************************************************/
BTA_API extern void BTA_DmBleSetAdvConfig (tBTA_BLE_AD_MASK data_mask,
- tBTA_BLE_ADV_DATA *p_adv_cfg);
+ tBTA_BLE_ADV_DATA *p_adv_cfg,
+ tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
/*******************************************************************************
**
**
*******************************************************************************/
BTA_API extern void BTA_DmBleSetScanRsp (tBTA_BLE_AD_MASK data_mask,
- tBTA_BLE_ADV_DATA *p_adv_cfg);
+ tBTA_BLE_ADV_DATA *p_adv_cfg,
+ tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
/*******************************************************************************
**
*******************************************************************************/
BTA_API extern void BTA_DmBleBroadcast (BOOLEAN start);
+
+/*******************************************************************************
+**
+** Function BTA_BleEnableAdvInstance
+**
+** Description This function enables the Multi ADV instance feature
+**
+** Parameters p_params Pointer to ADV param user defined structure
+** p_cback Pointer to Multi ADV callback structure
+** p_ref - Reference pointer
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern tBTA_STATUS BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params,
+ tBTA_BLE_MULTI_ADV_CBACK *p_cback,void *p_ref);
+
+/*******************************************************************************
+**
+** Function BTA_BleUpdateAdvInstParam
+**
+** Description This function updates the Multi ADV instance params
+**
+** Parameters inst_id Instance ID
+** p_params Pointer to ADV param user defined structure
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern tBTA_STATUS BTA_BleUpdateAdvInstParam (UINT8 inst_id,
+ tBTA_BLE_ADV_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** Function BTA_BleCfgAdvInstData
+**
+** Description This function is called to configure the ADV instance data
+**
+** Parameters inst_id - Instance ID
+** is_scan_rsp - Boolean value Scan response
+** Pointer to User defined ADV data structure
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern tBTA_STATUS BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
+ tBTA_BLE_AD_MASK data_mask, tBTA_BLE_ADV_DATA *p_data);
+
+/*******************************************************************************
+**
+** Function BTA_BleDisableAdvInstance
+**
+** Description This function is called to disable the ADV instance
+**
+** Parameters inst_id - Instance ID to be disabled
+**
+** Returns None
+**
+*******************************************************************************/
+BTA_API extern tBTA_STATUS BTA_BleDisableAdvInstance(UINT8 inst_id);
+
/*******************************************************************************
**
** Function BTA_DmBleUpdateConnectionParams
#define BTA_GATTC_LISTEN_EVT 16 /* listen event */
#define BTA_GATTC_ENC_CMPL_CB_EVT 17 /* encryption complete callback event */
#define BTA_GATTC_CFG_MTU_EVT 18 /* configure MTU complete event */
+#define BTA_GATTC_ADV_DATA_EVT 19 /* ADV data event */
+#define BTA_GATTC_MULT_ADV_ENB_EVT 20 /* Enable Multi ADV event */
+#define BTA_GATTC_MULT_ADV_UPD_EVT 21 /* Update parameter event */
+#define BTA_GATTC_MULT_ADV_DATA_EVT 22 /* Multi ADV data event */
+#define BTA_GATTC_MULT_ADV_DIS_EVT 23 /* Disable Multi ADV event */
typedef UINT8 tBTA_GATTC_EVT;
--- /dev/null
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+#ifndef BTIF_GATT_MULTI_ADV_UTIL_H
+#define BTIF_GATT_MULTI_ADV_UTIL_H
+
+#include <hardware/bluetooth.h>
+#include "bta_api.h"
+
+#define CLNT_IF_IDX 0
+#define INST_ID_IDX 1
+#define INVALID_ADV_INST -1
+#define STD_ADV_INSTID 0
+#define ADV_FLAGS 0x02
+
+typedef struct
+{
+ int client_if;
+ BOOLEAN set_scan_rsp;
+ BOOLEAN include_name;
+ BOOLEAN include_txpower;
+ int min_interval;
+ int max_interval;
+ int appearance;
+ uint16_t manufacturer_len;
+ uint8_t* p_manufacturer_data;
+ uint16_t service_data_len;
+ uint8_t* p_service_data;
+ uint16_t service_uuid_len;
+ uint8_t* p_service_uuid;
+} btif_adv_data_t;
+
+typedef struct
+{
+ UINT8 inst_id;
+ BOOLEAN is_scan_rsp;
+ UINT8 client_if;
+ UINT16 service_uuid_len;
+ tBTA_BLE_AD_MASK mask;
+ tBTA_BLE_ADV_DATA data;
+ tBTA_BLE_ADV_PARAMS param;
+}btgatt_multi_adv_inst_cb;
+
+typedef struct
+{
+ INT8 clntif_map[BTM_BLE_MULTI_ADV_MAX][INST_ID_IDX+1];
+ // Includes the stored data for standard LE instance
+ btgatt_multi_adv_inst_cb inst_cb[BTM_BLE_MULTI_ADV_MAX+1];
+} btgatt_multi_adv_common_data;
+
+extern btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb();
+extern void btif_gattc_init_multi_adv_cb(void);
+extern void btif_gattc_destroy_multi_adv_cb();
+extern int btif_multi_adv_add_instid_map(int client_if, int inst_id,
+ BOOLEAN gen_temp_instid);
+extern int btif_multi_adv_instid_for_clientif(int client_if);
+extern int btif_gattc_obtain_idx_for_datacb(int value, int arrindex);
+extern void btif_gattc_clear_clientif(int client_if);
+extern void btif_gattc_cleanup_inst_cb(int inst_id);
+extern void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_inst_cb);
+extern BOOLEAN btif_gattc_copy_datacb(int arrindex, btif_adv_data_t *p_adv_data,
+ BOOLEAN bInstData);
+extern 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,
+ char* service_uuid, btif_adv_data_t *p_multi_adv_inst);
+
+#endif
+
+
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
-#include "gki.h"
+#include "btif_gatt_multi_adv_util.h"
#include <hardware/bt_gatt.h>
#include "bta_api.h"
#include "bta_gatt_api.h"
** Constants & Macros
********************************************************************************/
-#define ADV_FLAGS 0x02
-
#define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
{\
ALOGW("%s: BTGATT not initialized", __FUNCTION__);\
BTIF_GATTC_SCAN_FILTER_CONFIG,
BTIF_GATTC_SCAN_FILTER_CLEAR,
BTIF_GATTC_SET_SCAN_PARAMS,
+ BTIF_GATTC_ADV_INSTANCE_ENABLE,
+ BTIF_GATTC_ADV_INSTANCE_UPDATE,
+ BTIF_GATTC_ADV_INSTANCE_SET_DATA,
+ BTIF_GATTC_ADV_INSTANCE_DISABLE
} btif_gattc_event_t;
#define BTIF_GATT_MAX_OBSERVED_DEV 40
typedef struct
{
- tBTA_BLE_AD_MASK mask;
- tBTA_BLE_ADV_DATA data;
-} btgatt_adv_data;
-
-typedef struct
-{
uint8_t value[BTGATT_MAX_ATTR_LEN];
- btgatt_adv_data adv_data;
+ uint8_t inst_id;
bt_bdaddr_t bd_addr;
btgatt_srvc_id_t srvc_id;
btgatt_srvc_id_t incl_srvc_id;
{
memset(p_dev_cb, 0, sizeof(btif_gattc_dev_cb_t));
}
-
static void btif_gattc_add_remote_bdaddr (BD_ADDR p_bda, uint8_t addr_type)
{
BOOLEAN found=FALSE;
break;
}
+ case BTA_GATTC_MULT_ADV_ENB_EVT:
+ {
+ btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
+ btif_multi_adv_add_instid_map(p_btif_cb->client_if,
+ p_btif_cb->inst_id,false);
+ HAL_CBACK(bt_gatt_callbacks, client->multi_adv_enable_cb
+ , p_btif_cb->client_if
+ , p_btif_cb->status
+ );
+ break;
+ }
+
+ case BTA_GATTC_MULT_ADV_UPD_EVT:
+ {
+ btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
+ HAL_CBACK(bt_gatt_callbacks, client->multi_adv_update_cb
+ , p_btif_cb->client_if
+ , p_btif_cb->status
+ );
+ break;
+ }
+
+ case BTA_GATTC_MULT_ADV_DATA_EVT:
+ {
+ btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
+ btif_gattc_cleanup_inst_cb(p_btif_cb->inst_id);
+ HAL_CBACK(bt_gatt_callbacks, client->multi_adv_data_cb
+ , p_btif_cb->client_if
+ , p_btif_cb->status
+ );
+ break;
+ }
+
+ case BTA_GATTC_MULT_ADV_DIS_EVT:
+ {
+ btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*)p_param;
+ btif_gattc_clear_clientif(p_btif_cb->client_if);
+ HAL_CBACK(bt_gatt_callbacks, client->multi_adv_disable_cb
+ , p_btif_cb->client_if
+ , p_btif_cb->status
+ );
+ break;
+ }
+
+ case BTA_GATTC_ADV_DATA_EVT:
+ {
+ btif_gattc_cleanup_inst_cb(STD_ADV_INSTID);
+ /* No HAL callback available */
+ break;
+ }
+
default:
ALOGE("%s: Unhandled event (%d)!", __FUNCTION__, event);
break;
ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
}
+static void bta_gattc_multi_adv_cback(tBTA_BLE_MULTI_ADV_EVT event, UINT8 inst_id,
+ void *p_ref, tBTA_STATUS call_status)
+{
+ btif_gattc_cb_t btif_cb;
+ tBTA_GATTC_EVT upevt;
+ uint8_t client_if = 0;
+
+ if(NULL == p_ref)
+ {
+ BTIF_TRACE_ERROR1("%s Invalid p_ref received",__FUNCTION__);
+ return;
+ }
+
+ client_if = *(UINT8 *)p_ref;
+ BTIF_TRACE_DEBUG4("%s -Inst ID %d, Status:%x, client_if:%d",__FUNCTION__,inst_id, call_status,
+ client_if);
+
+ btif_cb.status = call_status;
+ btif_cb.client_if = client_if;
+ btif_cb.inst_id = inst_id;
+
+ switch(event)
+ {
+ case BTA_BLE_MULTI_ADV_ENB_EVT:
+ {
+ upevt = BTA_GATTC_MULT_ADV_ENB_EVT;
+ break;
+ }
+
+ case BTA_BLE_MULTI_ADV_DISABLE_EVT:
+ upevt = BTA_GATTC_MULT_ADV_DIS_EVT;
+ break;
+
+ case BTA_BLE_MULTI_ADV_PARAM_EVT:
+ upevt = BTA_GATTC_MULT_ADV_UPD_EVT;
+ break;
+
+ case BTA_BLE_MULTI_ADV_DATA_EVT:
+ upevt = BTA_GATTC_MULT_ADV_DATA_EVT;
+ break;
+
+ default:
+ return;
+ }
+
+ bt_status_t status = btif_transfer_context(btif_gattc_upstreams_evt, (uint16_t) upevt,
+ (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
+ ASSERTC(status == BT_STATUS_SUCCESS, "Context transfer failed!", status);
+}
+
+static void bta_gattc_set_adv_data_cback(tBTA_STATUS call_status)
+{
+ UNUSED(call_status);
+ btif_gattc_cb_t btif_cb;
+ btif_cb.status = call_status;
+ btif_cb.action = 0;
+ btif_transfer_context(btif_gattc_upstreams_evt, BTA_GATTC_ADV_DATA_EVT,
+ (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
+}
+
static void bta_scan_results_cb (tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
btif_gattc_cb_t btif_cb;
tBTA_GATTC_INCL_SVC_ID out_incl_svc_id;
tBTA_GATT_UNFMT descr_val;
- btif_gattc_cb_t* p_cb = (btif_gattc_cb_t*)p_param;
- if (!p_cb) return;
+ btif_gattc_cb_t* p_cb = NULL;
+ btif_adv_data_t *p_adv_data = NULL;
+ btgatt_multi_adv_inst_cb *p_inst_cb = NULL;
+
+ if(BTIF_GATTC_ADV_INSTANCE_ENABLE == event || BTIF_GATTC_ADV_INSTANCE_DISABLE == event ||
+ BTIF_GATTC_ADV_INSTANCE_UPDATE == event)
+ {
+ p_inst_cb = (btgatt_multi_adv_inst_cb*)p_param;
+ }
+ else
+ {
+ if(BTIF_GATTC_ADV_INSTANCE_SET_DATA == event || BTIF_GATTC_SET_ADV_DATA == event)
+ p_adv_data = (btif_adv_data_t*)p_param;
+ else
+ p_cb = (btif_gattc_cb_t*)p_param;
+ }
+
+ if (!p_cb && !p_adv_data && !p_inst_cb) return;
ALOGD("%s: Event %d", __FUNCTION__, event);
{
case BTIF_GATTC_REGISTER_APP:
btif_to_bta_uuid(&uuid, &p_cb->uuid);
+ btif_gattc_init_multi_adv_cb();
BTA_GATTC_AppRegister(&uuid, bta_gattc_cback);
break;
case BTIF_GATTC_UNREGISTER_APP:
+ btif_gattc_destroy_multi_adv_cb();
BTA_GATTC_AppDeregister(p_cb->client_if);
break;
case BTIF_GATTC_SET_ADV_DATA:
{
- if (p_cb->start == 0)
- BTA_DmBleSetAdvConfig(p_cb->adv_data.mask, &p_cb->adv_data.data);
+ int cbindex = CLNT_IF_IDX;
+ if(cbindex >= 0 && NULL != p_adv_data)
+ {
+ btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
+ if(!btif_gattc_copy_datacb(cbindex, p_adv_data, false))
+ return;
+
+ if (!p_adv_data->set_scan_rsp)
+ {
+ BTA_DmBleSetAdvConfig(p_multi_adv_data_cb->inst_cb[cbindex].mask,
+ &p_multi_adv_data_cb->inst_cb[cbindex].data, bta_gattc_set_adv_data_cback);
+ }
+ else
+ {
+ BTA_DmBleSetScanRsp(p_multi_adv_data_cb->inst_cb[cbindex].mask,
+ &p_multi_adv_data_cb->inst_cb[cbindex].data, bta_gattc_set_adv_data_cback);
+ }
+ break;
+ }
+ }
+
+ case BTIF_GATTC_ADV_INSTANCE_ENABLE:
+ {
+ if(NULL == p_inst_cb)
+ return;
+
+ int arrindex = btif_multi_adv_add_instid_map(p_inst_cb->client_if,INVALID_ADV_INST,
+ true);
+ int cbindex = btif_gattc_obtain_idx_for_datacb(p_inst_cb->client_if, CLNT_IF_IDX);
+ if(cbindex >= 0 && arrindex >= 0)
+ {
+ btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
+ memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].param,
+ &p_inst_cb->param, sizeof(tBTA_BLE_ADV_PARAMS));
+
+ BTA_BleEnableAdvInstance(&(p_multi_adv_data_cb->inst_cb[cbindex].param),
+ bta_gattc_multi_adv_cback,
+ &(p_multi_adv_data_cb->clntif_map[arrindex][CLNT_IF_IDX]));
+ }
else
- BTA_DmBleSetScanRsp(p_cb->adv_data.mask, &p_cb->adv_data.data);
+ BTIF_TRACE_ERROR1("%s invalid index in BTIF_GATTC_ENABLE_ADV",__FUNCTION__);
+ break;
+ }
- // Cleanup ...
+ case BTIF_GATTC_ADV_INSTANCE_UPDATE:
+ {
+ if(NULL == p_inst_cb)
+ return;
- // ... manufacturer data
- if (p_cb->adv_data.data.manu.p_val != NULL)
- GKI_freebuf(p_cb->adv_data.data.manu.p_val);
+ int inst_id = btif_multi_adv_instid_for_clientif(p_inst_cb->client_if);
+ int cbindex = btif_gattc_obtain_idx_for_datacb(p_inst_cb->client_if, CLNT_IF_IDX);
+ if(inst_id >= 0 && cbindex >= 0 && NULL != p_inst_cb)
+ {
+ btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
+ memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].param, &p_inst_cb->param,
+ sizeof(tBTA_BLE_ADV_PARAMS));
+ BTA_BleUpdateAdvInstParam((UINT8)inst_id,
+ &(p_multi_adv_data_cb->inst_cb[cbindex].param));
+ }
+ else
+ BTIF_TRACE_ERROR1("%s invalid index in BTIF_GATTC_UPDATE_ADV", __FUNCTION__);
+ break;
+ }
+
+ case BTIF_GATTC_ADV_INSTANCE_SET_DATA:
+ {
+ if(NULL == p_adv_data)
+ return;
- // ... service data
- if (p_cb->adv_data.data.p_proprietary != NULL)
+ int cbindex = btif_gattc_obtain_idx_for_datacb(p_adv_data->client_if, CLNT_IF_IDX);
+ int inst_id = btif_multi_adv_instid_for_clientif(p_adv_data->client_if);
+ if(inst_id < 0 || cbindex < 0)
{
- int i = 0;
- tBTA_BLE_PROP_ELEM *p_elem = p_cb->adv_data.data.p_proprietary->p_elem;
- while (i++ != p_cb->adv_data.data.p_proprietary->num_elem && p_elem)
- {
- if (p_elem->p_val != NULL)
- GKI_freebuf(p_elem->p_val);
- ++p_elem;
- }
- if (p_cb->adv_data.data.p_proprietary->p_elem != NULL)
- GKI_freebuf(p_cb->adv_data.data.p_proprietary->p_elem);
- GKI_freebuf(p_cb->adv_data.data.p_proprietary);
+ BTIF_TRACE_ERROR1("%s invalid index in BTIF_GATTC_SETADV_INST_DATA", __FUNCTION__);
+ return;
}
- // ... service list
- if (p_cb->adv_data.data.services.p_uuid != NULL)
- GKI_freebuf(p_cb->adv_data.data.services.p_uuid);
+ if(!btif_gattc_copy_datacb(cbindex, p_adv_data, true))
+ return;
+
+ btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
+ BTA_BleCfgAdvInstData((UINT8)inst_id, p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp,
+ p_multi_adv_data_cb->inst_cb[cbindex].mask,
+ &p_multi_adv_data_cb->inst_cb[cbindex].data);
+ break;
+ }
+
+ case BTIF_GATTC_ADV_INSTANCE_DISABLE:
+ {
+ if(NULL == p_inst_cb)
+ return;
+ int inst_id = btif_multi_adv_instid_for_clientif(p_inst_cb->client_if);
+ if(inst_id >=0)
+ BTA_BleDisableAdvInstance((UINT8)inst_id);
+ else
+ BTIF_TRACE_ERROR1("%s invalid instance ID in BTIF_GATTC_DISABLE_ADV",__FUNCTION__);
break;
}
+
case BTIF_GATTC_CONFIGURE_MTU:
BTA_GATTC_ConfigureMTU(p_cb->conn_id, p_cb->len);
break;
uint16_t service_uuid_len, char* service_uuid)
{
CHECK_BTGATT_INIT();
- btif_gattc_cb_t btif_cb;
- memset(&btif_cb, 0, sizeof(btif_gattc_cb_t));
- memset(&btif_cb.adv_data, 0, sizeof(btgatt_adv_data));
-
- btif_cb.client_if = (uint8_t) client_if;
- btif_cb.start = set_scan_rsp ? 1 : 0;
-
- if (!set_scan_rsp)
- {
- btif_cb.adv_data.mask = BTM_BLE_AD_BIT_FLAGS;
- btif_cb.adv_data.data.flag = ADV_FLAGS;
- }
-
- if (include_name)
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_DEV_NAME;
-
- if (include_txpower)
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_TX_PWR;
-
- if (min_interval > 0 && max_interval > 0 && max_interval > min_interval)
- {
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_INT_RANGE;
- btif_cb.adv_data.data.int_range.low = min_interval;
- btif_cb.adv_data.data.int_range.hi = max_interval;
- }
-
- if (appearance != 0)
- {
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_APPEARANCE;
- btif_cb.adv_data.data.appearance = appearance;
- }
-
- if (manufacturer_len > 0 && manufacturer_data != NULL)
- {
- btif_cb.adv_data.data.manu.p_val = GKI_getbuf(manufacturer_len);
- if (btif_cb.adv_data.data.manu.p_val != NULL)
- {
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_MANU;
- btif_cb.adv_data.data.manu.len = manufacturer_len;
- memcpy(btif_cb.adv_data.data.manu.p_val, manufacturer_data, manufacturer_len);
- }
- }
-
- tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
- tBTA_BLE_PROP_ELEM *p_elem_service_128 = NULL;
-
- if (service_data_len > 0 && service_data != NULL)
- {
- p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
- if (p_elem_service_data != NULL)
- {
- p_elem_service_data->p_val = GKI_getbuf(service_data_len);
- if (p_elem_service_data->p_val != NULL)
- {
- p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
- p_elem_service_data->len = service_data_len;
- memcpy(p_elem_service_data->p_val, service_data, service_data_len);
-
- } else {
- GKI_freebuf(p_elem_service_data);
- p_elem_service_data = NULL;
- }
- }
- }
-
- if (service_uuid_len > 0 && service_uuid != NULL)
- {
- btif_cb.adv_data.data.services.list_cmpl = FALSE;
- btif_cb.adv_data.data.services.num_service = 0;
-
- btif_cb.adv_data.data.services.p_uuid =
- GKI_getbuf(service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
- if (btif_cb.adv_data.data.services.p_uuid != NULL)
- {
- UINT16 *p_uuid_out = btif_cb.adv_data.data.services.p_uuid;
- while (service_uuid_len >= LEN_UUID_128)
- {
- bt_uuid_t uuid;
- memset(&uuid, 0, sizeof(bt_uuid_t));
- memcpy(&uuid.uu, service_uuid, LEN_UUID_128);
-
- tBT_UUID bt_uuid;
- memset(&bt_uuid, 0, sizeof(tBT_UUID));
- btif_to_bta_uuid(&bt_uuid, &uuid);
-
- if (bt_uuid.len == LEN_UUID_16)
- {
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_SERVICE;
- ++btif_cb.adv_data.data.services.num_service;
- *p_uuid_out++ = bt_uuid.uu.uuid16;
-
- } else if (bt_uuid.len == LEN_UUID_128 && p_elem_service_128 == NULL) {
- /* Currently, only one 128-bit UUID is supported */
- p_elem_service_128 = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
- if (p_elem_service_128 != NULL)
- {
- p_elem_service_128->p_val = GKI_getbuf(LEN_UUID_128);
- if (p_elem_service_128->p_val != NULL)
- {
- p_elem_service_128->adv_type = BTM_BLE_AD_TYPE_128SRV_PART;
- p_elem_service_128->len = LEN_UUID_128;
- memcpy(p_elem_service_128->p_val, bt_uuid.uu.uuid128, LEN_UUID_128);
+ bt_status_t status =0;
- } else {
- GKI_freebuf(p_elem_service_128);
- p_elem_service_128 = NULL;
- }
- }
- }
+ btif_adv_data_t adv_data;
- service_uuid += LEN_UUID_128;
- service_uuid_len -= LEN_UUID_128;
- }
- }
- }
+ btif_gattc_adv_data_packager(client_if, set_scan_rsp, include_name,
+ include_txpower, min_interval, max_interval, appearance, manufacturer_len,
+ manufacturer_data, service_data_len, service_data, service_uuid_len, service_uuid,
+ &adv_data);
- if (p_elem_service_data != NULL || p_elem_service_128 != NULL)
- {
- btif_cb.adv_data.data.p_proprietary = GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
- if (btif_cb.adv_data.data.p_proprietary != NULL)
- {
- tBTA_BLE_PROPRIETARY *p_prop = btif_cb.adv_data.data.p_proprietary;
- tBTA_BLE_PROP_ELEM *p_elem = NULL;
- p_prop->num_elem = 0;
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_PROPRIETARY;
+ status = btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
+ (char*) &adv_data, sizeof(btif_adv_data_t), NULL);
- if (p_elem_service_128 != NULL)
- ++p_prop->num_elem;
+ if (NULL != adv_data.p_service_data)
+ GKI_freebuf(adv_data.p_service_data);
- if (p_elem_service_data != NULL)
- ++p_prop->num_elem;
+ if (NULL != adv_data.p_service_uuid)
+ GKI_freebuf(adv_data.p_service_uuid);
- p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
- p_elem = p_prop->p_elem;
+ if (NULL != adv_data.p_manufacturer_data)
+ GKI_freebuf(adv_data.p_manufacturer_data);
- if (p_elem_service_128 != NULL)
- {
- memcpy(p_elem++, p_elem_service_128, sizeof(tBTA_BLE_PROP_ELEM));
- GKI_freebuf(p_elem_service_128);
- }
-
- if (p_elem_service_data != NULL)
- {
- memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
- GKI_freebuf(p_elem_service_data);
- }
- }
- }
-
-#if (defined(BLE_PERIPHERAL_ADV_NAME) && (BLE_PERIPHERAL_ADV_NAME == TRUE))
- btif_cb.adv_data.mask |= BTM_BLE_AD_BIT_DEV_NAME;
-#endif
-
- return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_SET_ADV_DATA,
- (char*) &btif_cb, sizeof(btif_gattc_cb_t), NULL);
+ return status;
}
static bt_status_t btif_gattc_refresh( int client_if, const bt_bdaddr_t *bd_addr )
return 0;
}
+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)
+{
+ CHECK_BTGATT_INIT();
+ btgatt_multi_adv_inst_cb adv_cb;
+ adv_cb.client_if = (uint8_t) client_if;
+
+ adv_cb.param.adv_int_min = min_interval;
+ adv_cb.param.adv_int_max = max_interval;
+ adv_cb.param.adv_type = adv_type;
+ adv_cb.param.channel_map = chnl_map;
+ adv_cb.param.adv_filter_policy = 0;
+ adv_cb.param.tx_power = tx_power;
+ 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)
+{
+ CHECK_BTGATT_INIT();
+ btgatt_multi_adv_inst_cb adv_cb;
+ adv_cb.client_if = (uint8_t) client_if;
+
+ adv_cb.param.adv_int_min = min_interval;
+ adv_cb.param.adv_int_max = max_interval;
+ adv_cb.param.adv_type = adv_type;
+ adv_cb.param.channel_map = chnl_map;
+ adv_cb.param.adv_filter_policy = 0;
+ adv_cb.param.tx_power = tx_power;
+ 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)
+{
+ CHECK_BTGATT_INIT();
+
+ int min_interval = 0, max_interval = 0;
+ bt_status_t status =0;
+
+ btif_adv_data_t multi_adv_data_inst;
+
+ btif_gattc_adv_data_packager(client_if, set_scan_rsp, include_name, incl_txpower,
+ min_interval, max_interval, appearance, manufacturer_len, manufacturer_data,
+ service_data_len, service_data, service_uuid_len, service_uuid, &multi_adv_data_inst);
+
+ status = btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_SET_DATA,
+ (char*) &multi_adv_data_inst, sizeof(btif_adv_data_t), NULL);
+
+ if (NULL != multi_adv_data_inst.p_service_data)
+ GKI_freebuf(multi_adv_data_inst.p_service_data);
+
+ if (NULL != multi_adv_data_inst.p_service_uuid)
+ GKI_freebuf(multi_adv_data_inst.p_service_uuid);
+
+ if (NULL != multi_adv_data_inst.p_manufacturer_data)
+ GKI_freebuf(multi_adv_data_inst.p_manufacturer_data);
+
+ return status;
+}
+
+static bt_status_t btif_gattc_multi_adv_disable(int client_if)
+{
+ CHECK_BTGATT_INIT();
+ btgatt_multi_adv_inst_cb adv_cb;
+ adv_cb.client_if = (uint8_t) client_if;
+
+ return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_DISABLE,
+ (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
+}
+
extern bt_status_t btif_gattc_test_command_impl(int command, btgatt_test_params_t* params);
static bt_status_t btif_gattc_test_command(int command, btgatt_test_params_t* params)
btif_gattc_set_adv_data,
btif_gattc_configure_mtu,
btif_gattc_set_scan_parameters,
+ btif_gattc_multi_adv_enable,
+ btif_gattc_multi_adv_update,
+ btif_gattc_multi_adv_setdata,
+ btif_gattc_multi_adv_disable,
btif_gattc_test_command
};
--- /dev/null
+/******************************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+
+/*******************************************************************************
+ *
+ * Filename: btif_gatt_multi_adv_util.c
+ *
+ * Description: Multi ADV helper implementation
+ *
+ *******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define LOG_TAG "BtGatt.btif"
+#if (BLE_INCLUDED == TRUE)
+
+#include "btif_gatt_multi_adv_util.h"
+#include "btif_common.h"
+#include <hardware/bt_gatt.h>
+#include "bta_gatt_api.h"
+#include "btif_gatt_util.h"
+
+/*******************************************************************************
+** Static variables
+********************************************************************************/
+static int multi_adv_enable_count = 0;
+static btgatt_multi_adv_common_data *p_multi_adv_com_data_cb = NULL;
+
+btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
+{
+ if(p_multi_adv_com_data_cb == NULL)
+ p_multi_adv_com_data_cb = GKI_getbuf(sizeof(btgatt_multi_adv_common_data));
+ return p_multi_adv_com_data_cb;
+}
+
+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(multi_adv_enable_count == 0)
+ {
+ memset(p_multi_adv_data_cb,0,sizeof(btgatt_multi_adv_common_data));
+
+ for (i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX] = INVALID_ADV_INST;
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = INVALID_ADV_INST;
+ }
+ }
+ multi_adv_enable_count++;
+}
+
+void btif_gattc_destroy_multi_adv_cb()
+{
+ if(multi_adv_enable_count > 0)
+ multi_adv_enable_count --;
+ if(multi_adv_enable_count == 0)
+ {
+ GKI_freebuf(p_multi_adv_com_data_cb);
+ p_multi_adv_com_data_cb = NULL;
+ }
+}
+
+int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid)
+{
+ 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 INVALID_ADV_INST;
+
+ for(i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ if(client_if == p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX])
+ {
+ if(!gen_temp_instid)
+ {
+ // Write the final inst_id value obtained from stack layer
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = inst_id;
+ BTIF_TRACE_DEBUG3("%s -Index: %d, Found client_if: %d", __FUNCTION__,
+ i, p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX]);
+ break;
+ }
+ else
+ {
+ //Store the passed in inst_id value
+ if(inst_id != INVALID_ADV_INST)
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = inst_id;
+ else
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = (i + 1);
+ BTIF_TRACE_DEBUG3("%s - Index:%d,Found client_if: %d", __FUNCTION__,
+ i, p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX]);
+ break;
+ }
+ }
+ }
+
+ if(i < BTM_BLE_MULTI_ADV_MAX)
+ return i;
+
+ // If client ID if is not found, then write both values
+ for(i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ if(INVALID_ADV_INST == p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX])
+ {
+ p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX] = client_if;
+ if(inst_id != INVALID_ADV_INST)
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = inst_id;
+ else
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = (i + 1);
+ BTIF_TRACE_DEBUG4("%s -Not found - Index:%d, client_if: %d, Inst ID: %d",
+ __FUNCTION__,i,
+ p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX],
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX]);
+ break;
+ }
+ }
+
+ if(i < BTM_BLE_MULTI_ADV_MAX)
+ return i;
+ return INVALID_ADV_INST;
+}
+
+int btif_multi_adv_instid_for_clientif(int client_if)
+{
+ int i=0, ret = INVALID_ADV_INST;
+
+ 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;
+
+ // Retrieve the existing inst_id for the client_if value
+ for(i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ if(client_if == p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX])
+ ret = p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX];
+ }
+
+ if(ret != INVALID_ADV_INST)
+ return ret;
+
+ return INVALID_ADV_INST;
+}
+
+
+int btif_gattc_obtain_idx_for_datacb(int value, int arrindex)
+{
+ 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 INVALID_ADV_INST;
+
+ // Retrieve the array index for the inst_id value
+ for(i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
+ {
+ if(value == p_multi_adv_data_cb->clntif_map[i][arrindex])
+ break;
+ }
+
+ if(i < BTM_BLE_MULTI_ADV_MAX)
+ {
+ BTIF_TRACE_DEBUG2("%s, %d",__FUNCTION__,i+1);
+ return (i + 1);
+ }
+
+ BTIF_TRACE_DEBUG1("%s Invalid instance",__FUNCTION__);
+ 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,
+ char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
+{
+ memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
+
+ p_multi_adv_inst->client_if = (uint8_t) client_if;
+ p_multi_adv_inst->set_scan_rsp = set_scan_rsp;
+ p_multi_adv_inst->include_name = include_name;
+ p_multi_adv_inst->include_txpower = include_txpower;
+ p_multi_adv_inst->min_interval = min_interval;
+ p_multi_adv_inst->max_interval = max_interval;
+ p_multi_adv_inst->appearance = appearance;
+ p_multi_adv_inst->manufacturer_len = manufacturer_len;
+
+ if(manufacturer_len > 0)
+ {
+ p_multi_adv_inst->p_manufacturer_data = GKI_getbuf(manufacturer_len);
+ memcpy(p_multi_adv_inst->p_manufacturer_data, manufacturer_data, manufacturer_len);
+ }
+
+ p_multi_adv_inst->service_data_len = service_data_len;
+ if(service_data_len > 0)
+ {
+ p_multi_adv_inst->p_service_data = GKI_getbuf(service_data_len);
+ memcpy(p_multi_adv_inst->p_service_data, service_data, service_data_len);
+ }
+
+ p_multi_adv_inst->service_uuid_len = service_uuid_len;
+ if(service_uuid_len > 0)
+ {
+ p_multi_adv_inst->p_service_uuid = GKI_getbuf(service_uuid_len);
+ memcpy(p_multi_adv_inst->p_service_uuid, service_uuid, service_uuid_len);
+ }
+}
+
+BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN bInstData)
+{
+ 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 || cbindex < 0)
+ return false;
+
+ BTIF_TRACE_DEBUG1("%s", __FUNCTION__);
+ memset(&p_multi_adv_data_cb->inst_cb[cbindex],0, sizeof(btgatt_multi_adv_inst_cb));
+ memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0, sizeof(tBTA_BLE_ADV_DATA));
+
+ if (!p_adv_data->set_scan_rsp)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp = p_adv_data->set_scan_rsp ? 1 : 0;
+ 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;
+ }
+
+ if (p_adv_data->include_name)
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
+
+ if (p_adv_data->include_txpower)
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_TX_PWR;
+
+ if (false == bInstData && p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
+ p_adv_data->max_interval > p_adv_data->min_interval)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_INT_RANGE;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
+ p_adv_data->min_interval;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
+ p_adv_data->max_interval;
+ }
+ else
+ if(true == bInstData)
+ {
+ if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min > 0 &&
+ p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max > 0 &&
+ p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max >
+ p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
+ p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
+ p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max;
+ }
+
+ if (p_adv_data->include_txpower)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.tx_power =
+ p_multi_adv_data_cb->inst_cb[cbindex].param.tx_power;
+ }
+ }
+
+ if (p_adv_data->appearance != 0)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_APPEARANCE;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
+ }
+
+ if (p_adv_data->manufacturer_len > 0 && p_adv_data->p_manufacturer_data != NULL)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu =
+ GKI_getbuf(sizeof(tBTA_BLE_MANU));
+ if(p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu != NULL)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val =
+ GKI_getbuf(p_adv_data->manufacturer_len);
+ if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val != NULL)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->len =
+ p_adv_data->manufacturer_len;
+ memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val,
+ p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
+ }
+ }
+ }
+
+ tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
+ tBTA_BLE_PROP_ELEM *p_elem_service_128 = NULL;
+
+ if (p_adv_data->service_data_len > 0 && p_adv_data->p_service_data != NULL)
+ {
+ BTIF_TRACE_DEBUG1("%s - In service_data", __FUNCTION__);
+ p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+ if (p_elem_service_data != NULL)
+ {
+ p_elem_service_data->p_val = GKI_getbuf(p_adv_data->service_data_len);
+ if (p_elem_service_data->p_val != NULL)
+ {
+ p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
+ p_elem_service_data->len = p_adv_data->service_data_len;
+ memcpy(p_elem_service_data->p_val, p_adv_data->p_service_data,
+ p_adv_data->service_data_len);
+ } else {
+ GKI_freebuf(p_elem_service_data);
+ p_elem_service_data = NULL;
+ }
+ }
+ }
+
+ if (p_adv_data->service_uuid_len > 0 && p_adv_data->p_service_uuid != NULL)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_services =
+ GKI_getbuf(sizeof(tBTA_BLE_SERVICE));
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->list_cmpl = FALSE;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service = 0;
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid =
+ GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
+ if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid != NULL)
+ {
+ UINT16 *p_uuid_out = p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid;
+ while (p_adv_data->service_uuid_len >= LEN_UUID_128)
+ {
+ bt_uuid_t uuid;
+ memset(&uuid, 0, sizeof(bt_uuid_t));
+ memcpy(&uuid.uu, p_adv_data->p_service_uuid, LEN_UUID_128);
+ tBT_UUID bt_uuid;
+ memset(&bt_uuid, 0, sizeof(tBT_UUID));
+ btif_to_bta_uuid(&bt_uuid, &uuid);
+
+ if (bt_uuid.len == LEN_UUID_16)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
+ ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service;
+ *p_uuid_out++ = bt_uuid.uu.uuid16;
+ } else if (bt_uuid.len == LEN_UUID_128 && p_elem_service_128 == NULL) {
+ /* Currently, only one 128-bit UUID is supported */
+ p_elem_service_128 = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
+ if (p_elem_service_128 != NULL)
+ {
+ p_elem_service_128->p_val = GKI_getbuf(LEN_UUID_128);
+ if (p_elem_service_128->p_val != NULL)
+ {
+ p_elem_service_128->adv_type = BTM_BLE_AD_TYPE_128SRV_PART;
+ p_elem_service_128->len = LEN_UUID_128;
+ memcpy(p_elem_service_128->p_val, bt_uuid.uu.uuid128, LEN_UUID_128);
+ } else {
+ GKI_freebuf(p_elem_service_128);
+ p_elem_service_128 = NULL;
+ }
+ }
+ }
+ p_adv_data->p_service_uuid += LEN_UUID_128;
+ p_adv_data->service_uuid_len -= LEN_UUID_128;
+ }
+ }
+ }
+
+ if (p_elem_service_data != NULL || p_elem_service_128 != NULL)
+ {
+ p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary =
+ GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
+ if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary != NULL)
+ {
+ tBTA_BLE_PROPRIETARY *p_prop = p_multi_adv_data_cb->inst_cb[cbindex].
+ data.p_proprietary;
+ tBTA_BLE_PROP_ELEM *p_elem = NULL;
+ p_prop->num_elem = 0;
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
+ if (p_elem_service_128 != NULL)
+ ++p_prop->num_elem;
+ if (p_elem_service_data != NULL)
+ ++p_prop->num_elem;
+ p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
+ p_elem = p_prop->p_elem;
+ if (p_elem_service_128 != NULL)
+ {
+ memcpy(p_elem++, p_elem_service_128, sizeof(tBTA_BLE_PROP_ELEM));
+ GKI_freebuf(p_elem_service_128);
+ }
+ if (p_elem_service_data != NULL)
+ {
+ memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
+ GKI_freebuf(p_elem_service_data);
+ }
+ }
+ }
+
+#if (defined(BLE_PERIPHERAL_ADV_NAME) && (BLE_PERIPHERAL_ADV_NAME == TRUE))
+ p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
+#endif
+ return true;
+}
+
+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_BLE_MULTI_ADV_MAX; i++)
+ {
+ if(client_if == p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX])
+ {
+ p_multi_adv_data_cb->clntif_map[i][INST_ID_IDX] = INVALID_ADV_INST;
+ p_multi_adv_data_cb->clntif_map[i][CLNT_IF_IDX] = INVALID_ADV_INST;
+ BTIF_TRACE_DEBUG2("Cleaning up index %d for clnt_if :%d,", i, client_if);
+ break;
+ }
+ }
+}
+
+void btif_gattc_cleanup_inst_cb(int inst_id)
+{
+ int cbindex = 0;
+ // Check for invalid instance id
+ if (inst_id < 0 || inst_id > BTM_BLE_MULTI_ADV_MAX)
+ 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;
+
+ if(inst_id > 0)
+ {
+ 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;
+
+ BTIF_TRACE_DEBUG2("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]);
+}
+
+void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb)
+{
+ // Manufacturer data cleanup
+ if (p_multi_inst_cb->data.p_manu != NULL)
+ {
+ if (p_multi_inst_cb->data.p_manu->p_val != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_manu->p_val);
+ GKI_freebuf(p_multi_inst_cb->data.p_manu);
+ }
+
+ // Proprietary data cleanup
+ if (p_multi_inst_cb->data.p_proprietary != NULL)
+ {
+ int i = 0;
+ tBTA_BLE_PROP_ELEM *p_elem = p_multi_inst_cb->data.p_proprietary->p_elem;
+ while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem
+ && p_elem)
+ {
+ if (p_elem->p_val != NULL)
+ GKI_freebuf(p_elem->p_val);
+ ++p_elem;
+ }
+
+ if (p_multi_inst_cb->data.p_proprietary->p_elem != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_proprietary->p_elem);
+ GKI_freebuf(p_multi_inst_cb->data.p_proprietary);
+ }
+
+ // Service list cleanup
+ if (p_multi_inst_cb->data.p_services != NULL)
+ {
+ if (p_multi_inst_cb->data.p_services->p_uuid != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_services->p_uuid);
+ GKI_freebuf(p_multi_inst_cb->data.p_services);
+ }
+
+ // Service data cleanup
+ if (p_multi_inst_cb->data.p_service_data != NULL)
+ {
+ if (p_multi_inst_cb->data.p_service_data->p_val != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_service_data->p_val);
+ GKI_freebuf(p_multi_inst_cb->data.p_service_data);
+ }
+
+ if (p_multi_inst_cb->data.p_services_128b != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_services_128b);
+
+ if (p_multi_inst_cb->data.p_service_32b != NULL)
+ {
+ if (p_multi_inst_cb->data.p_service_32b->p_uuid != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_service_32b->p_uuid);
+ GKI_freebuf(p_multi_inst_cb->data.p_service_32b);
+ }
+
+ if (p_multi_inst_cb->data.p_sol_services != NULL)
+ {
+ if (p_multi_inst_cb->data.p_sol_services->p_uuid != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_sol_services->p_uuid);
+ GKI_freebuf(p_multi_inst_cb->data.p_sol_services);
+ }
+
+ if (p_multi_inst_cb->data.p_sol_service_32b != NULL)
+ {
+ if (p_multi_inst_cb->data.p_sol_service_32b->p_uuid != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b->p_uuid);
+ GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b);
+ }
+
+ if(p_multi_inst_cb->data.p_sol_service_128b != NULL)
+ GKI_freebuf(p_multi_inst_cb->data.p_sol_service_128b);
+}
+
+#endif
#define BLE_ANDROID_CONTROLLER_SCAN_FILTER TRUE
#endif
-
#ifndef LOCAL_BLE_CONTROLLER_ID
#define LOCAL_BLE_CONTROLLER_ID (1)
#endif
#define BLE_PRIVACY_SPT TRUE
#endif
+#ifndef BLE_MULTI_ADV_INCLUDED
+#define BLE_MULTI_ADV_INCLUDED TRUE
+#endif
+
+
/******************************************************************************
**
** ATT/GATT Protocol/Profile Settings
../btif/src/btif_sock_util.c \
../btif/src/btif_pan.c \
../btif/src/btif_gatt.c \
+ ../btif/src/btif_gatt_multi_adv_util.c \
../btif/src/btif_gatt_client.c \
../btif/src/btif_gatt_server.c \
../btif/src/btif_gatt_util.c \
./btm/btm_main.c \
./btm/btm_dev.c \
./btm/btm_ble_gap.c \
+ ./btm/btm_ble_multi_adv.c \
./btm/btm_acl.c \
./btm/btm_sco.c \
./btm/btm_pm.c \
if (callback_rc == BTM_SUCCESS)
#endif
{
+#if BTM_BLE_CONFORMANCE_TESTING == TRUE
+ if (btm_cb.devcb.keep_rfu_in_auth_req)
+ {
+ BTM_TRACE_DEBUG1 ("btm_ble_io_capabilities_req keep_rfu_in_auth_req = %u",
+ btm_cb.devcb.keep_rfu_in_auth_req);
+ p_data->auth_req &= BTM_LE_AUTH_REQ_MASK_KEEP_RFU;
+ btm_cb.devcb.keep_rfu_in_auth_req = FALSE;
+ }
+ else
+ { /* default */
+ p_data->auth_req &= BTM_LE_AUTH_REQ_MASK;
+ }
+#else
p_data->auth_req &= BTM_LE_AUTH_REQ_MASK;
+#endif
BTM_TRACE_DEBUG2 ("btm_ble_io_capabilities_req 1: p_dev_rec->security_required = %d auth_req:%d",
p_dev_rec->security_required, p_data->auth_req);
{
role = HCI_ROLE_UNKNOWN;
- if (status == HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT)
+ if (status != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT)
{
- btm_ble_dir_adv_tout();
+ btm_ble_set_conn_st(BLE_CONN_IDLE);
}
/* this is to work around broadcom firmware problem to handle
* unsolicited command complete event for HCI_LE_Create_Connection_Cancel
}
+
+/*******************************************************************************
+**
+** Function btm_ble_set_keep_rfu_in_auth_req
+**
+** Description This function indicates if RFU bits have to be kept as is
+** (by default they have to be set to 0 by the sender).
+**
+** Returns void
+**
+*******************************************************************************/
+void btm_ble_set_keep_rfu_in_auth_req(BOOLEAN keep_rfu)
+{
+ BTM_TRACE_DEBUG1 ("btm_ble_set_keep_rfu_in_auth_req keep_rfus=%d", keep_rfu);
+ btm_cb.devcb.keep_rfu_in_auth_req = keep_rfu;
+}
+
#endif /* BTM_BLE_CONFORMANCE_TESTING */
#endif /* BLE_INCLUDED */
#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
#include "btm_ble_int.h"
#include "smp_api.h"
-#define BTM_BLE_PRIVATE_ADDR_INT 900 /* 15 minutes minimum for
- random address refreshing */
/*******************************************************************************
**
/* start a periodical timer to refresh random addr */
btu_stop_timer(&p_cb->raddr_timer_ent);
+#if (BTM_BLE_CONFORMANCE_TESTING == TRUE)
+ btu_start_timer (&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
+ btm_cb.ble_ctr_cb.rpa_tout);
+#else
btu_start_timer (&p_cb->raddr_timer_ent, BTU_TTYPE_BLE_RANDOM_ADDR,
BTM_BLE_PRIVATE_ADDR_INT);
-
+#endif
}
else
{
** Returns void
**
*******************************************************************************/
-static void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p)
+void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p)
{
#if (BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
** Returns void
**
*******************************************************************************/
-void btm_gen_resolvable_private_addr (void)
+void btm_gen_resolvable_private_addr (void *p_cmd_cplt_cback)
{
BTM_TRACE_EVENT0 ("btm_gen_resolvable_private_addr");
/* generate 3B rand as BD LSB, SRK with it, get BD MSB */
- if (!btsnd_hcic_ble_rand((void *)btm_gen_resolve_paddr_low))
+ if (!btsnd_hcic_ble_rand((void *)p_cmd_cplt_cback))
btm_gen_resolve_paddr_cmpl(NULL);
}
/*******************************************************************************
/******************************************************************************
*
- * Copyright (C) 2008-2012 Broadcom Corporation
+ * Copyright (C) 2008-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.
#define BTM_BLE_POLICY_UNKNOWN 0xff
#define BTM_EXT_BLE_RMT_NAME_TIMEOUT 30
+#define MIN_ADV_LENGTH 2
+
+extern tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
/*******************************************************************************
** Local functions
*******************************************************************************/
static void btm_ble_update_adv_flag(UINT8 flag);
static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p);
-static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data);
+UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
+ tBTM_BLE_ADV_DATA *p_data);
static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
BD_ADDR_PTR p_addr_ptr,
tBLE_ADDR_TYPE *p_init_addr_type,
/*******************************************************************************
**
+** Function btm_vsc_brcm_features_complete
+**
+** Description Command Complete callback for HCI_BLE_VENDOR_CAP_OCF
+**
+** Returns void
+**
+*******************************************************************************/
+static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params)
+{
+ UINT8 status = 0xFF, *p;
+ UINT8 rpa_offloading, max_irk_list_sz, filtering_support, max_filter;
+ UINT16 scan_result_storage;
+
+ /* Check status of command complete event */
+ if((p_vcs_cplt_params->opcode == HCI_BLE_VENDOR_CAP_OCF)
+ &&(p_vcs_cplt_params->param_len > 0 ))
+ {
+ p = p_vcs_cplt_params->p_param_buf;
+ STREAM_TO_UINT8 (status, p);
+ }
+
+ if(status == HCI_SUCCESS)
+ {
+ STREAM_TO_UINT8 (btm_multi_adv_cb.adv_inst_max, p);
+ STREAM_TO_UINT8 (rpa_offloading, p);
+ STREAM_TO_UINT16 (scan_result_storage, p);
+ STREAM_TO_UINT8 (max_irk_list_sz, p);
+ STREAM_TO_UINT8 (filtering_support, p);
+ STREAM_TO_UINT8 (max_filter, p);
+ }
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_vendor_capability_init
+**
+** Description LE Get_Vendor Capabilities
+**
+** Returns None.
+**
+*******************************************************************************/
+void btm_ble_vendor_capability_init(void)
+{
+ if ( BTM_VendorSpecificCommand (HCI_BLE_VENDOR_CAP_OCF,
+ 0,
+ NULL,
+ btm_ble_vendor_capability_vsc_cmpl_cback)
+ != BTM_CMD_STARTED)
+ {
+ BTM_TRACE_ERROR0("LE Get_Vendor Capabilities Command Failed.");
+ }
+ return ;
+}
+
+/*******************************************************************************
+**
** Function BTM_RegisterScanReqEvt
**
** Description This function is called to register a scan request callback
if (p_cb->privacy)
{
/* generate resolvable private address */
- btm_gen_resolvable_private_addr();
+ btm_gen_resolvable_private_addr(NULL);
}
else /* if privacy disabled, always use public address */
{
!BTM_BLE_IS_RESOLVE_BDA(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr))
{
/* need to generate RRA and update random addresss in controller */
- btm_gen_resolvable_private_addr();
+ btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
}
#endif
}
p_cb_data->p_pad = p;
- if (data_mask != 0)
+ if (mask != 0)
{
BTM_TRACE_ERROR0("Partial data write into ADV");
}
**
** Description This function is called build the adv data and rsp data.
*******************************************************************************/
-static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data)
+UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
+ tBTM_BLE_ADV_DATA *p_data)
{
- UINT16 data_mask = *p_data_mask;
+ UINT32 data_mask = *p_data_mask;
UINT8 *p = *p_dst,
*p_flag = NULL;
UINT16 len = BTM_BLE_AD_DATA_LEN, cp_len = 0;
/* flags */
if (data_mask & BTM_BLE_AD_BIT_FLAGS)
{
- *p++ = 2;
+ *p++ = MIN_ADV_LENGTH;
*p++ = BTM_BLE_AD_TYPE_FLAG;
p_flag = p;
if (p_data)
}
/* device name */
#if BTM_MAX_LOC_BD_NAME_LEN > 0
- if (len > 2 && data_mask & BTM_BLE_AD_BIT_DEV_NAME)
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_DEV_NAME)
{
- if (strlen(btm_cb.cfg.bd_name) > (UINT16)(len - 2))
+ if (strlen(btm_cb.cfg.bd_name) > (UINT16)(len - MIN_ADV_LENGTH))
{
- *p++ = len - 2 + 1;
+ *p++ = len - MIN_ADV_LENGTH + 1;
*p++ = BTM_BLE_AD_TYPE_NAME_SHORT;
- ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, len - 2);
+ ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, len - MIN_ADV_LENGTH);
}
else
{
*p++ = BTM_BLE_AD_TYPE_NAME_CMPL;
ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, cp_len);
}
- len -= (cp_len + 2);
+ len -= (cp_len + MIN_ADV_LENGTH);
data_mask &= ~BTM_BLE_AD_BIT_DEV_NAME;
}
#endif
/* manufacturer data */
- if (len > 2 && data_mask & BTM_BLE_AD_BIT_MANU &&
- p_data && p_data->manu.len != 0 && p_data->manu.p_val)
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_MANU &&
+ p_data && p_data->p_manu &&
+ p_data->p_manu->len != 0 && p_data->p_manu->p_val)
{
- if (p_data->manu.len > (len - 2))
- cp_len = len - 2;
+ if (p_data->p_manu->len > (len - MIN_ADV_LENGTH))
+ cp_len = len - MIN_ADV_LENGTH;
else
- cp_len = p_data->manu.len;
+ cp_len = p_data->p_manu->len;
*p++ = cp_len + 1;
*p++ = BTM_BLE_AD_TYPE_MANU;
- ARRAY_TO_STREAM(p, p_data->manu.p_val, cp_len);
+ ARRAY_TO_STREAM(p, p_data->p_manu->p_val, cp_len);
- len -= (cp_len + 2);
+ len -= (cp_len + MIN_ADV_LENGTH);
data_mask &= ~BTM_BLE_AD_BIT_MANU;
}
/* TX power */
- if (len > 2 && data_mask & BTM_BLE_AD_BIT_TX_PWR)
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_TX_PWR)
{
- *p++ = 2;
+ *p++ = MIN_ADV_LENGTH;
*p++ = BTM_BLE_AD_TYPE_TX_PWR;
- *p++ = btm_cb.ble_ctr_cb.inq_var.tx_power;
+ *p++ = p_data->tx_power;
len -= 3;
data_mask &= ~BTM_BLE_AD_BIT_TX_PWR;
}
- /* services */
- if (len > 2 && data_mask & BTM_BLE_AD_BIT_SERVICE &&
- p_data && p_data->services.num_service != 0 &&
- p_data->services.p_uuid)
+ /* 16 bits services */
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE &&
+ p_data && p_data->p_services &&
+ p_data->p_services->num_service != 0 &&
+ p_data->p_services->p_uuid)
{
- if (p_data->services.num_service * 2 > (len - 2))
+ if (p_data->p_services->num_service * LEN_UUID_16 > (len - MIN_ADV_LENGTH))
{
- cp_len = (len - 2)/2;
- *p ++ = 1 + cp_len * 2;
+ cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_16;
+ *p ++ = 1 + cp_len * LEN_UUID_16;
*p++ = BTM_BLE_AD_TYPE_16SRV_PART;
}
else
{
- cp_len = p_data->services.num_service;
- *p++ = 1 + cp_len * 2;
+ cp_len = p_data->p_services->num_service;
+ *p++ = 1 + cp_len * LEN_UUID_16;
*p++ = BTM_BLE_AD_TYPE_16SRV_CMPL;
}
for (i = 0; i < cp_len; i ++)
{
- UINT16_TO_STREAM(p, *(p_data->services.p_uuid + i));
+ UINT16_TO_STREAM(p, *(p_data->p_services->p_uuid + i));
}
- len -= (cp_len * 2 + 2);
+ len -= (cp_len * MIN_ADV_LENGTH + MIN_ADV_LENGTH);
data_mask &= ~BTM_BLE_AD_BIT_SERVICE;
}
+ /* 32 bits service uuid */
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_32 &&
+ p_data && p_data->p_service_32b &&
+ p_data->p_service_32b->num_service != 0 &&
+ p_data->p_service_32b->p_uuid)
+ {
+ if ((p_data->p_service_32b->num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
+ {
+ cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_32;
+ *p ++ = 1 + cp_len * LEN_UUID_32;
+ *p++ = BTM_BLE_AD_TYPE_32SRV_PART;
+ }
+ else
+ {
+ cp_len = p_data->p_service_32b->num_service;
+ *p++ = 1 + cp_len * LEN_UUID_32;
+ *p++ = BTM_BLE_AD_TYPE_32SRV_CMPL;
+ }
+ for (i = 0; i < cp_len; i ++)
+ {
+ UINT32_TO_STREAM(p, *(p_data->p_service_32b->p_uuid + i));
+ }
+
+ len -= (cp_len * LEN_UUID_32 + MIN_ADV_LENGTH);
+ data_mask &= ~BTM_BLE_AD_BIT_SERVICE_32;
+ }
+ /* 128 bits services */
+ if (len >= (MAX_UUID_SIZE + 2) && data_mask & BTM_BLE_AD_BIT_SERVICE_128 &&
+ p_data && p_data->p_services_128b)
+ {
+ *p ++ = 1 + MAX_UUID_SIZE;
+ if (!p_data->p_services_128b->list_cmpl)
+ *p++ = BTM_BLE_AD_TYPE_128SRV_PART;
+ else
+ *p++ = BTM_BLE_AD_TYPE_128SRV_CMPL;
+
+ ARRAY_TO_STREAM(p, p_data->p_services_128b->uuid128, MAX_UUID_SIZE);
+
+ len -= (MAX_UUID_SIZE + MIN_ADV_LENGTH);
+ data_mask &= ~BTM_BLE_AD_BIT_SERVICE_128;
+ }
+ /* 32 bits Service Solicitation UUIDs */
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_32SOL &&
+ p_data && p_data->p_sol_service_32b &&
+ p_data->p_sol_service_32b->num_service != 0 &&
+ p_data->p_sol_service_32b->p_uuid)
+ {
+ if ((p_data->p_sol_service_32b->num_service * LEN_UUID_32) > (len - MIN_ADV_LENGTH))
+ {
+ cp_len = (len - MIN_ADV_LENGTH)/LEN_UUID_32;
+ *p ++ = 1 + cp_len * LEN_UUID_32;
+ }
+ else
+ {
+ cp_len = p_data->p_sol_service_32b->num_service;
+ *p++ = 1 + cp_len * LEN_UUID_32;
+ }
+
+ *p++ = BTM_BLE_AD_TYPE_32SOL_SRV_UUID;
+ for (i = 0; i < cp_len; i ++)
+ {
+ UINT32_TO_STREAM(p, *(p_data->p_sol_service_32b->p_uuid + i));
+ }
+
+ len -= (cp_len * LEN_UUID_32 + MIN_ADV_LENGTH);
+ data_mask &= ~BTM_BLE_AD_BIT_SERVICE_32SOL;
+ }
+ /* 128 bits Solicitation services UUID */
+ if (len >= (MAX_UUID_SIZE + MIN_ADV_LENGTH) && data_mask & BTM_BLE_AD_BIT_SERVICE_128SOL &&
+ p_data && p_data->p_sol_service_128b)
+ {
+ *p ++ = 1 + MAX_UUID_SIZE;
+ *p++ = BTM_BLE_AD_TYPE_128SOL_SRV_UUID;
+ ARRAY_TO_STREAM(p, p_data->p_sol_service_128b->uuid128, MAX_UUID_SIZE);
+ len -= (MAX_UUID_SIZE + MIN_ADV_LENGTH);
+ data_mask &= ~BTM_BLE_AD_BIT_SERVICE_128SOL;
+ }
+ /* 16bits/32bits/128bits Service Data */
+ if (len > MIN_ADV_LENGTH && data_mask & BTM_BLE_AD_BIT_SERVICE_DATA &&
+ p_data && p_data->p_service_data->len != 0 && p_data->p_service_data->p_val)
+ {
+ if (len > (p_data->p_service_data->service_uuid.len + MIN_ADV_LENGTH))
+ {
+ if (p_data->p_service_data->len > (len - MIN_ADV_LENGTH))
+ cp_len = len - MIN_ADV_LENGTH- p_data->p_service_data->service_uuid.len;
+ else
+ cp_len = p_data->p_service_data->len;
+
+ *p++ = cp_len + 1 + p_data->p_service_data->service_uuid.len;
+ if (p_data->p_service_data->service_uuid.len == LEN_UUID_16)
+ {
+ *p++ = BTM_BLE_AD_TYPE_SERVICE_DATA;
+ UINT16_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid16);
+ }
+ else if (p_data->p_service_data->service_uuid.len == LEN_UUID_32)
+ {
+ *p++ = BTM_BLE_AD_TYPE_32SERVICE_DATA;
+ UINT32_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid32);
+ }
+ else
+ {
+ *p++ = BTM_BLE_AD_TYPE_128SERVICE_DATA;
+ ARRAY_TO_STREAM(p, p_data->p_service_data->service_uuid.uu.uuid128,
+ LEN_UUID_128);
+ }
+
+ ARRAY_TO_STREAM(p, p_data->p_service_data->p_val, cp_len);
+
+ len -= (cp_len + MIN_ADV_LENGTH + p_data->p_service_data->service_uuid.len);
+ data_mask &= ~BTM_BLE_AD_BIT_SERVICE_DATA;
+ }
+ else
+ {
+ BTM_TRACE_WARNING0("service data does not fit");
+ }
+ }
+
if (len >= 6 && data_mask & BTM_BLE_AD_BIT_INT_RANGE &&
p_data)
{
{
p_elem = p_data->p_proprietary->p_elem + i;
- if (len >= (2 + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2) + value length */
+ if (len >= (MIN_ADV_LENGTH + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2)
+ + value length */
{
*p ++ = p_elem->len + 1; /* Uuid len + value length */
*p ++ = p_elem->adv_type;
ARRAY_TO_STREAM(p, p_elem->p_val, p_elem->len);
- len -= (2 + p_elem->len);
+ len -= (MIN_ADV_LENGTH + p_elem->len);
}
else
{
**
** Description This function is called to set BLE discoverable mode.
**
-** Parameters: mode: discoverability mode.
+** Parameters: combined_mode: discoverability mode.
**
-** Returns void
+** Returns BTM_SUCCESS is status set successfully; otherwise failure.
**
*******************************************************************************/
tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode)
**
** Description This function is called to set BLE connectability mode.
**
-** Parameters: mode: connectability mode.
+** Parameters: combined_mode: connectability mode.
**
-** Returns void
+** Returns BTM_SUCCESS is status set successfully; otherwise failure.
**
*******************************************************************************/
tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode)
}
}
- if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE)
+ if (btm_multi_adv_cb.adv_inst_max == 0 &&
+ 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 );
}
case BTU_TTYPE_BLE_GAP_LIM_DISC:
/* lim_timeout expiried, limited discovery should exit now */
btm_cb.btm_inq_vars.discoverable_mode &= ~BTM_BLE_LIMITED_DISCOVERABLE;
-
btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, btm_cb.btm_inq_vars.discoverable_mode);
break;
case BTU_TTYPE_BLE_RANDOM_ADDR:
if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM)
{
+ if ((void *)(p_tle->param) == NULL)
/* refresh the random addr */
- btm_gen_resolvable_private_addr();
+ btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low);
+ else
+ {
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST*)&p_tle->param);
+#endif
+ }
}
break;
p_cb->scan_int = p_cb->scan_win = BTM_BLE_CONN_PARAM_UNDEF;
p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+ btm_ble_multi_adv_init();
+#endif
+
+ btm_ble_vendor_capability_init();
}
/*******************************************************************************
#define BTM_BLE_VALID_PRAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == BTM_BLE_CONN_PARAM_UNDEF))
+#define BTM_BLE_PRIVATE_ADDR_INT 900 /* 15 minutes minimum for
+ random address refreshing */
+
typedef struct
{
extern void btm_read_ble_local_supported_states_complete(UINT8 *p, UINT16 evt_len);
extern tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
extern void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st);
+extern UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst,
+ tBTM_BLE_ADV_DATA *p_data);
extern tBTM_STATUS btm_ble_start_adv(void);
extern tBTM_STATUS btm_ble_stop_adv(void);
extern tBTM_STATUS btm_ble_start_scan (UINT8 filter_enb);
extern void btm_ble_enqueue_direct_conn_req(void *p_param);
/* BLE address management */
-extern void btm_gen_resolvable_private_addr (void);
+extern void btm_gen_resolvable_private_addr (void *p_cmd_cplt_cback);
extern void btm_gen_non_resolvable_private_addr (tBTM_BLE_ADDR_CBACK *p_cback, void *p);
extern void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK * p_cback, void *p);
extern void btm_ble_update_reconnect_address(BD_ADDR bd_addr);
+extern void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p);
+
+extern void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst);
+extern void btm_ble_multi_adv_init(void);
+extern void btm_ble_multi_adv_reenable(UINT8 inst_id);
+
extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request);
extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state);
extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state);
BT_API extern void btm_ble_set_test_mac_value (BOOLEAN enable, UINT8 *p_test_mac_val);
BT_API extern void btm_ble_set_test_local_sign_cntr_value(BOOLEAN enable, UINT32 test_local_sign_cntr);
BT_API extern void btm_set_random_address(BD_ADDR random_bda);
+BT_API extern void btm_ble_set_keep_rfu_in_auth_req(BOOLEAN keep_rfu);
#endif
--- /dev/null
+/******************************************************************************
+ *
+ * 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 "bt_target.h"
+
+#if (BLE_INCLUDED == TRUE)
+#if BLE_MULTI_ADV_INCLUDED == TRUE
+#include "bt_types.h"
+#include "hcimsgs.h"
+#include "btu.h"
+#include "btm_int.h"
+#include "bt_utils.h"
+#include "hcidefs.h"
+#include "btm_ble_api.h"
+
+/* length of each multi adv sub command */
+#define BTM_BLE_MULTI_ADV_ENB_LEN 3
+#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 33
+#define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3)
+#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8
+
+#ifndef BTM_BLE_MULTI_ADV_INST_MAX
+#define BTM_BLE_MULTI_ADV_INST_MAX 5
+#endif
+
+tBTM_BLE_MULTI_ADV_CB btm_multi_adv_cb;
+
+static void btm_ble_multi_adv_gen_rpa_cmpl_1(tBTM_RAND_ENC *p);
+static void btm_ble_multi_adv_gen_rpa_cmpl_2(tBTM_RAND_ENC *p);
+static void btm_ble_multi_adv_gen_rpa_cmpl_3(tBTM_RAND_ENC *p);
+static void btm_ble_multi_adv_gen_rpa_cmpl_4(tBTM_RAND_ENC *p);
+
+typedef void (*tBTM_MULTI_ADV_RPA_CMPL)(tBTM_RAND_ENC *p);
+const tBTM_MULTI_ADV_RPA_CMPL btm_ble_multi_adv_rpa_cmpl [] =
+{
+ btm_ble_multi_adv_gen_rpa_cmpl_1,
+ btm_ble_multi_adv_gen_rpa_cmpl_2,
+ btm_ble_multi_adv_gen_rpa_cmpl_3,
+ btm_ble_multi_adv_gen_rpa_cmpl_4
+};
+
+#define BTM_BLE_MULTI_ADV_CB_EVT_MASK 0xF0
+#define BTM_BLE_MULTI_ADV_SUBCODE_MASK 0x0F
+
+/*******************************************************************************
+**
+** 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->inst_id[p_op_q->next_idx] = inst_id;
+
+ p_op_q->sub_code[p_op_q->next_idx] = (opcode |(cb_evt << 4));
+
+ p_op_q->next_idx = (p_op_q->next_idx + 1) % BTM_BLE_MULTI_ADV_MAX;
+}
+
+/*******************************************************************************
+**
+** 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->inst_id[p_op_q->pending_idx] & 0x7F;
+ *p_cb_evt = (p_op_q->sub_code[p_op_q->pending_idx] >> 4);
+ *p_opcode = (p_op_q->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_BLE_MULTI_ADV_MAX;
+}
+
+/*******************************************************************************
+**
+** 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_ERROR0("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_DEBUG3("op_code = %02x inst_id = %d cb_evt = %02x", opcode, inst_id, cb_evt);
+
+ if (opcode != subcode || inst_id == 0)
+ {
+ BTM_TRACE_ERROR2("get unexpected VSC cmpl, expect: %d get: %d",subcode,opcode);
+ return;
+ }
+
+ p_inst = &btm_multi_adv_cb.adv_inst[inst_id - 1];
+
+ switch (subcode)
+ {
+ case BTM_BLE_MULTI_ADV_ENB:
+ BTM_TRACE_DEBUG1("BTM_BLE_MULTI_ADV_ENB status = %d", status);
+ if (status != HCI_SUCCESS)
+ {
+ btm_multi_adv_cb.adv_inst[inst_id-1].inst_id = 0;
+ }
+ break;
+
+ case BTM_BLE_MULTI_ADV_SET_PARAM:
+ {
+ BTM_TRACE_DEBUG1("BTM_BLE_MULTI_ADV_SET_PARAM status = %d", status);
+ break;
+ }
+
+ case BTM_BLE_MULTI_ADV_WRITE_ADV_DATA:
+ {
+ BTM_TRACE_DEBUG1("BTM_BLE_MULTI_ADV_WRITE_ADV_DATA status = %d", status);
+ break;
+ }
+
+ case BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA:
+ {
+ BTM_TRACE_DEBUG1("BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA status = %d", status);
+ break;
+ }
+
+ case BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR:
+ {
+ BTM_TRACE_DEBUG1("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_EVENT2 (" 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_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 (btm_cb.ble_ctr_cb.privacy)
+ {
+ UINT8_TO_STREAM (pp, BLE_ADDR_RANDOM);
+ BDADDR_TO_STREAM (pp, p_inst->rpa);
+ }
+ else
+ {
+ UINT8_TO_STREAM (pp, BLE_ADDR_PUBLIC);
+ BDADDR_TO_STREAM (pp, btm_cb.devcb.local_addr);
+ }
+
+ BTM_TRACE_EVENT3 (" 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, p_params->tx_power);
+
+ BTM_TRACE_EVENT4("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 (btm_cb.ble_ctr_cb.privacy)
+ {
+ /* start timer */
+ p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
+ btu_start_timer (&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_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_EVENT0 (" btm_ble_multi_adv_set_random_addr");
+
+ 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(&p_inst->raddr_timer_ent);
+ p_inst->raddr_timer_ent.param = (TIMER_PARAM_TYPE) p_inst;
+ btu_start_timer (&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, tBTM_BLE_MULTI_ADV_INST *p_inst )
+{
+#if (SMP_INCLUDED == TRUE)
+ tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
+ tSMP_ENC output;
+
+ BTM_TRACE_EVENT1 ("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_DEBUG0("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 != 0)
+ {
+ /* set it to controller */
+ btm_ble_multi_adv_write_rpa(p_inst, p_inst->rpa);
+ }
+ }
+ }
+#endif
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_multi_adv_gen_rpa_cmpl1
+**
+** Description RPA generation completion callback for each adv instance. Will
+** continue write the new RPA into controller.
+**
+** Returns none.
+**
+*******************************************************************************/
+static void btm_ble_multi_adv_gen_rpa_cmpl_1(tBTM_RAND_ENC *p)
+{
+ btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[0]);
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_multi_adv_gen_rpa_cmpl2
+**
+** Description RPA generation completion callback for each adv instance. Will
+** continue write the new RPA into controller.
+**
+** Returns none.
+**
+*******************************************************************************/
+static void btm_ble_multi_adv_gen_rpa_cmpl_2(tBTM_RAND_ENC *p)
+{
+ btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[1]);
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_multi_adv_gen_rpa_cmpl3
+**
+** Description RPA generation completion callback for each adv instance. Will
+** continue write the new RPA into controller.
+**
+** Returns none.
+**
+*******************************************************************************/
+static void btm_ble_multi_adv_gen_rpa_cmpl_3(tBTM_RAND_ENC *p)
+{
+ btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[2]);
+}
+
+/*******************************************************************************
+**
+** Function btm_ble_multi_adv_gen_rpa_cmpl4
+**
+** Description RPA generation completion callback for each adv instance. Will
+** continue write the new RPA into controller.
+**
+** Returns none.
+**
+*******************************************************************************/
+static void btm_ble_multi_adv_gen_rpa_cmpl_4(tBTM_RAND_ENC *p)
+{
+ btm_ble_multi_adv_gen_rpa_cmpl(p, &btm_multi_adv_cb.adv_inst[3]);
+}
+/*******************************************************************************
+**
+** 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)
+{
+ btm_gen_resolvable_private_addr((void *)p_inst->p_rpa_cback);
+}
+
+/*******************************************************************************
+**
+** 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.adv_inst[inst_id - 1];
+
+ if (p_inst->inst_id != 0)
+ {
+ 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->inst_id = 0;
+ }
+ }
+}
+
+/*******************************************************************************
+**
+** 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.adv_inst[0];
+
+ BTM_TRACE_EVENT0("BTM_BleEnableAdvInstance called");
+
+ if (btm_multi_adv_cb.adv_inst_max == 0)
+ {
+ BTM_TRACE_ERROR0("Controller does not support Multi ADV");
+ return BTM_ERR_PROCESSING;
+ }
+
+ for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++, p_inst++)
+ {
+ if (p_inst->inst_id == 0)
+ {
+ p_inst->inst_id = i + 1;
+
+ /* configure adv parameter */
+ if (p_params)
+ btm_ble_multi_adv_set_params(p_inst, p_params, 0);
+
+ /* enable adv */
+ BTM_TRACE_EVENT1("btm_ble_enable_multi_adv being called with inst_id:%d",
+ p_inst->inst_id);
+ 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;
+ }
+ else
+ {
+ p_inst->inst_id = 0;
+ BTM_TRACE_ERROR0("BTM_BleEnableAdvInstance failed, no resources");
+ }
+ 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.adv_inst[inst_id - 1];
+
+ BTM_TRACE_EVENT1("BTM_BleUpdateAdvInstParam called with inst_id:%d", inst_id);
+
+ if (btm_multi_adv_cb.adv_inst_max == 0)
+ {
+ BTM_TRACE_ERROR0("Controller does not support Multi ADV");
+ return BTM_ERR_PROCESSING;
+ }
+
+ if (inst_id <= BTM_BLE_MULTI_ADV_MAX &&
+ inst_id != BTM_BLE_MULTI_ADV_DEFAULT_STD &&
+ p_params != NULL)
+ {
+ if (p_inst->inst_id == 0)
+ {
+ BTM_TRACE_DEBUG1("adv instance %d is not active", inst_id);
+ return BTM_WRONG_MODE;
+ }
+ else
+ btm_ble_enable_multi_adv(FALSE, inst_id, 0);
+
+ 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 scacn 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);
+
+ if (btm_multi_adv_cb.adv_inst_max == 0)
+ {
+ BTM_TRACE_ERROR0("Controller does not support Multi ADV");
+ return BTM_ERR_PROCESSING;
+ }
+
+ BTM_TRACE_EVENT1("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;
+
+ BTM_TRACE_EVENT1("BTM_BleDisableAdvInstance with inst_id:%d", inst_id);
+
+ if (btm_multi_adv_cb.adv_inst_max == 0)
+ {
+ BTM_TRACE_ERROR0("Controller does not support Multi ADV");
+ return BTM_ERR_PROCESSING;
+ }
+
+ if (inst_id <= BTM_BLE_MULTI_ADV_MAX && 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)
+ {
+ btu_stop_timer(&btm_multi_adv_cb.adv_inst[inst_id-1].raddr_timer_ent);
+
+ btm_multi_adv_cb.adv_inst[inst_id-1].inst_id = 0;
+ }
+ }
+ 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, reason, conn_handle;
+
+ /* Check if this is a BLE RSSI vendor specific event */
+ STREAM_TO_UINT8(sub_event, p);
+ len--;
+
+ BTM_TRACE_EVENT1("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);
+ STREAM_TO_UINT8(reason, p);
+ STREAM_TO_UINT16(conn_handle, p);
+
+ if (adv_inst <= BTM_BLE_MULTI_ADV_MAX && adv_inst != BTM_BLE_MULTI_ADV_DEFAULT_STD)
+ {
+ BTM_TRACE_EVENT0("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
+**
+** Returns status
+**
+*******************************************************************************/
+void btm_ble_multi_adv_init(void)
+{
+ UINT8 i;
+
+ memset(&btm_multi_adv_cb, 0, sizeof(tBTM_BLE_MULTI_ADV_CB));
+
+ for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++)
+ btm_multi_adv_cb.adv_inst[i].p_rpa_cback = btm_ble_multi_adv_rpa_cmpl[i];
+
+ BTM_RegisterForVSEvents(btm_ble_multi_adv_vse_cback, TRUE);
+}
+#endif
+#endif
+
#define BTM_BLE_API_H
#include "btm_api.h"
+#include "gki.h"
#define CHNL_MAP_LEN 5
typedef UINT8 tBTM_BLE_CHNL_MAP[CHNL_MAP_LEN];
#define BTM_BLE_POLICY_ALLOW_CONN 0x02 /* relevant to advertiser */
#define BTM_BLE_POLICY_WHITE_ALL 0x03 /* relevant to both */
-typedef struct
-{
- UINT8 adv_int_min;
- UINT8 adv_int_max;
- tBTM_BLE_CHNL_MAP chnl_map;
-
-}tBTM_BLE_ADV_PARAMS;
-
/* ADV data flag bit definition used for BTM_BLE_AD_TYPE_FLAG */
#define BTM_BLE_LIMIT_DISC_FLAG (0x01 << 0)
#define BTM_BLE_GEN_DISC_FLAG (0x01 << 1)
/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support */
#define BTM_BLE_DMT_CONTROLLER_SPT (0x01 << 3)
#define BTM_BLE_DMT_HOST_SPT (0x01 << 4)
-
#define BTM_BLE_NON_LIMIT_DISC_FLAG (0x00 ) /* lowest bit unset */
#define BTM_BLE_ADV_FLAG_MASK (BTM_BLE_LIMIT_DISC_FLAG | BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG)
#define BTM_BLE_LIMIT_DISC_MASK (BTM_BLE_LIMIT_DISC_FLAG )
#define BTM_BLE_AD_BIT_RANDOM_ADDR (0x00000001 << 13)
#define BTM_BLE_AD_BIT_SERVICE_32 (0x00000001 << 4)
#define BTM_BLE_AD_BIT_SERVICE_32SOL (0x00000001 << 14)
-
#define BTM_BLE_AD_BIT_PROPRIETARY (0x00000001 << 15)
+#define BTM_BLE_AD_BIT_SERVICE_128 (0x00000001 << 16) /*128-bit Service UUIDs*/
typedef UINT32 tBTM_BLE_AD_MASK;
#define BTM_BLE_AD_TYPE_MANU HCI_EIR_MANUFACTURER_SPECIFIC_TYPE /* 0xff */
typedef UINT8 tBTM_BLE_AD_TYPE;
+/* adv tx power level */
+#define BTM_BLE_ADV_TX_POWER_MIN 0 /* minimum tx power */
+#define BTM_BLE_ADV_TX_POWER_LOW 1 /* low tx power */
+#define BTM_BLE_ADV_TX_POWER_MID 2 /* middle tx power */
+#define BTM_BLE_ADV_TX_POWER_UPPER 3 /* upper tx power */
+#define BTM_BLE_ADV_TX_POWER_MAX 4 /* maximum tx power */
+typedef UINT8 tBTM_BLE_ADV_TX_POWER;
+
/* slave preferred connection interval range */
typedef struct
{
UINT16 *p_uuid;
}tBTM_BLE_SERVICE;
-/* Service tag supported in the device */
+/* 32 bits Service supported in the device */
typedef struct
{
UINT8 num_service;
UINT32 *p_uuid;
}tBTM_BLE_32SERVICE;
+/* 128 bits Service supported in the device */
+typedef struct
+{
+ BOOLEAN list_cmpl;
+ UINT8 uuid128[MAX_UUID_SIZE];
+}tBTM_BLE_128SERVICE;
typedef struct
{
UINT8 *p_val;
}tBTM_BLE_SERVICE_DATA;
-
typedef struct
{
UINT8 adv_type;
typedef struct
{
- tBTM_BLE_SERVICE_DATA *p_service_data;
- tBTM_BLE_MANU manu; /* manufactuer data */
tBTM_BLE_INT_RANGE int_range; /* slave prefered conn interval range */
- tBTM_BLE_SERVICE services; /* services */
- tBTM_BLE_32SERVICE service_32b; /* 32 bits Service UUID */
- tBTM_BLE_32SERVICE sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
+ tBTM_BLE_MANU *p_manu; /* manufactuer data */
+ tBTM_BLE_SERVICE *p_services; /* services */
+ tBTM_BLE_128SERVICE *p_services_128b; /* 128 bits service */
+ tBTM_BLE_32SERVICE *p_service_32b; /* 32 bits Service UUID */
+ tBTM_BLE_SERVICE *p_sol_services; /* 16 bits services Solicitation UUIDs */
+ tBTM_BLE_32SERVICE *p_sol_service_32b; /* List of 32 bit Service Solicitation UUIDs */
+ tBTM_BLE_128SERVICE *p_sol_service_128b; /* List of 128 bit Service Solicitation UUIDs */
+ tBTM_BLE_PROPRIETARY *p_proprietary;
+ tBTM_BLE_SERVICE_DATA *p_service_data; /* service data */
UINT16 appearance;
UINT8 flag;
- tBTM_BLE_PROPRIETARY *p_proprietary;
+ UINT8 tx_power;
}tBTM_BLE_ADV_DATA;
+#ifndef BTM_BLE_MULTI_ADV_MAX
+#define BTM_BLE_MULTI_ADV_MAX 4
+#endif
+
+#define BTM_BLE_MULTI_ADV_INVALID 0
+
+#define BTM_BLE_MULTI_ADV_ENB_EVT 1
+#define BTM_BLE_MULTI_ADV_DISABLE_EVT 2
+#define BTM_BLE_MULTI_ADV_PARAM_EVT 3
+#define BTM_BLE_MULTI_ADV_DATA_EVT 4
+typedef UINT8 tBTM_BLE_MULTI_ADV_EVT;
+
+#define BTM_BLE_MULTI_ADV_DEFAULT_STD 0
+
+typedef struct
+{
+ UINT16 adv_int_min;
+ UINT16 adv_int_max;
+ UINT8 adv_type;
+ tBTM_BLE_ADV_CHNL_MAP channel_map;
+ tBTM_BLE_AFP adv_filter_policy;
+ tBTM_BLE_ADV_TX_POWER tx_power;
+}tBTM_BLE_ADV_PARAMS;
+
+typedef struct
+{
+ UINT8 sub_code[BTM_BLE_MULTI_ADV_MAX];
+ UINT8 inst_id[BTM_BLE_MULTI_ADV_MAX];
+ UINT8 pending_idx;
+ UINT8 next_idx;
+}tBTM_BLE_MULTI_ADV_OPQ;
+
+typedef void (tBTM_BLE_MULTI_ADV_CBACK)(tBTM_BLE_MULTI_ADV_EVT evt, UINT8 inst_id,
+ void *p_ref, tBTM_STATUS status);
+
+typedef struct
+{
+ UINT8 inst_id;
+ UINT8 adv_evt;
+ BD_ADDR rpa;
+ TIMER_LIST_ENT raddr_timer_ent;
+ void *p_rpa_cback;
+ tBTM_BLE_MULTI_ADV_CBACK *p_cback;
+ void *p_ref;
+}tBTM_BLE_MULTI_ADV_INST;
+
+typedef struct
+{
+ tBTM_BLE_MULTI_ADV_INST adv_inst[BTM_BLE_MULTI_ADV_MAX];
+ tBTM_BLE_MULTI_ADV_OPQ op_q;
+ UINT8 adv_inst_max; /* max adv instance supported in controller */
+}tBTM_BLE_MULTI_ADV_CB;
+
+
/* These are the fields returned in each device adv packet. It
** is returned in the results callback if registered.
*/
*******************************************************************************/
BTM_API extern tBTM_STATUS BTM_BleStackEnable (BOOLEAN enable);
+/*******************************************************************************/
+/* Multi ADV API */
+/*******************************************************************************
+**
+** 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
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params,
+ tBTM_BLE_MULTI_ADV_CBACK *p_cback,
+ void *p_ref);
+
+/*******************************************************************************
+**
+** Function BTM_BleUpdateAdvInstParam
+**
+** Description This function update a Multi-ADV instance with the specififed
+** adv parameters.
+**
+** Parameters inst_id: adv instance ID
+** p_params: pointer to the adv parameter structure.
+**
+** Returns status
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleUpdateAdvInstParam (UINT8 inst_id, tBTM_BLE_ADV_PARAMS *p_params);
+
+/*******************************************************************************
+**
+** 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 scacn response, if no set as adv data.
+** data_mask: adv data mask.
+** p_data: pointer to the adv data structure.
+**
+** Returns status
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
+ tBTM_BLE_AD_MASK data_mask,
+ tBTM_BLE_ADV_DATA *p_data);
+
+/*******************************************************************************
+**
+** Function BTM_BleDisableAdvInstance
+**
+** Description This function disable a Multi-ADV instance.
+**
+** Parameters inst_id: adv instance ID
+**
+** Returns status
+**
+*******************************************************************************/
+BTM_API extern tBTM_STATUS BTM_BleDisableAdvInstance (UINT8 inst_id);
+
#ifdef __cplusplus
}
#endif
/******************************************************************************
*
- * Copyright (C) 1999-2012 Broadcom Corporation
+ * Copyright (C) 1999-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.
#define HCI_BLE_TRANSMITTER_TEST (0x001E | HCI_GRP_BLE_CMDS)
#define HCI_BLE_TEST_END (0x001F | HCI_GRP_BLE_CMDS)
+/* LE Get Vendor Capabilities Command OCF */
+#define HCI_BLE_VENDOR_CAP_OCF (0x0153 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* Multi adv OCF */
+#define HCI_BLE_MULTI_ADV_OCF (0x0154 | HCI_GRP_VENDOR_SPECIFIC)
+
+/* subcode for multi adv feature */
+#define BTM_BLE_MULTI_ADV_SET_PARAM 0x01
+#define BTM_BLE_MULTI_ADV_WRITE_ADV_DATA 0x02
+#define BTM_BLE_MULTI_ADV_WRITE_SCAN_RSP_DATA 0x03
+#define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR 0x04
+#define BTM_BLE_MULTI_ADV_ENB 0x05
+
+/* multi adv VSE subcode */
+#define HCI_VSE_SUBCODE_BLE_MULTI_ADV_ST_CHG 0x55 /* multi adv instance state change */
+
/* LE supported states definition */
#define HCI_LE_ADV_STATE 0x00000001
#define HCI_LE_SCAN_STATE 0x00000002