diff --git a/emulator/bthost.c b/emulator/bthost.c
index 20d90c9..3cb2cee 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
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;
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)
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);
}
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;
}
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)
{
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
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
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)