Diff between db38b66c92757fe74e3820171dd375153c888437 and 9da0e88c0da7a45fb283819c0e6c5a853d72452f

Changed Files

File Additions Deletions Status
emulator/bthost.c +42 -33 modified

Full Patch

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 22bdca5..8d06de9 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -484,38 +484,48 @@ static void send_packet(struct bthost *bthost, const struct iovec *iov,
 	bthost->send_handler(iov, iovlen, bthost->send_data);
 }
 
-static void send_acl(struct bthost *bthost, uint16_t handle, uint16_t cid,
-						const void *data, uint16_t len)
+static void send_iov(struct bthost *bthost, uint16_t handle, uint16_t cid,
+					const struct iovec *iov, int iovcnt)
 {
 	struct bt_hci_acl_hdr acl_hdr;
 	struct bt_l2cap_hdr l2_hdr;
 	uint8_t pkt = BT_H4_ACL_PKT;
-	struct iovec iov[4];
+	struct iovec pdu[3 + iovcnt];
+	int i, len = 0;
 
-	iov[0].iov_base = &pkt;
-	iov[0].iov_len = sizeof(pkt);
+	for (i = 0; i < iovcnt; i++) {
+		pdu[3 + i].iov_base = iov[i].iov_base;
+		pdu[3 + i].iov_len = iov[i].iov_len;
+		len += iov[i].iov_len;
+	}
+
+	pdu[0].iov_base = &pkt;
+	pdu[0].iov_len = sizeof(pkt);
 
 	acl_hdr.handle = acl_handle_pack(handle, 0);
 	acl_hdr.dlen = cpu_to_le16(len + sizeof(l2_hdr));
 
-	iov[1].iov_base = &acl_hdr;
-	iov[1].iov_len = sizeof(acl_hdr);
+	pdu[1].iov_base = &acl_hdr;
+	pdu[1].iov_len = sizeof(acl_hdr);
 
 	l2_hdr.cid = cpu_to_le16(cid);
 	l2_hdr.len = cpu_to_le16(len);
 
-	iov[2].iov_base = &l2_hdr;
-	iov[2].iov_len = sizeof(l2_hdr);
+	pdu[2].iov_base = &l2_hdr;
+	pdu[2].iov_len = sizeof(l2_hdr);
 
-	if (len == 0) {
-		send_packet(bthost, iov, 3);
-		return;
-	}
+	send_packet(bthost, pdu, 3 + iovcnt);
+}
 
-	iov[3].iov_base = (void *) data;
-	iov[3].iov_len = len;
+static void send_acl(struct bthost *bthost, uint16_t handle, uint16_t cid,
+						const void *data, uint16_t len)
+{
+	struct iovec iov;
 
-	send_packet(bthost, iov, 4);
+	iov.iov_base = (void *) data;
+	iov.iov_len = len;
+
+	send_iov(bthost, handle, cid, &iov, 1);
 }
 
 static uint8_t l2cap_sig_send(struct bthost *bthost, struct btconn *conn,
@@ -523,15 +533,9 @@ static uint8_t l2cap_sig_send(struct bthost *bthost, struct btconn *conn,
 					const void *data, uint16_t len)
 {
 	static uint8_t next_ident = 1;
-	struct bt_l2cap_hdr_sig *hdr;
-	uint16_t pkt_len, cid;
-	void *pkt_data;
-
-	pkt_len = sizeof(*hdr) + len;
-
-	pkt_data = malloc(pkt_len);
-	if (!pkt_data)
-		return 0;
+	struct bt_l2cap_hdr_sig hdr;
+	uint16_t cid;
+	struct iovec iov[2];
 
 	if (!ident) {
 		ident = next_ident++;
@@ -539,22 +543,27 @@ static uint8_t l2cap_sig_send(struct bthost *bthost, struct btconn *conn,
 			ident = next_ident++;
 	}
 
-	hdr = pkt_data;
-	hdr->code  = code;
-	hdr->ident = ident;
-	hdr->len   = cpu_to_le16(len);
+	hdr.code  = code;
+	hdr.ident = ident;
+	hdr.len   = cpu_to_le16(len);
 
-	if (len > 0)
-		memcpy(pkt_data + sizeof(*hdr), data, len);
+	iov[0].iov_base = &hdr;
+	iov[0].iov_len = sizeof(hdr);
 
 	if (conn->addr_type == BDADDR_BREDR)
 		cid = 0x0001;
 	else
 		cid = 0x0005;
 
-	send_acl(bthost, conn->handle, cid, pkt_data, pkt_len);
+	if (len == 0) {
+		send_iov(bthost, conn->handle, cid, iov, 1);
+		return ident;
+	}
+
+	iov[1].iov_base = (void *) data;
+	iov[1].iov_len = len;
 
-	free(pkt_data);
+	send_iov(bthost, conn->handle, cid, iov, 2);
 
 	return ident;
 }