diff --git a/emulator/bthost.c b/emulator/bthost.c
index 654338d..7ccef9c 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
struct l2cap_pending_req *next;
};
+struct l2cap_conn_cb_data {
+ uint16_t psm;
+ bthost_l2cap_connect_cb func;
+ void *user_data;
+ struct l2cap_conn_cb_data *next;
+};
+
struct bthost {
uint8_t bdaddr[6];
bthost_send_func send_handler;
void *cmd_complete_data;
bthost_new_conn_cb new_conn_cb;
void *new_conn_data;
- uint16_t server_psm;
+ struct l2cap_conn_cb_data *new_l2cap_conn_data;
struct l2cap_pending_req *l2reqs;
};
return NULL;
}
+static struct l2cap_conn_cb_data *bthost_find_l2cap_cb_by_psm(
+ struct bthost *bthost, uint16_t psm)
+{
+ struct l2cap_conn_cb_data *cb;
+
+ for (cb = bthost->new_l2cap_conn_data; cb != NULL; cb = cb->next) {
+ if (cb->psm == psm)
+ return cb;
+ }
+
+ return NULL;
+}
+
void bthost_destroy(struct bthost *bthost)
{
if (!bthost)
free(req);
}
+ while (bthost->new_l2cap_conn_data) {
+ struct l2cap_conn_cb_data *cb = bthost->new_l2cap_conn_data;
+
+ bthost->new_l2cap_conn_data = cb->next;
+ free(cb);
+ }
+
free(bthost);
}
memset(&rsp, 0, sizeof(rsp));
rsp.scid = req->scid;
- if (bthost->server_psm && bthost->server_psm == psm)
+ if (bthost_find_l2cap_cb_by_psm(bthost, psm))
rsp.dcid = cpu_to_le16(conn->next_cid++);
else
rsp.result = cpu_to_le16(0x0002); /* PSM Not Supported */
if (!rsp.result) {
struct bt_l2cap_pdu_config_req conf_req;
+ struct l2cap_conn_cb_data *cb_data;
+ struct l2conn *l2conn;
bthost_add_l2cap_conn(bthost, conn, le16_to_cpu(rsp.dcid),
le16_to_cpu(rsp.scid),
l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_CONFIG_REQ, 0,
&conf_req, sizeof(conf_req));
+
+ cb_data = bthost_find_l2cap_cb_by_psm(bthost, psm);
+ l2conn = btconn_find_l2cap_conn_by_scid(conn,
+ le16_to_cpu(rsp.scid));
+
+ if (cb_data && l2conn->psm == cb_data->psm && cb_data->func)
+ cb_data->func(conn->handle, l2conn->dcid,
+ cb_data->user_data);
}
return true;
rsp.mps = 23;
rsp.credits = 1;
- if (bthost->server_psm && bthost->server_psm == psm)
+ if (bthost_find_l2cap_cb_by_psm(bthost, psm))
rsp.dcid = cpu_to_le16(conn->next_cid++);
else
rsp.result = cpu_to_le16(0x0002); /* PSM Not Supported */
send_command(bthost, BT_HCI_CMD_LE_START_ENCRYPT, &cmd, sizeof(cmd));
}
+void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
+ bthost_l2cap_connect_cb func, void *user_data)
+{
+ struct l2cap_conn_cb_data *data;
+
+ data = malloc(sizeof(struct l2cap_conn_cb_data));
+ if (!data)
+ return;
+
+ data->psm = psm;
+ data->user_data = user_data;
+ data->func = func;
+ data->next = bthost->new_l2cap_conn_data;
+
+ bthost->new_l2cap_conn_data = data;
+}
+
void bthost_set_server_psm(struct bthost *bthost, uint16_t psm)
{
- bthost->server_psm = psm;
+ bthost_add_l2cap_server(bthost, psm, NULL, NULL);
}
void bthost_start(struct bthost *bthost)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 474ada9..2b8f212 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
void bthost_le_start_encrypt(struct bthost *bthost, uint16_t handle,
const uint8_t ltk[16]);
+typedef void (*bthost_l2cap_connect_cb) (uint16_t handle, uint16_t cid,
+ void *user_data);
void bthost_set_server_psm(struct bthost *bthost, uint16_t psm);
+void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
+ bthost_l2cap_connect_cb func, void *user_data);
+
void bthost_start(struct bthost *bthost);
void bthost_stop(struct bthost *bthost);