@@ -25,6 +25,7 @@
#include "src/shared/util.h"
#include "src/shared/tester.h"
+#include "src/shared/queue.h"
#include "monitor/bt.h"
#include "monitor/rfcomm.h"
#include "bthost.h"
@@ -187,6 +188,15 @@ struct rfcomm_connection_data {
void *user_data;
};
+struct le_ext_adv {
+ struct bthost *bthost;
+ uint16_t event_type;
+ uint8_t addr_type;
+ uint8_t addr[6];
+ uint8_t direct_addr_type;
+ uint8_t direct_addr[6];
+};
+
struct bthost {
bool ready;
bthost_ready_cb ready_cb;
@@ -215,6 +225,8 @@ struct bthost {
bool le;
bool sc;
+ struct queue *le_ext_adv;
+
bthost_debug_func_t debug_callback;
bthost_destroy_func_t debug_destroy;
void *debug_data;
@@ -234,6 +246,8 @@ struct bthost *bthost_create(void)
return NULL;
}
+ bthost->le_ext_adv = queue_new();
+
/* Set defaults */
bthost->io_capability = 0x03;
@@ -403,6 +417,32 @@ static struct rfcomm_conn_cb_data *bthost_find_rfcomm_cb_by_channel(
return NULL;
}
+static struct le_ext_adv *le_ext_adv_new(struct bthost *bthost)
+{
+ struct le_ext_adv *ext_adv;
+
+ ext_adv = new0(struct le_ext_adv, 1);
+ ext_adv->bthost = bthost;
+
+ /* Add to queue */
+ if (!queue_push_tail(bthost->le_ext_adv, ext_adv)) {
+ free(ext_adv);
+ return NULL;
+ }
+
+ return ext_adv;
+}
+
+static void le_ext_adv_free(void *data)
+{
+ struct le_ext_adv *ext_adv = data;
+
+ /* Remove from queue */
+ queue_remove(ext_adv->bthost->le_ext_adv, ext_adv);
+
+ free(ext_adv);
+}
+
void bthost_destroy(struct bthost *bthost)
{
if (!bthost)
@@ -449,6 +489,8 @@ void bthost_destroy(struct bthost *bthost)
smp_stop(bthost->smp_data);
+ queue_destroy(bthost->le_ext_adv, le_ext_adv_free);
+
free(bthost);
}
@@ -1306,6 +1348,38 @@ static void evt_le_cis_req(struct bthost *bthost, const void *data, uint8_t len)
send_command(bthost, BT_HCI_CMD_LE_ACCEPT_CIS, &cmd, sizeof(cmd));
}
+static void evt_le_ext_adv_report(struct bthost *bthost, const void *data,
+ uint8_t len)
+{
+ const struct bt_hci_evt_le_ext_adv_report *ev = data;
+ const struct bt_hci_le_ext_adv_report *report;
+ struct le_ext_adv *le_ext_adv;
+ int i;
+
+ data += sizeof(ev->num_reports);
+
+ for (i = 0; i < ev->num_reports; i++) {
+ char addr_str[18];
+
+ report = data;
+ ba2str((bdaddr_t *) report->addr, addr_str);
+
+ bthost_debug(bthost, "le ext adv report: %s (0x%02x)",
+ addr_str, report->addr_type);
+
+ /* Add ext event to the queue */
+ le_ext_adv = le_ext_adv_new(bthost);
+ if (le_ext_adv) {
+ le_ext_adv->addr_type = report->addr_type;
+ memcpy(le_ext_adv->addr, report->addr, 6);
+ le_ext_adv->direct_addr_type = report->direct_addr_type;
+ memcpy(le_ext_adv->direct_addr, report->direct_addr, 6);
+ }
+
+ data += (sizeof(*report) + report->data_len);
+ }
+}
+
static void evt_le_meta_event(struct bthost *bthost, const void *data,
uint8_t len)
{
@@ -1333,6 +1407,9 @@ static void evt_le_meta_event(struct bthost *bthost, const void *data,
case BT_HCI_EVT_LE_ENHANCED_CONN_COMPLETE:
evt_le_ext_conn_complete(bthost, evt_data, len - 1);
break;
+ case BT_HCI_EVT_LE_EXT_ADV_REPORT:
+ evt_le_ext_adv_report(bthost, evt_data, len - 1);
+ break;
case BT_HCI_EVT_LE_CIS_REQ:
evt_le_cis_req(bthost, evt_data, len - 1);
break;
@@ -2583,6 +2660,29 @@ void bthost_set_adv_enable(struct bthost *bthost, uint8_t enable)
send_command(bthost, BT_HCI_CMD_LE_SET_ADV_ENABLE, &enable, 1);
}
+void bthost_set_scan_params(struct bthost *bthost, uint8_t scan_type,
+ uint8_t addr_type, uint8_t filter_policy)
+{
+ struct bt_hci_cmd_le_set_scan_parameters cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.type = scan_type;
+ cp.own_addr_type = addr_type;
+ cp.filter_policy = filter_policy;
+ send_command(bthost, BT_HCI_CMD_LE_SET_SCAN_PARAMETERS,
+ &cp, sizeof(cp));
+}
+
+void bthost_set_scan_enable(struct bthost *bthost, uint8_t enable)
+{
+ struct bt_hci_cmd_le_set_scan_enable cp;
+
+ memset(&cp, 0, sizeof(cp));
+ cp.enable = enable;
+ send_command(bthost, BT_HCI_CMD_LE_SET_SCAN_ENABLE,
+ &cp, sizeof(cp));
+}
+
void bthost_set_ext_adv_params(struct bthost *bthost)
{
struct bt_hci_cmd_le_set_ext_adv_params cp;
@@ -2612,6 +2712,24 @@ void bthost_set_ext_adv_enable(struct bthost *bthost, uint8_t enable)
send_command(bthost, BT_HCI_CMD_LE_SET_EXT_ADV_ENABLE, cp, 6);
}
+bool bthost_search_ext_adv_addr(struct bthost *bthost, const uint8_t *addr)
+{
+ const struct queue_entry *entry;
+
+ if (queue_isempty(bthost->le_ext_adv))
+ return false;
+
+ for (entry = queue_get_entries(bthost->le_ext_adv); entry;
+ entry = entry->next) {
+ struct le_ext_adv *le_ext_adv = entry->data;
+
+ if (!memcmp(le_ext_adv->addr, addr, 6))
+ return true;
+ }
+
+ return false;
+}
+
void bthost_write_ssp_mode(struct bthost *bthost, uint8_t mode)
{
send_command(bthost, BT_HCI_CMD_WRITE_SIMPLE_PAIRING_MODE, &mode, 1);
@@ -84,6 +84,11 @@ void bthost_set_ext_adv_data(struct bthost *bthost, const uint8_t *data,
uint8_t len);
void bthost_set_ext_adv_params(struct bthost *bthost);
void bthost_set_ext_adv_enable(struct bthost *bthost, uint8_t enable);
+bool bthost_search_ext_adv_addr(struct bthost *bthost, const uint8_t *addr);
+
+void bthost_set_scan_params(struct bthost *bthost, uint8_t scan_type,
+ uint8_t addr_type, uint8_t filter_policy);
+void bthost_set_scan_enable(struct bthost *bthost, uint8_t enable);
void bthost_write_ssp_mode(struct bthost *bthost, uint8_t mode);
From: Tedd Ho-Jeong An <tedd.an@intel.com> This patch adds support LE_Extended_Advertising_Report Eevnt in bthost. --- emulator/bthost.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++ emulator/bthost.h | 5 ++ 2 files changed, 123 insertions(+)