summaryrefslogtreecommitdiff
path: root/emulator/le.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-12-14 15:39:03 +0100
committerMarcel Holtmann <marcel@holtmann.org>2014-12-14 15:39:03 +0100
commit4b2318b60dd35198919dc601cb79253026b54586 (patch)
treefb02b6483eb7efe90dbbf977f6851f726829975f /emulator/le.c
parent2eaec923bf23aaeedf4391d1a48339906f52bd6b (diff)
downloadbluez-4b2318b60dd35198919dc601cb79253026b54586.tar.gz
emulator: Add support for LE create connection commands and events
Diffstat (limited to 'emulator/le.c')
-rw-r--r--emulator/le.c70
1 files changed, 66 insertions, 4 deletions
diff --git a/emulator/le.c b/emulator/le.c
index da38e98f2..ce4c5cb8c 100644
--- a/emulator/le.c
+++ b/emulator/le.c
@@ -87,7 +87,6 @@ struct bt_le {
uint8_t le_scan_rsp_data_len;
uint8_t le_scan_rsp_data[31];
uint8_t le_adv_enable;
-
uint8_t le_scan_type;
uint16_t le_scan_interval;
uint16_t le_scan_window;
@@ -96,6 +95,8 @@ struct bt_le {
uint8_t le_scan_enable;
uint8_t le_scan_filter_dup;
+ uint8_t le_conn_enable;
+
uint8_t le_white_list_size;
uint8_t le_states[8];
@@ -147,8 +148,8 @@ static void reset_defaults(struct bt_le *hci)
hci->commands[26] |= 0x02; /* LE Set Advertise Enable */
hci->commands[26] |= 0x04; /* LE Set Scan Parameters */
hci->commands[26] |= 0x08; /* LE Set Scan Enable */
- //hci->commands[26] |= 0x10; /* LE Create Connection */
- //hci->commands[26] |= 0x20; /* LE Create Connection Cancel */
+ hci->commands[26] |= 0x10; /* LE Create Connection */
+ hci->commands[26] |= 0x20; /* LE Create Connection Cancel */
hci->commands[26] |= 0x40; /* LE Read White List Size */
hci->commands[26] |= 0x80; /* LE Clear White List */
hci->commands[27] |= 0x01; /* LE Add Device To White List */
@@ -244,6 +245,8 @@ static void reset_defaults(struct bt_le *hci)
hci->le_scan_enable = 0x00;
hci->le_scan_filter_dup = 0x00;
+ hci->le_conn_enable = 0x00;
+
hci->le_white_list_size = WHITE_LIST_SIZE;
memset(hci->le_states, 0, sizeof(hci->le_states));
@@ -862,6 +865,62 @@ static void cmd_le_set_scan_enable(struct bt_le *hci,
&status, sizeof(status));
}
+static void cmd_le_create_conn(struct bt_le *hci,
+ const void *data, uint8_t size)
+{
+ const struct bt_hci_cmd_le_create_conn *cmd = data;
+
+ if (hci->le_conn_enable == 0x01) {
+ cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED,
+ BT_HCI_CMD_LE_CREATE_CONN);
+ return;
+ }
+
+ /* Valid range for own address type is 0x00 to 0x01 */
+ if (cmd->own_addr_type > 0x01) {
+ cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+ BT_HCI_CMD_LE_CREATE_CONN);
+ return;
+ }
+
+ hci->le_conn_enable = 0x01;
+
+ cmd_status(hci, BT_HCI_ERR_SUCCESS, BT_HCI_CMD_LE_CREATE_CONN);
+}
+
+static void cmd_le_create_conn_cancel(struct bt_le *hci,
+ const void *data, uint8_t size)
+{
+ struct bt_hci_evt_le_conn_complete evt;
+ uint8_t status;
+
+ if (hci->le_conn_enable == 0x00) {
+ cmd_status(hci, BT_HCI_ERR_COMMAND_DISALLOWED,
+ BT_HCI_CMD_LE_CREATE_CONN_CANCEL);
+ return;
+ }
+
+ hci->le_conn_enable = 0x00;
+
+ status = BT_HCI_ERR_SUCCESS;
+ cmd_complete(hci, BT_HCI_CMD_LE_CREATE_CONN_CANCEL,
+ &status, sizeof(status));
+
+ evt.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
+ evt.handle = cpu_to_le16(0x0000);
+ evt.role = 0x00;
+ evt.peer_addr_type = 0x00;
+ memset(evt.peer_addr, 0, 6);
+ evt.interval = cpu_to_le16(0x0000);
+ evt.latency = cpu_to_le16(0x0000);
+ evt.supv_timeout = cpu_to_le16(0x0000);
+ evt.clock_accuracy = 0x00;
+
+ if (hci->le_event_mask[0] & 0x01)
+ le_meta_event(hci, BT_HCI_EVT_LE_CONN_COMPLETE,
+ &evt, sizeof(evt));
+}
+
static void cmd_le_read_white_list_size(struct bt_le *hci,
const void *data, uint8_t size)
{
@@ -1258,7 +1317,10 @@ static const struct {
cmd_le_set_scan_parameters, 7, true },
{ BT_HCI_CMD_LE_SET_SCAN_ENABLE,
cmd_le_set_scan_enable, 2, true },
-
+ { BT_HCI_CMD_LE_CREATE_CONN,
+ cmd_le_create_conn, 25, true },
+ { BT_HCI_CMD_LE_CREATE_CONN_CANCEL,
+ cmd_le_create_conn_cancel, 0, true },
{ BT_HCI_CMD_LE_READ_WHITE_LIST_SIZE,
cmd_le_read_white_list_size, 0, true },
{ BT_HCI_CMD_LE_CLEAR_WHITE_LIST,