diff --git a/emulator/bthost.c b/emulator/bthost.c
index 6fbabe8..9bf9ad3 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
struct cid_hook *next;
};
+struct rfcomm_channel_hook {
+ uint8_t channel;
+ bthost_rfcomm_channel_hook_func_t func;
+ void *user_data;
+ struct rfcomm_channel_hook *next;
+};
+
struct btconn {
uint16_t handle;
uint8_t bdaddr[6];
uint16_t next_cid;
struct l2conn *l2conns;
struct cid_hook *cid_hooks;
+ struct rfcomm_channel_hook *rfcomm_channel_hooks;
struct btconn *next;
void *smp_data;
};
free(hook);
}
+ while (conn->rfcomm_channel_hooks) {
+ struct rfcomm_channel_hook *hook = conn->rfcomm_channel_hooks;
+
+ conn->rfcomm_channel_hooks = hook->next;
+ free(hook);
+ }
+
free(conn);
}
return NULL;
}
+static struct rfcomm_channel_hook *find_rfcomm_channel_hook(struct btconn *conn,
+ uint16_t channel)
+{
+ struct rfcomm_channel_hook *hook;
+
+ for (hook = conn->rfcomm_channel_hooks; hook != NULL; hook = hook->next)
+ if (hook->channel == channel)
+ return hook;
+
+ return NULL;
+}
+
static void rfcomm_ua_send(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, uint8_t cr, uint8_t dlci)
{
if (len < sizeof(*hdr))
return;
- if (RFCOMM_GET_DLCI(hdr->address))
- return;
-
if (RFCOMM_TEST_EA(hdr->length))
hdr_len = sizeof(*hdr);
else
p = data + hdr_len;
- rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len);
+ if (RFCOMM_GET_DLCI(hdr->address)) {
+ struct rfcomm_channel_hook *hook;
+
+ hook = find_rfcomm_channel_hook(conn,
+ RFCOMM_GET_CHANNEL(hdr->address));
+ if (!hook)
+ return;
+
+ hook->func(p, len - hdr_len - sizeof(uint8_t),
+ hook->user_data);
+ } else {
+ rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len);
+ }
}
static void process_rfcomm(struct bthost *bthost, struct btconn *conn,
&req, sizeof(req), NULL, NULL);
}
+void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
+ uint8_t channel,
+ bthost_rfcomm_channel_hook_func_t func,
+ void *user_data)
+{
+ struct rfcomm_channel_hook *hook;
+ struct btconn *conn;
+
+ conn = bthost_find_conn(bthost, handle);
+ if (!conn)
+ return;
+
+ hook = malloc(sizeof(*hook));
+ if (!hook)
+ return;
+
+ memset(hook, 0, sizeof(*hook));
+
+ hook->channel = channel;
+ hook->func = func;
+ hook->user_data = user_data;
+
+ hook->next = conn->rfcomm_channel_hooks;
+ conn->rfcomm_channel_hooks = hook;
+}
+
void bthost_stop(struct bthost *bthost)
{
if (bthost->smp_data) {
diff --git a/emulator/bthost.h b/emulator/bthost.h
index a3c26a1..e922f0b 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
uint8_t channel, bthost_rfcomm_connect_cb func,
void *user_data);
+typedef void (*bthost_rfcomm_channel_hook_func_t) (const void *data,
+ uint16_t len,
+ void *user_data);
+
+void bthost_add_rfcomm_channel_hook(struct bthost *bthost, uint16_t handle,
+ uint8_t channel,
+ bthost_rfcomm_channel_hook_func_t func,
+ void *user_data);
+
void bthost_start(struct bthost *bthost);
void bthost_stop(struct bthost *bthost);