diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-07-14 22:44:47 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-07-14 23:09:34 +0200 |
commit | 81596d12b173a4d53e8fcf04a775ce3c6573d5e9 (patch) | |
tree | c4ebf47e7d85cb73196efb6e3553d3a6466f5df0 /emulator/le.c | |
parent | 8a4b1bd1bb7e34322d42c86a02734a5d09ad8be1 (diff) | |
download | bluez-81596d12b173a4d53e8fcf04a775ce3c6573d5e9.tar.gz |
emulator: Add support for scan window and scan interval handling
Diffstat (limited to 'emulator/le.c')
-rw-r--r-- | emulator/le.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/emulator/le.c b/emulator/le.c index a0d902bef..6ffa0d4a1 100644 --- a/emulator/le.c +++ b/emulator/le.c @@ -69,6 +69,8 @@ struct bt_le { struct bt_phy *phy; struct bt_crypto *crypto; int adv_timeout_id; + int scan_timeout_id; + bool scan_window_active; uint8_t event_mask[16]; uint16_t manufacturer; @@ -504,6 +506,60 @@ static bool stop_adv(struct bt_le *hci) return true; } +static void scan_timeout_callback(int id, void *user_data) +{ + struct bt_le *hci = user_data; + unsigned int msec; + + if (hci->le_scan_window == hci->le_scan_interval || + !hci->scan_window_active) { + msec = (hci->le_scan_window * 625) / 1000; + hci->scan_window_active = true; + } else { + msec = ((hci->le_scan_interval - + hci->le_scan_window) * 625) / 1000; + hci->scan_window_active = false; + } + + if (mainloop_modify_timeout(id, msec) < 0) { + fprintf(stderr, "Setting scanning timeout failed\n"); + hci->le_scan_enable = 0x00; + hci->scan_window_active = false; + } +} + +static bool start_scan(struct bt_le *hci) +{ + unsigned int msec; + + if (hci->scan_timeout_id >= 0) + return false; + + msec = (hci->le_scan_window * 625) / 1000; + + hci->scan_timeout_id = mainloop_add_timeout(msec, scan_timeout_callback, + hci, NULL); + if (hci->scan_timeout_id < 0) + return false; + + hci->scan_window_active = true; + + return true; +} + +static bool stop_scan(struct bt_le *hci) +{ + if (hci->scan_timeout_id < 0) + return false; + + mainloop_remove_timeout(hci->scan_timeout_id); + hci->scan_timeout_id = -1; + + hci->scan_window_active = false; + + return true; +} + static void cmd_complete(struct bt_le *hci, uint16_t opcode, const void *data, uint8_t len) { @@ -577,6 +633,7 @@ static void cmd_reset(struct bt_le *hci, const void *data, uint8_t size) uint8_t status; stop_adv(hci); + stop_scan(hci); reset_defaults(hci); status = BT_HCI_ERR_SUCCESS; @@ -982,6 +1039,7 @@ static void cmd_le_set_scan_enable(struct bt_le *hci, { const struct bt_hci_cmd_le_set_scan_enable *cmd = data; uint8_t status; + bool result; /* Valid range for scan enable is 0x00 to 0x01 */ if (cmd->enable > 0x01) { @@ -1005,6 +1063,17 @@ static void cmd_le_set_scan_enable(struct bt_le *hci, clear_scan_cache(hci); + if (cmd->enable == 0x01) + result = start_scan(hci); + else + result = stop_scan(hci); + + if (!result) { + cmd_status(hci, BT_HCI_ERR_UNSPECIFIED_ERROR, + BT_HCI_CMD_LE_SET_SCAN_ENABLE); + return; + } + hci->le_scan_enable = cmd->enable; hci->le_scan_filter_dup = cmd->filter_dup; @@ -1721,7 +1790,7 @@ static void phy_recv_callback(uint16_t type, const void *data, if (!(hci->le_event_mask[0] & 0x02)) return; - if (hci->le_scan_enable == 0x01) { + if (hci->scan_window_active) { const struct bt_phy_pkt_adv *pkt = data; uint8_t buf[100]; struct bt_hci_evt_le_adv_report *evt = (void *) buf; @@ -1785,6 +1854,8 @@ struct bt_le *bt_le_new(void) return NULL; hci->adv_timeout_id = -1; + hci->scan_timeout_id = -1; + hci->scan_window_active = false; reset_defaults(hci); |