summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2016-10-05 12:19:59 +0300
committerJohan Hedberg <johan.hedberg@intel.com>2016-10-16 09:00:57 +0300
commit0817b052031752db383ed2b18bfbe6a4ce62600b (patch)
treed838b6839d5b0d652082eb0ce9b6421262f40b4e /net
parentaca8700f92108857513885eaed19a6ee54440305 (diff)
Bluetooth: L2CAP: Allow sending fragmented buffers
This enabled L2CAP CoC to send buffers that contains fragments. Change-Id: I898b8375f634d3f0652ec1e7f5a206aa47dd232d Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e06dea006..a72f55377 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1379,7 +1379,7 @@ static struct net_buf *l2cap_chan_create_seg(struct bt_l2cap_le_chan *ch,
if (net_buf_headroom(buf) >= headroom) {
if (sdu_hdr_len) {
/* Push SDU length if set */
- net_buf_push_le16(buf, buf->len);
+ net_buf_push_le16(buf, net_buf_frags_len(buf));
}
return net_buf_ref(buf);
}
@@ -1391,7 +1391,7 @@ segment:
}
if (sdu_hdr_len) {
- net_buf_add_le16(seg, buf->len);
+ net_buf_add_le16(seg, net_buf_frags_len(buf));
}
len = min(min(buf->len, L2CAP_LE_MIN_MTU - sdu_hdr_len), ch->tx.mps);
@@ -1436,22 +1436,33 @@ static int l2cap_chan_le_send_sdu(struct bt_l2cap_le_chan *ch,
struct net_buf *buf)
{
int ret, sent, total_len;
+ struct net_buf *frag;
- if (buf->len > ch->tx.mtu) {
+ total_len = net_buf_frags_len(buf);
+
+ if (total_len > ch->tx.mtu) {
return -EMSGSIZE;
}
- total_len = buf->len;
+ frag = buf;
+ if (!frag->len && frag->frags) {
+ frag = frag->frags;
+ }
/* Add SDU length for the first segment */
- ret = l2cap_chan_le_send(ch, buf, BT_L2CAP_SDU_HDR_LEN);
+ ret = l2cap_chan_le_send(ch, frag, BT_L2CAP_SDU_HDR_LEN);
if (ret < 0) {
return ret;
}
/* Send remaining segments */
for (sent = ret; sent < total_len; sent += ret) {
- ret = l2cap_chan_le_send(ch, buf, 0);
+ /* Proceed to next fragment */
+ if (!frag->len) {
+ frag = frag->frags;
+ }
+
+ ret = l2cap_chan_le_send(ch, frag, 0);
if (ret < 0) {
return ret;
}