In order to write discovery tests for LE, we need some implementation
on emulator side.
This patch series basically reports virtual devices in adv mode for
devices in scan mode.
This new series was reorganized by merging some commits and removing
others not related to discovery tests. Note that this is just a first
set, based on a RFC sent a while ago by Bruna Moreira. Future patches
will build on these patches.
Jefferson Delfes (6):
emulator: Store LE advertising data length in btdev
emulator: Implement basic LE set adv enable command
emulator: Store LE scan state of virtual controller
emulator: Disallow LE set scan params command when scan is enabled
emulator: Dummy LE set advertising parameters
emulator: Implement LE advertising report
emulator/btdev.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
monitor/bt.h | 13 +++++++
2 files changed, 113 insertions(+), 2 deletions(-)
--
1.8.3.2
Hi Jefferson,
On Wed, Jul 03, 2013, Jefferson Delfes wrote:
> In order to write discovery tests for LE, we need some implementation
> on emulator side.
> This patch series basically reports virtual devices in adv mode for
> devices in scan mode.
>
> This new series was reorganized by merging some commits and removing
> others not related to discovery tests. Note that this is just a first
> set, based on a RFC sent a while ago by Bruna Moreira. Future patches
> will build on these patches.
>
> Jefferson Delfes (6):
> emulator: Store LE advertising data length in btdev
> emulator: Implement basic LE set adv enable command
> emulator: Store LE scan state of virtual controller
> emulator: Disallow LE set scan params command when scan is enabled
> emulator: Dummy LE set advertising parameters
> emulator: Implement LE advertising report
>
> emulator/btdev.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
> monitor/bt.h | 13 +++++++
> 2 files changed, 113 insertions(+), 2 deletions(-)
All patches in this set have been applied. Thanks.
Johan
When LE scan is enabled, the command LE set scan parameters should
return a command disallowed in status of command complete event.
---
emulator/btdev.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 925eaf7..f3de1a5 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -1475,7 +1475,10 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
case BT_HCI_CMD_LE_SET_SCAN_PARAMETERS:
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
- status = BT_HCI_ERR_SUCCESS;
+ if (btdev->le_scan_enable)
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ else
+ status = BT_HCI_ERR_SUCCESS;
cmd_complete(btdev, opcode, &status, sizeof(status));
break;
--
1.8.3.2
The LE command set scan enable can change the scan state of virtual
controller.
---
emulator/btdev.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 060347d..925eaf7 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -91,6 +91,8 @@ struct btdev {
uint8_t le_event_mask[8];
uint8_t le_adv_data[31];
uint8_t le_adv_data_len;
+ uint8_t le_scan_enable;
+ uint8_t le_filter_dup;
uint8_t le_adv_enable;
uint16_t sync_train_interval;
@@ -843,6 +845,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
const struct bt_hci_cmd_le_set_event_mask *lsem;
const struct bt_hci_cmd_le_set_adv_data *lsad;
const struct bt_hci_cmd_le_set_adv_enable *lsae;
+ const struct bt_hci_cmd_le_set_scan_enable *lsse;
struct bt_hci_rsp_read_default_link_policy rdlp;
struct bt_hci_rsp_read_stored_link_key rslk;
struct bt_hci_rsp_write_stored_link_key wslk;
@@ -1479,7 +1482,14 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
case BT_HCI_CMD_LE_SET_SCAN_ENABLE:
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
- status = BT_HCI_ERR_SUCCESS;
+ lsse = data;
+ if (btdev->le_scan_enable == lsse->enable)
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ else {
+ btdev->le_scan_enable = lsse->enable;
+ btdev->le_filter_dup = lsse->filter_dup;
+ status = BT_HCI_ERR_SUCCESS;
+ }
cmd_complete(btdev, opcode, &status, sizeof(status));
break;
--
1.8.3.2
When a virtual device starts a LE advertising, emulator searches for
other virtual devices that are in scan mode, in order to send adv data
to these devices.
Inverse goes when LE scan is enabled. Emulator searches virtual devices
that are in advertising mode and copy adv data to them.
---
emulator/btdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index c98a20d..79d2f0e 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -811,6 +811,60 @@ static void remote_version_complete(struct btdev *btdev, uint16_t handle)
&rvc, sizeof(rvc));
}
+static void le_send_adv_report(struct btdev *btdev, const struct btdev *remote)
+{
+ struct __packed {
+ uint8_t subevent;
+ union {
+ struct bt_hci_evt_le_adv_report lar;
+ uint8_t raw[10 + 31 + 1];
+ };
+ } meta_event;
+
+ meta_event.subevent = BT_HCI_EVT_LE_ADV_REPORT;
+
+ memset(&meta_event.lar, 0, sizeof(meta_event.lar));
+ meta_event.lar.num_reports = 1;
+ memcpy(meta_event.lar.addr, remote->bdaddr, 6);
+ meta_event.lar.data_len = remote->le_adv_data_len;
+ memcpy(meta_event.lar.data, remote->le_adv_data,
+ meta_event.lar.data_len);
+ /* Not available */
+ meta_event.raw[10 + meta_event.lar.data_len] = 127;
+ send_event(btdev, BT_HCI_EVT_LE_META_EVENT, &meta_event,
+ 1 + 10 + meta_event.lar.data_len + 1);
+}
+
+static void le_set_adv_enable_complete(struct btdev *btdev)
+{
+ int i;
+
+ for (i = 0; i < MAX_BTDEV_ENTRIES; i++) {
+ if (!btdev_list[i] || btdev_list[i] == btdev)
+ continue;
+
+ if (!btdev_list[i]->le_scan_enable)
+ continue;
+
+ le_send_adv_report(btdev_list[i], btdev);
+ }
+}
+
+static void le_set_scan_enable_complete(struct btdev *btdev)
+{
+ int i;
+
+ for (i = 0; i < MAX_BTDEV_ENTRIES; i++) {
+ if (!btdev_list[i] || btdev_list[i] == btdev)
+ continue;
+
+ if (!btdev_list[i]->le_adv_enable)
+ continue;
+
+ le_send_adv_report(btdev, btdev_list[i]);
+ }
+}
+
static void default_cmd(struct btdev *btdev, uint16_t opcode,
const void *data, uint8_t len)
{
@@ -1480,6 +1534,8 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
status = BT_HCI_ERR_SUCCESS;
}
cmd_complete(btdev, opcode, &status, sizeof(status));
+ if (status == BT_HCI_ERR_SUCCESS && btdev->le_adv_enable)
+ le_set_adv_enable_complete(btdev);
break;
case BT_HCI_CMD_LE_SET_SCAN_PARAMETERS:
@@ -1504,6 +1560,8 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
status = BT_HCI_ERR_SUCCESS;
}
cmd_complete(btdev, opcode, &status, sizeof(status));
+ if (status == BT_HCI_ERR_SUCCESS && btdev->le_scan_enable)
+ le_set_scan_enable_complete(btdev);
break;
case BT_HCI_CMD_LE_READ_WHITE_LIST_SIZE:
--
1.8.3.2
Implement basic LE set adv parameters command.
---
emulator/btdev.c | 10 ++++++++++
monitor/bt.h | 12 ++++++++++++
2 files changed, 22 insertions(+)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index f3de1a5..c98a20d 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -1451,6 +1451,16 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
cmd_complete(btdev, opcode, &lrlf, sizeof(lrlf));
break;
+ case BT_HCI_CMD_LE_SET_ADV_PARAMETERS:
+ if (btdev->type == BTDEV_TYPE_BREDR)
+ goto unsupported;
+ if (btdev->le_adv_enable)
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ else
+ status = BT_HCI_ERR_SUCCESS;
+ cmd_complete(btdev, opcode, &status, sizeof(status));
+ break;
+
case BT_HCI_CMD_LE_READ_ADV_TX_POWER:
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
diff --git a/monitor/bt.h b/monitor/bt.h
index da62a3d..0f1c1d8 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -842,6 +842,18 @@ struct bt_hci_cmd_le_set_random_address {
uint8_t addr[6];
} __attribute__ ((packed));
+#define BT_HCI_CMD_LE_SET_ADV_PARAMETERS 0x2006
+struct bt_hci_cmd_le_set_adv_parameters {
+ uint16_t adv_interval_min;
+ uint16_t adv_interval_max;
+ uint8_t adv_type;
+ uint8_t own_address_type;
+ uint8_t direct_address_type;
+ uint8_t direct_address[6];
+ uint8_t adv_channel_map;
+ uint8_t adv_filter_policy;
+} __attribute__ ((packed));
+
#define BT_HCI_CMD_LE_READ_ADV_TX_POWER 0x2007
struct bt_hci_rsp_le_read_adv_tx_power {
uint8_t status;
--
1.8.3.2
Store advertising state of virtual controller in btdev struct.
---
emulator/btdev.c | 15 +++++++++++++++
monitor/bt.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 73174a5..060347d 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -91,6 +91,7 @@ struct btdev {
uint8_t le_event_mask[8];
uint8_t le_adv_data[31];
uint8_t le_adv_data_len;
+ uint8_t le_adv_enable;
uint16_t sync_train_interval;
uint32_t sync_train_timeout;
@@ -841,6 +842,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
const struct bt_hci_cmd_set_event_mask_page2 *semp2;
const struct bt_hci_cmd_le_set_event_mask *lsem;
const struct bt_hci_cmd_le_set_adv_data *lsad;
+ const struct bt_hci_cmd_le_set_adv_enable *lsae;
struct bt_hci_rsp_read_default_link_policy rdlp;
struct bt_hci_rsp_read_stored_link_key rslk;
struct bt_hci_rsp_write_stored_link_key wslk;
@@ -1454,6 +1456,19 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
cmd_complete(btdev, opcode, &lratp, sizeof(lratp));
break;
+ case BT_HCI_CMD_LE_SET_ADV_ENABLE:
+ if (btdev->type == BTDEV_TYPE_BREDR)
+ goto unsupported;
+ lsae = data;
+ if (btdev->le_adv_enable == lsae->enable)
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+ else {
+ btdev->le_adv_enable = lsae->enable;
+ status = BT_HCI_ERR_SUCCESS;
+ }
+ cmd_complete(btdev, opcode, &status, sizeof(status));
+ break;
+
case BT_HCI_CMD_LE_SET_SCAN_PARAMETERS:
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
diff --git a/monitor/bt.h b/monitor/bt.h
index f8759c7..da62a3d 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -1479,6 +1479,7 @@ struct bt_hci_evt_le_long_term_key_request {
#define BT_HCI_ERR_UNKNOWN_CONN_ID 0x02
#define BT_HCI_ERR_HARDWARE_FAILURE 0x03
#define BT_HCI_ERR_PAGE_TIMEOUT 0x04
+#define BT_HCI_ERR_COMMAND_DISALLOWED 0x0c
#define BT_HCI_ERR_INVALID_PARAMETERS 0x12
struct bt_l2cap_hdr {
--
1.8.3.2
LE advertising data length will be used for emulating reports in other
virtual devices.
---
emulator/btdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index a602c05..73174a5 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -90,6 +90,7 @@ struct btdev {
uint8_t le_simultaneous;
uint8_t le_event_mask[8];
uint8_t le_adv_data[31];
+ uint8_t le_adv_data_len;
uint16_t sync_train_interval;
uint32_t sync_train_timeout;
@@ -1487,6 +1488,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
if (btdev->type == BTDEV_TYPE_BREDR)
goto unsupported;
lsad = data;
+ btdev->le_adv_data_len = lsad->len;
memcpy(btdev->le_adv_data, lsad->data, 31);
status = BT_HCI_ERR_SUCCESS;
cmd_complete(btdev, opcode, &status, sizeof(status));
--
1.8.3.2