diff --git a/emulator/btdev.c b/emulator/btdev.c
index c5ea35e..90457a5 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
};
struct le_ext_adv {
+ struct btdev *dev;
uint8_t handle;
uint8_t enable;
uint8_t type; /* evt_properties */
uint8_t adv_data_len;
uint8_t scan_data[252];
uint8_t scan_data_len;
+ unsigned int id;
};
struct btdev {
if (handle && ext_adv->handle != handle)
return;
+ if (ext_adv->id) {
+ timeout_remove(ext_adv->id);
+ ext_adv->id = 0;
+ }
+
ext_adv->enable = 0x00;
}
struct le_ext_adv *ext_adv;
ext_adv = new0(struct le_ext_adv, 1);
+ ext_adv->dev = btdev;
ext_adv->handle = handle;
/* Add to queue */
{
struct le_ext_adv *ext_adv = data;
+ /* Remove to queue */
+ queue_remove(ext_adv->dev->le_ext_adv, ext_adv);
+
+ if (ext_adv->id)
+ timeout_remove(ext_adv->id);
+
free(ext_adv);
}
}
}
}
+static void adv_set_terminate(struct btdev *dev, uint8_t status, uint8_t handle,
+ uint16_t conn_handle, uint8_t num_evts)
+{
+ struct bt_hci_evt_le_adv_set_term ev;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.status = status;
+ ev.handle = handle;
+ ev.conn_handle = cpu_to_le16(conn_handle);
+ ev.num_evts = num_evts;
+
+ le_meta_event(dev, BT_HCI_EVT_LE_ADV_SET_TERM, &ev, sizeof(ev));
+}
+
+static bool ext_adv_timeout(void *user_data)
+{
+ struct le_ext_adv *adv = user_data;
+
+ adv->id = 0;
+ adv_set_terminate(adv->dev, BT_HCI_ERR_ADV_TIMEOUT, adv->handle,
+ 0x0000, 0x00);
+ le_ext_adv_free(adv);
+
+ return false;
+}
static int cmd_set_ext_adv_enable(struct btdev *dev, const void *data,
uint8_t len)
}
ext_adv->enable = cmd->enable;
+
+ if (!cmd->enable)
+ ext_adv_disable(ext_adv, NULL);
+ else if (eas->duration)
+ ext_adv->id = timeout_add(eas->duration * 10,
+ ext_adv_timeout,
+ ext_adv, NULL);
}
exit_complete:
return 0;
}
+static void ext_adv_term(void *data, void *user_data)
+{
+ struct le_ext_adv *adv = data;
+ struct btdev_conn *conn = user_data;
+
+ /* if connectable bit is set the send adv terminate */
+ if (conn && adv->type & 0x01) {
+ adv_set_terminate(conn->dev, 0x00, adv->handle, conn->handle,
+ 0x00);
+ le_ext_adv_free(adv);
+ }
+}
+
static void le_ext_conn_complete(struct btdev *btdev,
const struct bt_hci_cmd_le_ext_create_conn *cmd,
struct le_ext_adv *ext_adv,
return;
/* Disable EXT ADV */
- queue_foreach(btdev->le_ext_adv, ext_adv_disable, NULL);
- queue_foreach(conn->link->dev->le_ext_adv, ext_adv_disable,
- NULL);
+ queue_foreach(btdev->le_ext_adv, ext_adv_term, conn);
+ queue_foreach(conn->link->dev->le_ext_adv, ext_adv_term, conn);
ev.status = status;
ev.peer_addr_type = btdev->le_scan_own_addr_type;
diff --git a/monitor/bt.h b/monitor/bt.h
index d60bbdb..738bc29 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
#define BT_HCI_ERR_UNSUPPORTED_FEATURE 0x11
#define BT_HCI_ERR_INVALID_PARAMETERS 0x12
#define BT_HCI_ERR_UNSPECIFIED_ERROR 0x1f
+#define BT_HCI_ERR_ADV_TIMEOUT 0x3c
#define BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH 0x3e
#define BT_HCI_ERR_UNKNOWN_ADVERTISING_ID 0x42