@@ -102,7 +102,8 @@ struct le_ext_adv {
uint8_t adv_data_len;
uint8_t scan_data[252];
uint8_t scan_data_len;
- unsigned int id;
+ unsigned int broadcast_id;
+ unsigned int timeout_id;
};
struct le_per_adv {
@@ -575,8 +576,10 @@ static void le_ext_adv_free(void *data)
/* Remove to queue */
queue_remove(ext_adv->dev->le_ext_adv, ext_adv);
- if (ext_adv->id)
- timeout_remove(ext_adv->id);
+ if (ext_adv->broadcast_id)
+ timeout_remove(ext_adv->broadcast_id);
+ if (ext_adv->timeout_id)
+ timeout_remove(ext_adv->timeout_id);
free(ext_adv);
}
@@ -4756,9 +4759,13 @@ static void ext_adv_disable(void *data, void *user_data)
if (handle && ext_adv->handle != handle)
return;
- if (ext_adv->id) {
- timeout_remove(ext_adv->id);
- ext_adv->id = 0;
+ if (ext_adv->broadcast_id) {
+ timeout_remove(ext_adv->broadcast_id);
+ ext_adv->broadcast_id = 0;
+ }
+ if (ext_adv->timeout_id) {
+ timeout_remove(ext_adv->timeout_id);
+ ext_adv->timeout_id = 0;
}
ext_adv->enable = 0x00;
@@ -4975,9 +4982,10 @@ static void send_ext_adv(struct btdev *btdev, const struct btdev *remote,
1 + 24 + meta_event.lear.data_len);
}
-static void le_set_ext_adv_enable_complete(struct btdev *btdev,
- struct le_ext_adv *ext_adv)
+static bool ext_adv_broadcast(void *user_data)
{
+ struct le_ext_adv *ext_adv = user_data;
+ struct btdev *btdev = ext_adv->dev;
uint16_t report_type;
int i;
@@ -5013,7 +5021,10 @@ static void le_set_ext_adv_enable_complete(struct btdev *btdev,
report_type, true);
}
}
+
+ return true;
}
+
static void adv_set_terminate(struct btdev *dev, uint8_t status, uint8_t handle,
uint16_t conn_handle, uint8_t num_evts)
{
@@ -5032,7 +5043,7 @@ static bool ext_adv_timeout(void *user_data)
{
struct le_ext_adv *adv = user_data;
- adv->id = 0;
+ adv->timeout_id = 0;
adv_set_terminate(adv->dev, BT_HCI_ERR_ADV_TIMEOUT, adv->handle,
0x0000, 0x00);
le_ext_adv_free(adv);
@@ -5117,32 +5128,32 @@ static int cmd_set_ext_adv_enable(struct btdev *dev, const void *data,
if (!cmd->enable)
ext_adv_disable(ext_adv, NULL);
- else if (eas->duration)
- ext_adv->id = timeout_add(eas->duration * 10,
- ext_adv_timeout,
+ else {
+ /* Send the first advertising report right away and
+ * start the timer for continuous advertising. */
+ ext_adv_broadcast(ext_adv);
+ /* BLE advertising interval shall be between 20 ms
+ * and 10.24 s in 0.625 ms steps. Most devices which
+ * require fast advertising use an interval between
+ * 100 ms and 500 ms.
+ */
+ ext_adv->broadcast_id = timeout_add(200 /* 200 ms */,
+ ext_adv_broadcast,
ext_adv, NULL);
+ if (eas->duration) {
+ unsigned int duration_ms = eas->duration * 10;
+ ext_adv->timeout_id = timeout_add(duration_ms,
+ ext_adv_timeout,
+ ext_adv, NULL);
+ }
+ }
+
}
exit_complete:
cmd_complete(dev, BT_HCI_CMD_LE_SET_EXT_ADV_ENABLE, &status,
sizeof(status));
- if (status == BT_HCI_ERR_SUCCESS && cmd->enable) {
- /* Go through each sets and send adv event to peer device */
- for (i = 0; i < cmd->num_of_sets; i++) {
- const struct bt_hci_cmd_ext_adv_set *eas;
- struct le_ext_adv *ext_adv;
-
- eas = data + sizeof(*cmd) + (sizeof(*eas) * i);
-
- ext_adv = queue_find(dev->le_ext_adv,
- match_ext_adv_handle,
- UINT_TO_PTR(eas->handle));
- if (ext_adv)
- le_set_ext_adv_enable_complete(dev, ext_adv);
- }
- }
-
return 0;
}
@@ -5492,43 +5503,6 @@ done:
return 0;
}
-static void scan_ext_adv(struct btdev *dev, struct btdev *remote)
-{
- const struct queue_entry *entry;
-
- for (entry = queue_get_entries(remote->le_ext_adv); entry;
- entry = entry->next) {
- struct le_ext_adv *ext_adv = entry->data;
- uint16_t report_type;
-
- if (!ext_adv->enable)
- continue;
-
- if (!ext_adv_match_addr(dev, ext_adv))
- continue;
-
- report_type = get_ext_adv_type(ext_adv->type);
- send_ext_adv(dev, remote, ext_adv, report_type, false);
-
- if (dev->le_scan_type != 0x01)
- continue;
-
- /* if scannable bit is set the send scan response */
- if (ext_adv->type & 0x02) {
- if (ext_adv->type == 0x13)
- report_type = 0x1b;
- else if (ext_adv->type == 0x12)
- report_type = 0x1a;
- else if (!(ext_adv->type & 0x10))
- report_type &= 0x08;
- else
- continue;
-
- send_ext_adv(dev, remote, ext_adv, report_type, true);
- }
- }
-}
-
static void scan_pa(struct btdev *dev, struct btdev *remote)
{
struct le_per_adv *per_adv = queue_find(dev->le_per_adv,
@@ -5557,7 +5531,6 @@ static int cmd_set_ext_scan_enable_complete(struct btdev *dev, const void *data,
if (!btdev_list[i] || btdev_list[i] == dev)
continue;
- scan_ext_adv(dev, btdev_list[i]);
scan_pa(dev, btdev_list[i]);
}