@@ -80,6 +80,10 @@ struct btd_adv_client {
uint32_t flags;
struct bt_ad *data;
struct bt_ad *scan;
+ uint8_t *adv_data;
+ uint8_t *scan_rsp;
+ size_t adv_data_len;
+ size_t scan_rsp_len;
uint8_t instance;
uint32_t min_interval;
uint32_t max_interval;
@@ -141,6 +145,16 @@ static void client_free(void *data)
bt_ad_unref(client->data);
bt_ad_unref(client->scan);
+ if (client->adv_data) {
+ free(client->adv_data);
+ client->adv_data = NULL;
+ }
+
+ if (client->scan_rsp) {
+ free(client->scan_rsp);
+ client->scan_rsp = NULL;
+ }
+
g_dbus_proxy_unref(client->proxy);
if (client->owner)
@@ -915,6 +929,22 @@ static int refresh_extended_adv(struct btd_adv_client *client,
flags |= MGMT_ADV_PARAM_TX_POWER;
}
+ client->adv_data = generate_adv_data(client, &flags,
+ &client->adv_data_len);
+ if (!client->adv_data ||
+ (client->adv_data_len > calc_max_adv_len(client, flags))) {
+ error("Advertising data too long or couldn't be generated.");
+ return -EINVAL;
+ }
+
+ client->scan_rsp = generate_scan_rsp(client, &flags,
+ &client->scan_rsp_len);
+ if (!client->scan_rsp && client->scan_rsp_len) {
+ error("Scan data couldn't be generated.");
+ free(client->adv_data);
+ return -EINVAL;
+ }
+
cp.flags = htobl(flags);
mgmt_ret = mgmt_send(client->manager->mgmt, MGMT_OP_ADD_EXT_ADV_PARAMS,
@@ -1222,11 +1252,6 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
const struct mgmt_rp_add_ext_adv_params *rp = param;
struct mgmt_cp_add_ext_adv_data *cp = NULL;
uint8_t param_len;
- uint8_t *adv_data = NULL;
- size_t adv_data_len;
- uint8_t *scan_rsp = NULL;
- size_t scan_rsp_len = -1;
- uint32_t flags = 0;
unsigned int mgmt_ret;
dbus_int16_t tx_power;
@@ -1248,23 +1273,8 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
client->instance = rp->instance;
- flags = get_adv_flags(client);
-
- adv_data = generate_adv_data(client, &flags, &adv_data_len);
- if (!adv_data || (adv_data_len > rp->max_adv_data_len)) {
- error("Advertising data too long or couldn't be generated.");
- goto fail;
- }
-
- scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
- if ((!scan_rsp && scan_rsp_len) ||
- scan_rsp_len > rp->max_scan_rsp_len) {
- error("Scan data couldn't be generated.");
- goto fail;
- }
-
- param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len +
- scan_rsp_len;
+ param_len = sizeof(struct mgmt_cp_add_advertising) +
+ client->adv_data_len + client->scan_rsp_len;
cp = malloc0(param_len);
if (!cp) {
@@ -1273,15 +1283,11 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
}
cp->instance = client->instance;
- cp->adv_data_len = adv_data_len;
- cp->scan_rsp_len = scan_rsp_len;
- memcpy(cp->data, adv_data, adv_data_len);
- memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);
-
- free(adv_data);
- free(scan_rsp);
- adv_data = NULL;
- scan_rsp = NULL;
+ cp->adv_data_len = client->adv_data_len;
+ cp->scan_rsp_len = client->scan_rsp_len;
+ memcpy(cp->data, client->adv_data, client->adv_data_len);
+ memcpy(cp->data + client->adv_data_len, client->scan_rsp,
+ client->scan_rsp_len);
/* Submit request to update instance data */
mgmt_ret = mgmt_send(client->manager->mgmt, MGMT_OP_ADD_EXT_ADV_DATA,
@@ -1305,12 +1311,6 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
return;
fail:
- if (adv_data)
- free(adv_data);
-
- if (scan_rsp)
- free(scan_rsp);
-
if (cp)
free(cp);
@@ -1454,6 +1454,11 @@ static struct btd_adv_client *client_create(struct btd_adv_manager *manager,
if (!client->scan)
goto fail;
+ client->adv_data = NULL;
+ client->scan_rsp = NULL;
+ client->adv_data_len = 0;
+ client->scan_rsp_len = 0;
+
client->manager = manager;
client->appearance = UINT16_MAX;
client->tx_power = ADV_TX_POWER_NO_PREFERENCE;