From 1cb6d1445959dc373dd2ef926cc3bc3a265314aa Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 29 May 2013 11:29:37 +0300 Subject: [PATCH] emulator: Add callback mechanism for L2CAP requests --- emulator/bthost.c | 62 +++++++++++++++++++++++++++++++++++++++++--- emulator/bthost.h | 6 ++++- tools/l2cap-tester.c | 2 +- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/emulator/bthost.c b/emulator/bthost.c index 20d90c990..3cb2ceeb3 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 609da8076..b621d7039 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 f6426a706..dc3aa6872 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) -- 2.47.3