summaryrefslogtreecommitdiff
path: root/emulator/bthost.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2014-09-17 15:49:45 +0300
committerJohan Hedberg <johan.hedberg@intel.com>2014-09-18 08:04:23 +0300
commit3d51328b6c8bbf9ef687a962c8bc1127a5873138 (patch)
tree467e4a0f8fcfaed144cda4d58b5d1437511cd42b /emulator/bthost.c
parenta7b600b45b369961d53e33455ea30628f6ee0bea (diff)
downloadbluez-3d51328b6c8bbf9ef687a962c8bc1127a5873138.tar.gz
emulator/bthost: Add iovec support
This convert bthost_set_send_handler to take struct iovec for doing scatter io.
Diffstat (limited to 'emulator/bthost.c')
-rw-r--r--emulator/bthost.c96
1 files changed, 51 insertions, 45 deletions
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 1fae58079..766f14c79 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -448,11 +448,12 @@ void bthost_set_send_handler(struct bthost *bthost, bthost_send_func handler,
bthost->send_data = user_data;
}
-static void queue_command(struct bthost *bthost, const void *data,
- uint16_t len)
+static void queue_command(struct bthost *bthost, const struct iovec *iov,
+ int iovlen)
{
struct cmd_queue *cmd_q = &bthost->cmd_q;
struct cmd *cmd;
+ int i;
cmd = malloc(sizeof(*cmd));
if (!cmd)
@@ -460,8 +461,10 @@ static void queue_command(struct bthost *bthost, const void *data,
memset(cmd, 0, sizeof(*cmd));
- memcpy(cmd->data, data, len);
- cmd->len = len;
+ for (i = 0; i < iovlen; i++) {
+ memcpy(cmd->data + cmd->len, iov[i].iov_base, iov[i].iov_len);
+ cmd->len += iov[i].iov_len;
+ }
if (cmd_q->tail)
cmd_q->tail->next = cmd;
@@ -472,45 +475,47 @@ static void queue_command(struct bthost *bthost, const void *data,
cmd_q->tail = cmd;
}
-static void send_packet(struct bthost *bthost, const void *data, uint16_t len)
+static void send_packet(struct bthost *bthost, const struct iovec *iov,
+ int iovlen)
{
if (!bthost->send_handler)
return;
- bthost->send_handler(data, len, bthost->send_data);
+ 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)
{
- struct bt_hci_acl_hdr *acl_hdr;
- struct bt_l2cap_hdr *l2_hdr;
- uint16_t pkt_len;
- void *pkt_data;
+ struct bt_hci_acl_hdr acl_hdr;
+ struct bt_l2cap_hdr l2_hdr;
+ uint8_t pkt = BT_H4_ACL_PKT;
+ struct iovec iov[4];
- pkt_len = 1 + sizeof(*acl_hdr) + sizeof(*l2_hdr) + len;
+ iov[0].iov_base = &pkt;
+ iov[0].iov_len = sizeof(pkt);
- pkt_data = malloc(pkt_len);
- if (!pkt_data)
- return;
+ acl_hdr.handle = acl_handle_pack(handle, 0);
+ acl_hdr.dlen = cpu_to_le16(len + sizeof(l2_hdr));
- ((uint8_t *) pkt_data)[0] = BT_H4_ACL_PKT;
+ iov[1].iov_base = &acl_hdr;
+ iov[1].iov_len = sizeof(acl_hdr);
- acl_hdr = pkt_data + 1;
- acl_hdr->handle = acl_handle_pack(handle, 0);
- acl_hdr->dlen = cpu_to_le16(len + sizeof(*l2_hdr));
+ l2_hdr.cid = cpu_to_le16(cid);
+ l2_hdr.len = cpu_to_le16(len);
- l2_hdr = pkt_data + 1 + 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);
- if (len > 0)
- memcpy(pkt_data + 1 + sizeof(*acl_hdr) + sizeof(*l2_hdr),
- data, len);
+ if (len == 0) {
+ send_packet(bthost, iov, 3);
+ return;
+ }
- send_packet(bthost, pkt_data, pkt_len);
+ iov[3].iov_base = (void *) data;
+ iov[3].iov_len = len;
- free(pkt_data);
+ send_packet(bthost, iov, 4);
}
static uint8_t l2cap_sig_send(struct bthost *bthost, struct btconn *conn,
@@ -636,33 +641,30 @@ bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t code,
static void send_command(struct bthost *bthost, uint16_t opcode,
const void *data, uint8_t len)
{
- struct bt_hci_cmd_hdr *hdr;
- uint16_t pkt_len;
- void *pkt_data;
+ struct bt_hci_cmd_hdr hdr;
+ uint8_t pkt = BT_H4_CMD_PKT;
+ struct iovec iov[3];
- pkt_len = 1 + sizeof(*hdr) + len;
+ iov[0].iov_base = &pkt;
+ iov[0].iov_len = sizeof(pkt);
- pkt_data = malloc(pkt_len);
- if (!pkt_data)
- return;
+ hdr.opcode = cpu_to_le16(opcode);
+ hdr.plen = len;
- ((uint8_t *) pkt_data)[0] = BT_H4_CMD_PKT;
+ iov[1].iov_base = &hdr;
+ iov[1].iov_len = sizeof(hdr);
- hdr = pkt_data + 1;
- hdr->opcode = cpu_to_le16(opcode);
- hdr->plen = len;
-
- if (len > 0)
- memcpy(pkt_data + 1 + sizeof(*hdr), data, len);
+ if (len > 0) {
+ iov[2].iov_base = (void *) data;
+ iov[2].iov_len = len;
+ }
if (bthost->ncmd) {
- send_packet(bthost, pkt_data, pkt_len);
+ send_packet(bthost, iov, len > 0 ? 3 : 2);
bthost->ncmd--;
} else {
- queue_command(bthost, pkt_data, pkt_len);
+ queue_command(bthost, iov, len > 0 ? 3 : 2);
}
-
- free(pkt_data);
}
static void next_cmd(struct bthost *bthost)
@@ -670,6 +672,7 @@ static void next_cmd(struct bthost *bthost)
struct cmd_queue *cmd_q = &bthost->cmd_q;
struct cmd *cmd = cmd_q->head;
struct cmd *next;
+ struct iovec iov;
if (!cmd)
return;
@@ -679,7 +682,10 @@ static void next_cmd(struct bthost *bthost)
if (!bthost->ncmd)
return;
- send_packet(bthost, cmd->data, cmd->len);
+ iov.iov_base = cmd->data;
+ iov.iov_len = cmd->len;
+
+ send_packet(bthost, &iov, 1);
bthost->ncmd--;
if (next)