Diff between 391dbdefa0dfe3e8cddcd280019cb39b5aa0b24e and 1cb6d1445959dc373dd2ef926cc3bc3a265314aa

Changed Files

File Additions Deletions Status
emulator/bthost.c +59 -3 modified
emulator/bthost.h +5 -1 modified
tools/l2cap-tester.c +1 -1 modified

Full Patch

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 20d90c9..3cb2cee 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -66,6 +66,13 @@ struct l2conn {
 	struct l2conn *next;
 };
 
+struct l2cap_pending_req {
+	uint8_t ident;
+	bthost_l2cap_rsp_cb cb;
+	void *user_data;
+	struct l2cap_pending_req *next;
+};
+
 struct bthost {
 	uint8_t bdaddr[6];
 	bthost_send_func send_handler;
@@ -78,6 +85,7 @@ struct bthost {
 	bthost_new_conn_cb new_conn_cb;
 	void *new_conn_data;
 	uint16_t server_psm;
+	struct l2cap_pending_req *l2reqs;
 };
 
 struct bthost *bthost_create(void)
@@ -181,6 +189,14 @@ void bthost_destroy(struct bthost *bthost)
 		btconn_free(conn);
 	}
 
+	while (bthost->l2reqs) {
+		struct l2cap_pending_req *req = bthost->l2reqs;
+
+		bthost->l2reqs = req->next;
+		req->cb(0, NULL, 0, req->user_data);
+		free(req);
+	}
+
 	free(bthost);
 }
 
@@ -293,15 +309,32 @@ static uint8_t l2cap_sig_send(struct bthost *bthost, uint16_t handle,
 	return ident;
 }
 
-bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t req,
-					const void *data, uint16_t len)
+bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t code,
+				const void *data, uint16_t len,
+				bthost_l2cap_rsp_cb cb, void *user_data)
 {
+	struct l2cap_pending_req *req;
 	uint8_t ident;
 
-	ident = l2cap_sig_send(bthost, handle, req, 0, data, len);
+	ident = l2cap_sig_send(bthost, handle, code, 0, data, len);
 	if (!ident)
 		return false;
 
+	if (!cb)
+		return true;
+
+	req = malloc(sizeof(*req));
+	if (!req)
+		return false;
+
+	memset(req, 0, sizeof(*req));
+	req->ident = ident;
+	req->cb = cb;
+	req->user_data = user_data;
+
+	req->next = bthost->l2reqs;
+	bthost->l2reqs = req;
+
 	return true;
 }
 
@@ -698,6 +731,26 @@ static bool l2cap_info_req(struct bthost *bthost, uint16_t handle,
 	return true;
 }
 
+static void handle_pending_l2reqs(struct bthost *bthost, uint16_t handle,
+						uint8_t ident, uint8_t code,
+						const void *data, uint16_t len)
+{
+	struct l2cap_pending_req **curr;
+
+	for (curr = &bthost->l2reqs; *curr != NULL;) {
+		struct l2cap_pending_req *req = *curr;
+
+		if (req->ident != ident) {
+			curr = &req->next;
+			continue;
+		}
+
+		*curr = req->next;
+		req->cb(code, data, len, req->user_data);
+		free(req);
+	}
+}
+
 static void l2cap_sig(struct bthost *bthost, uint16_t handle, const void *data,
 								uint16_t len)
 {
@@ -750,6 +803,9 @@ static void l2cap_sig(struct bthost *bthost, uint16_t handle, const void *data,
 		ret = false;
 	}
 
+	handle_pending_l2reqs(bthost, handle, hdr->ident, hdr->code,
+						data + sizeof(*hdr), hdr_len);
+
 	if (ret)
 		return;
 
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 609da80..b621d70 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -51,8 +51,12 @@ void bthost_set_connect_cb(struct bthost *bthost, bthost_new_conn_cb cb,
 
 void bthost_hci_connect(struct bthost *bthost, const uint8_t *bdaddr);
 
+typedef void (*bthost_l2cap_rsp_cb) (uint8_t code, const void *data,
+						uint16_t len, void *user_data);
+
 bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t req,
-					const void *data, uint16_t len);
+				const void *data, uint16_t len,
+				bthost_l2cap_rsp_cb cb, void *user_data);
 
 void bthost_write_scan_enable(struct bthost *bthost, uint8_t scan);
 
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index f6426a7..dc3aa68 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -481,7 +481,7 @@ static void client_new_conn(uint16_t handle, void *user_data)
 
 	bthost = hciemu_client_get_host(data->hciemu);
 	bthost_l2cap_req(bthost, handle, BT_L2CAP_PDU_CONN_REQ,
-							&req, sizeof(req));
+						&req, sizeof(req), NULL, NULL);
 }
 
 static void test_bredr_accept_success(const void *test_data)