Bluetooth: Move L2CAP header encoding to sending stage
Encoding the L2CAP header when allocating the buffer means that we must know the final size up-front. This is not always possible, so move the header encoding to bt_l2cap_send() and only have the bt_l2cap_create_pdu() function reserve enough headroom without actually encoding anything. Change-Id: Ic1c3b6b72c265cd0db4e835790fa915e0acd9388 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
e104fa5928
commit
44e67698a6
6 changed files with 30 additions and 45 deletions
|
@ -67,7 +67,7 @@ static void send_err_rsp(struct bt_conn *conn, uint8_t req, uint16_t handle,
|
|||
rsp->handle = sys_cpu_to_le16(handle);
|
||||
rsp->error = err;
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf);
|
||||
}
|
||||
|
||||
static void att_mtu_req(struct bt_conn *conn, struct bt_buf *data)
|
||||
|
@ -112,7 +112,7 @@ static void att_mtu_req(struct bt_conn *conn, struct bt_buf *data)
|
|||
rsp = bt_buf_add(buf, sizeof(*rsp));
|
||||
rsp->mtu = sys_cpu_to_le16(mtu);
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf);
|
||||
}
|
||||
|
||||
static bool range_is_valid(uint16_t start, uint16_t end, uint16_t *err)
|
||||
|
@ -573,7 +573,7 @@ struct bt_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len)
|
|||
struct bt_att_hdr *hdr;
|
||||
struct bt_buf *buf;
|
||||
|
||||
buf = bt_l2cap_create_pdu(conn, BT_L2CAP_CID_ATT, sizeof(*hdr) + len);
|
||||
buf = bt_l2cap_create_pdu(conn);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ void bt_conn_send(struct bt_conn *conn, struct bt_buf *buf)
|
|||
remaining -= len;
|
||||
|
||||
while (remaining) {
|
||||
buf = bt_conn_create_pdu(conn);
|
||||
buf = bt_l2cap_create_pdu(conn);
|
||||
|
||||
len = min(remaining, dev->le_mtu);
|
||||
|
||||
|
@ -366,10 +366,3 @@ void bt_conn_put(struct bt_conn *conn)
|
|||
|
||||
conn->handle = 0;
|
||||
}
|
||||
|
||||
struct bt_buf *bt_conn_create_pdu(struct bt_conn *conn)
|
||||
{
|
||||
size_t reserve = conn->dev->drv->head_reserve;
|
||||
|
||||
return bt_buf_get(BT_ACL_OUT, reserve + sizeof(struct bt_hci_acl_hdr));
|
||||
}
|
||||
|
|
|
@ -102,9 +102,6 @@ struct bt_conn {
|
|||
char rx_stack[BT_CONN_RX_STACK_SIZE];
|
||||
};
|
||||
|
||||
/* Prepare a new buffer to be sent over the connection */
|
||||
struct bt_buf *bt_conn_create_pdu(struct bt_conn *conn);
|
||||
|
||||
/* Process incoming data for a connection */
|
||||
void bt_conn_recv(struct bt_conn *conn, struct bt_buf *buf, uint8_t flags);
|
||||
|
||||
|
|
|
@ -67,29 +67,24 @@ static uint8_t get_ident(struct bt_conn *conn)
|
|||
return conn->l2cap.ident;
|
||||
}
|
||||
|
||||
struct bt_buf *bt_l2cap_create_pdu(struct bt_conn *conn, uint16_t cid,
|
||||
size_t len)
|
||||
struct bt_buf *bt_l2cap_create_pdu(struct bt_conn *conn)
|
||||
{
|
||||
size_t head_reserve = sizeof(struct bt_l2cap_hdr) +
|
||||
sizeof(struct bt_hci_acl_hdr) +
|
||||
conn->dev->drv->head_reserve;
|
||||
|
||||
return bt_buf_get(BT_ACL_OUT, head_reserve);
|
||||
}
|
||||
|
||||
void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct bt_buf *buf)
|
||||
{
|
||||
struct bt_l2cap_hdr *hdr;
|
||||
struct bt_buf *buf;
|
||||
|
||||
buf = bt_conn_create_pdu(conn);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if buf created has enough space */
|
||||
if (bt_buf_tailroom(buf) - sizeof(*hdr) < len) {
|
||||
BT_ERR("Buffer too short\n");
|
||||
bt_buf_put(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hdr = bt_buf_add(buf, sizeof(*hdr));
|
||||
hdr->len = sys_cpu_to_le16(len);
|
||||
hdr = bt_buf_push(buf, sizeof(*hdr));
|
||||
hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));
|
||||
hdr->cid = sys_cpu_to_le16(cid);
|
||||
|
||||
return buf;
|
||||
bt_conn_send(conn, buf);
|
||||
}
|
||||
|
||||
static void rej_not_understood(struct bt_conn *conn, uint8_t ident)
|
||||
|
@ -98,8 +93,7 @@ static void rej_not_understood(struct bt_conn *conn, uint8_t ident)
|
|||
struct bt_l2cap_sig_hdr *hdr;
|
||||
struct bt_buf *buf;
|
||||
|
||||
buf = bt_l2cap_create_pdu(conn, BT_L2CAP_CID_LE_SIG,
|
||||
sizeof(*hdr) + sizeof(*rej));
|
||||
buf = bt_l2cap_create_pdu(conn);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
@ -112,7 +106,7 @@ static void rej_not_understood(struct bt_conn *conn, uint8_t ident)
|
|||
rej = bt_buf_add(buf, sizeof(*rej));
|
||||
rej->reason = sys_cpu_to_le16(BT_L2CAP_REJ_NOT_UNDERSTOOD);
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
|
||||
}
|
||||
|
||||
static void le_conn_param_rsp(struct bt_conn *conn, struct bt_buf *buf)
|
||||
|
@ -212,8 +206,7 @@ void bt_l2cap_update_conn_param(struct bt_conn *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
buf = bt_l2cap_create_pdu(conn, BT_L2CAP_CID_LE_SIG,
|
||||
sizeof(*hdr) + sizeof(*req));
|
||||
buf = bt_l2cap_create_pdu(conn);
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
@ -229,5 +222,5 @@ void bt_l2cap_update_conn_param(struct bt_conn *conn)
|
|||
req->latency = sys_cpu_to_le16(LE_CONN_LATENCY);
|
||||
req->timeout = sys_cpu_to_le16(LE_CONN_TIMEOUT);
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
|
||||
}
|
||||
|
|
|
@ -69,8 +69,10 @@ struct bt_l2cap_conn_param_rsp {
|
|||
} PACK_STRUCT;
|
||||
|
||||
/* Prepare an L2CAP PDU to be sent over a connection */
|
||||
struct bt_buf *bt_l2cap_create_pdu(struct bt_conn *conn, uint16_t cid,
|
||||
size_t len);
|
||||
struct bt_buf *bt_l2cap_create_pdu(struct bt_conn *conn);
|
||||
|
||||
/* Send L2CAP PDU over a connection */
|
||||
void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct bt_buf *buf);
|
||||
|
||||
/* Receive a new L2CAP PDU from a connection */
|
||||
void bt_l2cap_recv(struct bt_conn *conn, struct bt_buf *buf);
|
||||
|
|
|
@ -204,7 +204,7 @@ struct bt_buf *bt_smp_create_pdu(struct bt_conn *conn, uint8_t op, size_t len)
|
|||
struct bt_smp_hdr *hdr;
|
||||
struct bt_buf *buf;
|
||||
|
||||
buf = bt_l2cap_create_pdu(conn, BT_L2CAP_CID_SMP, sizeof(*hdr) + len);
|
||||
buf = bt_l2cap_create_pdu(conn);
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ static void send_err_rsp(struct bt_conn *conn, uint8_t reason)
|
|||
rsp = bt_buf_add(buf, sizeof(*rsp));
|
||||
rsp->reason = reason;
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf);
|
||||
}
|
||||
|
||||
static int smp_init(struct bt_conn_smp *smp)
|
||||
|
@ -295,7 +295,7 @@ static int smp_pairing_req(struct bt_conn *conn, struct bt_buf *buf)
|
|||
smp->prsp[0] = BT_SMP_CMD_PAIRING_RSP;
|
||||
memcpy(smp->prsp + 1, rsp, sizeof(*rsp));
|
||||
|
||||
bt_conn_send(conn, rsp_buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_SMP, rsp_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ static int smp_pairing_confirm(struct bt_conn *conn, struct bt_buf *buf)
|
|||
return BT_SMP_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
bt_conn_send(conn, rsp_buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_SMP, rsp_buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ static int smp_pairing_random(struct bt_conn *conn, struct bt_buf *buf)
|
|||
rsp = bt_buf_add(rsp_buf, sizeof(*rsp));
|
||||
memcpy(rsp->val, smp->prnd, sizeof(rsp->val));
|
||||
|
||||
bt_conn_send(conn, rsp_buf);
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_SMP, rsp_buf);
|
||||
|
||||
/*smp_s1(smp->tk, smp->prnd, smp->rrnd, stk);*/
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue