bdaddr_t bdaddr; /* controller Bluetooth address */
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
bdaddr_t le_static_addr;
+ bdaddr_t rpa;
#endif
uint8_t bdaddr_type; /* address type */
uint32_t dev_class; /* controller class of device */
return NULL;
}
-static void create_advertiser(struct btd_adapter *adapter,
+static struct adv_info *create_advertiser(struct btd_adapter *adapter,
int slot_id)
{
struct adv_info *adv;
if (!adapter)
- return;
+ return NULL;
- if (find_advertiser(adapter, slot_id) != NULL) {
- error("Aleady existed [%d]", slot_id);
- return;
+ adv = find_advertiser(adapter, slot_id);
+ if (adv != NULL) {
+ DBG("Aleady existed. solt_id [%d]", slot_id);
+ return adv;
}
DBG("Create adv slot id : %d", slot_id);
adv = g_new0(struct adv_info, 1);
if (adv == NULL)
- return;
+ return NULL;
adv->slot_id = slot_id;
adapter->adv_list = g_slist_append(adapter->adv_list, adv);
- return;
+ return adv;
}
g_slist_free(adapter->adv_list);
adapter->adv_list = NULL;
}
+
+static void update_advertiser_address(gpointer data, gpointer user_data)
+{
+ struct adv_info *adv = data;
+ struct btd_adapter *adapter = user_data;
+
+ if (adv->slot_id > 0 && adv->status == 1)
+ adapter_le_set_random_address(adapter, &adapter->rpa, adv->slot_id);
+}
+
+static void rpa_changed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_rpa_changed *ev = param;
+ struct btd_adapter *adapter = user_data;
+ char addr[18];
+
+ if (length < sizeof(*ev)) {
+ error("Too small rpa changed event");
+ return;
+ }
+
+ ba2str(&ev->bdaddr, addr);
+ DBG("RPA changed %s", addr);
+ bacpy(&adapter->rpa, &ev->bdaddr);
+
+ if (!adapter->adv_list)
+ return;
+
+ g_slist_foreach(adapter->adv_list, update_advertiser_address, adapter);
+}
+
#endif
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
adapter_le_adv_inst_info_t *p_inst;
adapter_le_adv_param_t *p_params;
- p_inst = malloc(sizeof(adapter_le_adv_inst_info_t));
- p_params = malloc(sizeof(adapter_le_adv_param_t));
- memset(p_inst, 0, sizeof(adapter_le_adv_inst_info_t));
- memset(p_params, 0, sizeof(adapter_le_adv_param_t));
+ p_inst = g_malloc0(sizeof(adapter_le_adv_inst_info_t));
+ p_params = g_malloc0(sizeof(adapter_le_adv_param_t));
p_inst->inst_id = slot_id;
p_params->adv_int_min = interval_min;
p_params->adv_int_max = interval_max;
p_params->channel_map = 0x07; /* fixed channel :: will be used all */
p_params->adv_filter_policy = filter_policy;
p_params->tx_power = BLE_ADV_TX_POWER_MID; /* TODO:need to optimize */
- if (adapter->le_static_addr.b[5] != 0) {
+
+ if (adapter->current_settings & MGMT_SETTING_PRIVACY) {
+ p_inst->bdaddr_type = 0x01;
+ bacpy(&p_inst->bdaddr, &adapter->rpa);
+ } else if (adapter->le_static_addr.b[5] != 0) {
p_inst->bdaddr_type = 0x01;
bacpy(&p_inst->bdaddr, &adapter->le_static_addr);
} else {
ret = adapter_le_set_multi_adv_params(p_inst, p_params);
- free(p_inst);
- free(p_params);
+ g_free(p_inst);
+ g_free(p_params);
if (ret)
return dbus_message_new_method_return(msg);
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
const bdaddr_t *btd_adapter_get_le_address(struct btd_adapter *adapter)
{
- if (adapter->le_static_addr.b[5] != 0)
+ if (adapter->current_settings & MGMT_SETTING_PRIVACY)
+ return &adapter->rpa;
+ else if (adapter->le_static_addr.b[5] != 0)
return &adapter->le_static_addr;
else
return &adapter->bdaddr;
uint8_t btd_adapter_get_le_address_type(struct btd_adapter * adapter)
{
- if (adapter->le_static_addr.b[5] != 0)
- return BDADDR_LE_RANDOM;
- else
- return BDADDR_LE_PUBLIC;
+ if (adapter->current_settings & MGMT_SETTING_PRIVACY ||
+ adapter->le_static_addr.b[5] != 0)
+ return BDADDR_LE_RANDOM;
+ else
+ return BDADDR_LE_PUBLIC;
}
#endif
adapter->dev_id,
le_conn_update_completed_callback,
adapter, NULL);
+
+ mgmt_register(adapter->mgmt, MGMT_EV_RPA_CHANGED,
+ adapter->dev_id,
+ rpa_changed_callback,
+ adapter, NULL);
#endif
set_dev_class(adapter);
return TRUE;
}
+gboolean adapter_le_set_random_address (struct btd_adapter *adapter,
+ const bdaddr_t *addr, uint8_t inst_id)
+{
+ int ret;
+ adapter_le_vsc_cp_set_random_address cp;
+ apater_le_vsc_rp_set_random_address rp;
+
+ DBG("");
+
+ memset(&cp, 0, sizeof(cp));
+ cp.subcode = SUB_CMD_LE_MULTI_ADV_SET_RANDOM_ADDR;
+ cp.inst_id = inst_id;
+ bacpy(&cp.bdaddr, addr);
+
+ ret = send_vsc_command(OCF_BCM_LE_MULTI_ADV, (uint8_t *) &cp, sizeof(cp),
+ (uint8_t *) &rp, sizeof(rp));
+
+ if (ret < 0)
+ return FALSE;
+
+ if (HCI_SUCCESS != rp.status) {
+ DBG("Fail to send VSC :: sub[%x] - status [0x%02x]", rp.subcode, rp.status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
gboolean adapter_le_enable_multi_adv (struct btd_adapter *adapter,
gboolean enable, uint8_t inst_id)
{
uint8_t bdaddr_type;
const bdaddr_t *bdaddr;
- DBG("");
+ DBG("%s slot_id %d", enable ? "Enable" : "Disable", inst_id);
if (enable) {
bdaddr_type = btd_adapter_get_le_address_type(adapter);
if (bdaddr_type == BDADDR_LE_RANDOM) {
/**
*
+* CP for SUB_CMD_LE_MULTI_ADV_SET_RANDOM_ADDR
+*
+* (6 octet) b : Random address
+* (1 octet) inst_id : Specifies the applicability of the above parameters
+* to an instance. Instance 0 has special meaning this
+* refers to std HCI instance.
+*/
+typedef struct {
+ uint8_t subcode;
+ bdaddr_t bdaddr;
+ uint8_t inst_id;
+} __attribute__ ((packed)) adapter_le_vsc_cp_set_random_address;
+
+/**
+*
+* RP
+*
+* (1 octet) status : Command complete status
+* (1 octet) subcode : subcode of SUB_CMD_LE_MULTI_ADV_SET_RANDOM_ADDR
+*/
+typedef struct {
+ uint8_t status;
+ uint8_t subcode;
+} __attribute__ ((packed)) apater_le_vsc_rp_set_random_address;
+
+/**
+*
* CP for SUB_CMD_LE_MULTI_ADV_ENB
*
* (1 octet) subcode : SUB_CMD_LE_MULTI_ADV_ENB
gboolean adapter_le_set_multi_adv_data(uint8_t inst_id, gboolean is_scan_rsp,
uint8_t data_len, uint8_t *p_data);
+gboolean adapter_le_set_random_address (struct btd_adapter *adapter,
+ const bdaddr_t *addr, uint8_t inst_id);
+
gboolean adapter_le_enable_multi_adv (struct btd_adapter *adapter,
gboolean enable, uint8_t inst_id);