summaryrefslogtreecommitdiff
path: root/emulator/bthost.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-02-27 13:22:46 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2015-02-27 13:22:46 +0200
commit731e9954b36c2a34136af8b069a93fbbf95e67c2 (patch)
tree5269c1fc458e329b01211fcc81303fba7ba9d1a0 /emulator/bthost.c
parent74aa69af7d0f83c4317a28f5cc4ada2c69fed027 (diff)
downloadbluez-731e9954b36c2a34136af8b069a93fbbf95e67c2.tar.gz
emulator/bthost: Fix calling RFCOMM callback for zero-length data
Diffstat (limited to 'emulator/bthost.c')
-rw-r--r--emulator/bthost.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 86f1e56f3..16e103d1a 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -2038,23 +2038,30 @@ static void rfcomm_mcc_recv(struct bthost *bthost, struct btconn *conn,
}
}
+#define GET_LEN8(length) ((length & 0xfe) >> 1)
+#define GET_LEN16(length) ((length & 0xfffe) >> 1)
+
static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
struct l2conn *l2conn, const void *data,
uint16_t len)
{
const struct rfcomm_hdr *hdr = data;
- uint16_t hdr_len;
+ uint16_t hdr_len, data_len;
const void *p;
if (len < sizeof(*hdr))
return;
- if (RFCOMM_TEST_EA(hdr->length))
+ if (RFCOMM_TEST_EA(hdr->length)) {
+ data_len = (uint16_t) GET_LEN8(hdr->length);
hdr_len = sizeof(*hdr);
- else
+ } else {
+ uint8_t ex_len = *((uint8_t *)(data + sizeof(*hdr)));
+ data_len = ((uint16_t) hdr->length << 8) | ex_len;
hdr_len = sizeof(*hdr) + sizeof(uint8_t);
+ }
- if (len < hdr_len)
+ if (len < hdr_len + data_len)
return;
p = data + hdr_len;
@@ -2064,13 +2071,10 @@ static void rfcomm_uih_recv(struct bthost *bthost, struct btconn *conn,
hook = find_rfcomm_chan_hook(conn,
RFCOMM_GET_CHANNEL(hdr->address));
- if (!hook)
- return;
-
- hook->func(p, len - hdr_len - sizeof(uint8_t),
- hook->user_data);
+ if (hook && data_len)
+ hook->func(p, data_len, hook->user_data);
} else {
- rfcomm_mcc_recv(bthost, conn, l2conn, p, len - hdr_len);
+ rfcomm_mcc_recv(bthost, conn, l2conn, p, data_len);
}
}