Diff between 50b0d43e5624eb740cd4c4200a15d00b08ddaf8d and 918e4d24a53fdb1db1a3c43cf7c07b8aac60f385

Changed Files

File Additions Deletions Status
emulator/btdev.c +1 -1 modified
monitor/bt.h +91 -1 modified
monitor/packet.c +226 -12 modified

Full Patch

diff --git a/emulator/btdev.c b/emulator/btdev.c
index e0c4642..718920b 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -1057,7 +1057,7 @@ static void process_cmd(struct btdev *btdev, const void *data, uint16_t len)
 		rlai.max_pdu = cpu_to_le32(672);
 		rlai.amp_type = 0x01;		/* 802.11 AMP Controller */
 		rlai.pal_cap = cpu_to_le16(0x0000);
-		rlai.max_assoc_size = cpu_to_le16(512);
+		rlai.max_assoc_len = cpu_to_le16(672);
 		rlai.max_flush_to = cpu_to_le32(0xffffffff);
 		rlai.be_flush_to = cpu_to_le32(0xffffffff);
 		cmd_complete(btdev, opcode, &rlai, sizeof(rlai));
diff --git a/monitor/bt.h b/monitor/bt.h
index 7bb82e7..287d705 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -270,6 +270,17 @@ struct bt_hci_cmd_io_capability_request_neg_reply {
 	uint8_t  reason;
 } __attribute__ ((packed));
 
+#define BT_HCI_CMD_DISCONN_PHY_LINK		0x0437
+struct bt_hci_cmd_disconn_phy_link {
+	uint8_t  phy_handle;
+	uint8_t  reason;
+} __attribute__ ((packed));
+
+#define BT_HCI_CMD_DISCONN_LOGIC_LINK		0x043a
+struct bt_hci_cmd_disconn_logic_link {
+	uint16_t handle;
+} __attribute__ ((packed));
+
 #define BT_HCI_CMD_HOLD_MODE			0x0801
 struct bt_hci_cmd_hold_mode {
 	uint16_t handle;
@@ -662,6 +673,16 @@ struct bt_hci_rsp_read_data_block_size {
 	uint16_t num_blocks;
 } __attribute__ ((packed));
 
+#define BT_HCI_CMD_READ_ENCRYPT_KEY_SIZE	0x1408
+struct bt_hci_cmd_read_encrypt_key_size {
+	uint16_t handle;
+} __attribute__ ((packed));
+struct bt_hci_rsp_read_encrypt_key_size {
+	uint8_t  status;
+	uint16_t handle;
+	uint8_t  key_size;
+} __attribute__ ((packed));
+
 #define BT_HCI_CMD_READ_LOCAL_AMP_INFO		0x1409
 struct bt_hci_rsp_read_local_amp_info {
 	uint8_t  status;
@@ -672,11 +693,36 @@ struct bt_hci_rsp_read_local_amp_info {
 	uint32_t max_pdu;
 	uint8_t  amp_type;
 	uint16_t pal_cap;
-	uint16_t max_assoc_size;
+	uint16_t max_assoc_len;
 	uint32_t max_flush_to;
 	uint32_t be_flush_to;
 } __attribute__ ((packed));
 
+#define BT_HCI_CMD_READ_LOCAL_AMP_ASSOC		0x140a
+struct bt_hci_cmd_read_local_amp_assoc {
+	uint8_t  phy_handle;
+	uint16_t len_so_far;
+	uint16_t max_assoc_len;
+} __attribute__ ((packed));
+struct bt_hci_rsp_read_local_amp_assoc {
+	uint8_t  status;
+	uint8_t  phy_handle;
+	uint16_t remain_assoc_len;
+	uint8_t  assoc_fragement[248];
+} __attribute__ ((packed));
+
+#define BT_HCI_CMD_WRITE_REMOTE_AMP_ASSOC	0x140b
+struct bt_hci_cmd_write_remote_amp_assoc {
+	uint8_t  phy_handle;
+	uint16_t len_so_far;
+	uint16_t remain_assoc_len;
+	uint8_t  assoc_fragement[248];
+} __attribute__ ((packed));
+struct bt_hci_rsp_write_remote_amp_assoc {
+	uint8_t  status;
+	uint8_t  phy_handle;
+} __attribute__ ((packed));
+
 #define BT_HCI_CMD_LE_SET_EVENT_MASK		0x2001
 struct bt_hci_cmd_le_set_event_mask {
 	uint8_t  mask[8];
@@ -1146,6 +1192,50 @@ struct bt_hci_evt_remote_host_features_notify {
 	uint8_t  features[8];
 } __attribute__ ((packed));
 
+#define BT_HCI_EVT_LE_META_EVENT		0x3e
+
+#define BT_HCI_EVT_PHY_LINK_COMPLETE		0x40
+struct bt_hci_evt_phy_link_complete {
+	uint8_t  status;
+	uint8_t  phy_handle;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_CHANNEL_SELECTED		0x412
+struct bt_hci_evt_channel_selected {
+	uint8_t  phy_handle;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_DISCONN_PHY_LINK_COMPLETE	0x42
+struct bt_hci_evt_disconn_phy_link_complete {
+	uint8_t  status;
+	uint8_t  phy_handle;
+	uint8_t  reason;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_LOGIC_LINK_COMPLETE		0x45
+struct bt_hci_evt_logic_link_complete {
+	uint8_t  status;
+	uint16_t handle;
+	uint8_t  phy_handle;
+	uint8_t  flow_spec;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_DISCONN_LOGIC_LINK_COMPLETE	0x46
+struct bt_hci_evt_disconn_logic_link_complete {
+	uint8_t  status;
+	uint16_t handle;
+	uint8_t  reason;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_NUM_COMPLETED_DATA_BLOCKS	0x48
+struct bt_hci_evt_num_completed_data_blocks {
+	uint16_t total_num_blocks;
+	uint8_t  num_handles;
+	uint16_t handle;
+	uint16_t num_packets;
+	uint16_t num_blocks;
+} __attribute__ ((packed));
+
 #define BT_HCI_EVT_LE_CONN_COMPLETE		0x01
 struct bt_hci_evt_le_conn_complete {
 	uint8_t  status;
diff --git a/monitor/packet.c b/monitor/packet.c
index fea13df..524bfd6 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -418,6 +418,11 @@ static void print_handle(uint16_t handle)
 	print_field("Handle: %d", btohs(handle));
 }
 
+static void print_phy_handle(uint8_t phy_handle)
+{
+	print_field("Physical handle: %d", phy_handle);
+}
+
 static void print_pkt_type(uint16_t pkt_type)
 {
 	print_field("Packet type: 0x%4.4x", btohs(pkt_type));
@@ -748,6 +753,11 @@ static void print_key_type(uint8_t key_type)
 	print_field("Key type: %s (0x%2.2x)", str, key_type);
 }
 
+static void print_key_size(uint8_t key_size)
+{
+	print_field("Key size: %d", key_size);
+}
+
 static void print_key(const char *label, const uint8_t *link_key)
 {
 	char str[33];
@@ -1638,6 +1648,21 @@ static void io_capability_request_neg_reply_cmd(const void *data, uint8_t size)
 	print_reason(cmd->reason);
 }
 
+static void disconn_phy_link_cmd(const void *data, uint8_t size)
+{
+	const struct bt_hci_cmd_disconn_phy_link *cmd = data;
+
+	print_phy_handle(cmd->phy_handle);
+	print_reason(cmd->reason);
+}
+
+static void disconn_logic_link_cmd(const void *data, uint8_t size)
+{
+	const struct bt_hci_cmd_disconn_logic_link *cmd = data;
+
+	print_handle(cmd->handle);
+}
+
 static void hold_mode_cmd(const void *data, uint8_t size)
 {
 	const struct bt_hci_cmd_hold_mode *cmd = data;
@@ -2175,6 +2200,122 @@ static void read_data_block_size_rsp(const void *data, uint8_t size)
 	print_field("Num blocks: %d", btohs(rsp->num_blocks));
 }
 
+static void read_encrypt_key_size_cmd(const void *data, uint8_t size)
+{
+	const struct bt_hci_cmd_read_encrypt_key_size *cmd = data;
+
+	print_handle(cmd->handle);
+}
+
+static void read_encrypt_key_size_rsp(const void *data, uint8_t size)
+{
+	const struct bt_hci_rsp_read_encrypt_key_size *rsp = data;
+
+	print_status(rsp->status);
+	print_handle(rsp->handle);
+	print_key_size(rsp->key_size);
+}
+
+static void read_local_amp_info_rsp(const void *data, uint8_t size)
+{
+	const struct bt_hci_rsp_read_local_amp_info *rsp = data;
+	const char *str;
+
+	print_status(rsp->status);
+
+	switch (rsp->amp_status) {
+	case 0x00:
+		str = "Present";
+		break;
+	case 0x01:
+		str = "Bluetooth only";
+		break;
+	case 0x02:
+		str = "No capacity";
+		break;
+	case 0x03:
+		str = "Low capacity";
+		break;
+	case 0x04:
+		str = "Medium capacity";
+		break;
+	case 0x05:
+		str = "High capacity";
+		break;
+	case 0x06:
+		str = "Full capacity";
+		break;
+	default:
+		str = "Reserved";
+		break;
+	}
+
+	print_field("AMP status: %s (0x%2.2x)", str, rsp->amp_status);
+
+	print_field("Total bandwidth: %d kbps", btohl(rsp->total_bw));
+	print_field("Max guaranteed bandwidth: %d kbps", btohl(rsp->max_bw));
+	print_field("Min latency: %d", btohl(rsp->min_latency));
+	print_field("Max PDU size: %d", btohl(rsp->max_pdu));
+
+	switch (rsp->amp_type) {
+	case 0x00:
+		str = "Primary BR/EDR Controller";
+		break;
+	case 0x01:
+		str = "802.11 AMP Controller";
+		break;
+	default:
+		str = "Reserved";
+		break;
+	}
+
+	print_field("Controller type: %s (0x%2.2x)", str, rsp->amp_type);
+
+	print_field("PAL capabilities: 0x%4.4x", rsp->pal_cap);
+	print_field("Max ASSOC length: %d", rsp->max_assoc_len);
+	print_field("Max flush timeout: %d", rsp->max_flush_to);
+	print_field("Best effort flush timeout: %d", rsp->be_flush_to);
+}
+
+static void read_local_amp_assoc_cmd(const void *data, uint8_t size)
+{
+	const struct bt_hci_cmd_read_local_amp_assoc *cmd = data;
+
+	print_phy_handle(cmd->phy_handle);
+	print_field("Length so far: %d", btohs(cmd->len_so_far));
+	print_field("Max ASSOC length: %d", btohs(cmd->max_assoc_len));
+}
+
+static void read_local_amp_assoc_rsp(const void *data, uint8_t size)
+{
+	const struct bt_hci_rsp_read_local_amp_assoc *rsp = data;
+
+	print_status(rsp->status);
+	print_phy_handle(rsp->phy_handle);
+	print_field("Remaining ASSOC length: %d", btohs(rsp->remain_assoc_len));
+
+	packet_hexdump(data + 4, size - 4);
+}
+
+static void write_remote_amp_assoc_cmd(const void *data, uint8_t size)
+{
+	const struct bt_hci_cmd_write_remote_amp_assoc *cmd = data;
+
+	print_phy_handle(cmd->phy_handle);
+	print_field("Length so far: %d", btohs(cmd->len_so_far));
+	print_field("Remaining ASSOC length: %d", btohs(cmd->remain_assoc_len));
+
+	packet_hexdump(data + 5, size - 5);
+}
+
+static void write_remote_amp_assoc_rsp(const void *data, uint8_t size)
+{
+	const struct bt_hci_rsp_write_remote_amp_assoc *rsp = data;
+
+	print_status(rsp->status);
+	print_phy_handle(rsp->phy_handle);
+}
+
 static void le_set_event_mask_cmd(const void *data, uint8_t size)
 {
 	const struct bt_hci_cmd_le_set_event_mask *cmd = data;
@@ -2502,10 +2643,12 @@ static const struct opcode_data opcode_table[] = {
 				status_bdaddr_rsp, 7, true },
 	{ 0x0435, "Create Physical Link"		},
 	{ 0x0436, "Accept Physical Link"		},
-	{ 0x0437, "Disconnect Physical Link"		},
+	{ 0x0437, "Disconnect Physical Link",
+				disconn_phy_link_cmd, 2, true },
 	{ 0x0438, "Create Logical Link"			},
 	{ 0x0439, "Accept Logical Link"			},
-	{ 0x043a, "Disconnect Logical Link"		},
+	{ 0x043a, "Disconnect Logical Link",
+				disconn_logic_link_cmd, 2, true },
 	{ 0x043b, "Logical Link Cancel"			},
 	{ 0x043c, "Flow Specifcation Modify"		},
 
@@ -2749,10 +2892,18 @@ static const struct opcode_data opcode_table[] = {
 	{ 0x1405, "Read RSSI"				},
 	{ 0x1406, "Read AFH Channel Map"		},
 	{ 0x1407, "Read Clock"				},
-	{ 0x1408, "Read Encryption Key Size"		},
-	{ 0x1409, "Read Local AMP Info"			},
-	{ 0x140a, "Read Local AMP ASSOC"		},
-	{ 0x140b, "Write Remote AMP ASSOC"		},
+	{ 0x1408, "Read Encryption Key Size",
+				read_encrypt_key_size_cmd, 2, true,
+				read_encrypt_key_size_rsp, 4, true },
+	{ 0x1409, "Read Local AMP Info",
+				null_cmd, 0, true,
+				read_local_amp_info_rsp, 31, true },
+	{ 0x140a, "Read Local AMP ASSOC",
+				read_local_amp_assoc_cmd, 5, true,
+				read_local_amp_assoc_rsp, 5, false },
+	{ 0x140b, "Write Remote AMP ASSOC",
+				write_remote_amp_assoc_cmd, 6, false,
+				write_remote_amp_assoc_rsp, 2, true },
 
 	/* OGF 8 - LE Control */
 	{ 0x2001, "LE Set Event Mask",
@@ -3377,6 +3528,63 @@ static void remote_host_features_notify_evt(const void *data, uint8_t size)
 	print_features(evt->features);
 }
 
+static void phy_link_complete_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_phy_link_complete *evt = data;
+
+	print_status(evt->status);
+	print_phy_handle(evt->phy_handle);
+}
+
+static void channel_selected_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_channel_selected *evt = data;
+
+	print_phy_handle(evt->phy_handle);
+}
+
+static void disconn_phy_link_complete_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_disconn_phy_link_complete *evt = data;
+
+	print_status(evt->status);
+	print_phy_handle(evt->phy_handle);
+	print_reason(evt->reason);
+}
+
+static void logic_link_complete_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_logic_link_complete *evt = data;
+
+	print_status(evt->status);
+	print_handle(evt->handle);
+	print_phy_handle(evt->phy_handle);
+	print_field("TX flow spec: 0x%2.2x", evt->flow_spec);
+}
+
+static void disconn_logic_link_complete_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_disconn_logic_link_complete *evt = data;
+
+	print_status(evt->status);
+	print_handle(evt->handle);
+	print_reason(evt->reason);
+}
+
+static void num_completed_data_blocks_evt(const void *data, uint8_t size)
+{
+	const struct bt_hci_evt_num_completed_data_blocks *evt = data;
+
+	print_field("Total num data blocks: %d", btohs(evt->total_num_blocks));
+	print_field("Num handles: %d", evt->num_handles);
+	print_handle(evt->handle);
+	print_field("Num packets: %d", evt->num_packets);
+	print_field("Num blocks: %d", evt->num_blocks);
+
+	if (size > sizeof(*evt))
+		packet_hexdump(data + sizeof(*evt), size - sizeof(*evt));
+}
+
 static void le_conn_complete_evt(const void *data, uint8_t size)
 {
 	const struct bt_hci_evt_le_conn_complete *evt = data;
@@ -3651,15 +3859,21 @@ static const struct event_data event_table[] = {
 	{ 0x3e, "LE Meta Event",
 				le_meta_event_evt, 1, false },
 	/* reserved event */
-	{ 0x40, "Physical Link Complete"		},
-	{ 0x41, "Channel Selected"			},
-	{ 0x42, "Disconn Physical Link Complete"	},
+	{ 0x40, "Physical Link Complete",
+				phy_link_complete_evt, 2, true },
+	{ 0x41, "Channel Selected",
+				channel_selected_evt, 1, true },
+	{ 0x42, "Disconnect Physical Link Complete",
+				disconn_phy_link_complete_evt, 3, true },
 	{ 0x43, "Physical Link Loss Early Warning"	},
 	{ 0x44, "Physical Link Recovery"		},
-	{ 0x45, "Logical Link Complete"			},
-	{ 0x46, "Disconn Logical Link Complete"		},
+	{ 0x45, "Logical Link Complete",
+				logic_link_complete_evt, 5, true },
+	{ 0x46, "Disconnect Logical Link Complete",
+				disconn_logic_link_complete_evt, 4, true },
 	{ 0x47, "Flow Spec Modify Complete"		},
-	{ 0x48, "Number Of Completed Data Blocks"	},
+	{ 0x48, "Number Of Completed Data Blocks",
+				num_completed_data_blocks_evt, 3, false },
 	{ 0x49, "AMP Start Test"			},
 	{ 0x4a, "AMP Test End"				},
 	{ 0x4b, "AMP Receiver Report"			},