You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/11/18 22:47:07 UTC
incubator-mynewt-larva git commit: ATT MTU exchange.
Repository: incubator-mynewt-larva
Updated Branches:
refs/heads/master a73a7e819 -> 126f083ec
ATT MTU exchange.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/126f083e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/126f083e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/126f083e
Branch: refs/heads/master
Commit: 126f083ecce7a3d0a8b8fb2c0de488099d9236fd
Parents: a73a7e8
Author: Christopher Collins <cc...@gmail.com>
Authored: Wed Nov 18 13:46:39 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Wed Nov 18 13:46:39 2015 -0800
----------------------------------------------------------------------
net/nimble/host/src/ble_hs_att.c | 28 +++++++++++++-------
net/nimble/host/src/ble_hs_att.h | 8 +++---
net/nimble/host/src/ble_hs_conn.c | 16 ++++++++++--
net/nimble/host/src/ble_hs_conn.h | 10 ++++---
net/nimble/host/src/ble_l2cap.c | 33 +++++++++++++-----------
net/nimble/host/src/ble_l2cap.h | 6 +++--
net/nimble/host/src/test/ble_hs_att_test.c | 9 ++++---
net/nimble/host/src/test/ble_hs_conn_test.c | 16 ++++++++++--
8 files changed, 86 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_hs_att.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att.c b/net/nimble/host/src/ble_hs_att.c
index fa92da5..be63df7 100644
--- a/net/nimble/host/src/ble_hs_att.c
+++ b/net/nimble/host/src/ble_hs_att.c
@@ -340,15 +340,24 @@ ble_hs_att_rx_mtu_req(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
uint8_t buf[BLE_HS_ATT_MTU_REQ_SZ];
int rc;
- rc = os_mbuf_copydata(om, 0, sizeof buf, buf);
- if (rc != 0) {
- return rc;
+ /* We should only receive this command as a server. */
+ if (conn->bhc_flags & BLE_HS_CONN_F_CLIENT) {
+ /* XXX: Unspecified what to do in this case. */
+ return EINVAL;
}
+ rc = os_mbuf_copydata(om, 0, sizeof buf, buf);
+ assert(rc == 0);
+
rc = ble_hs_att_mtu_req_parse(buf, sizeof buf, &req);
assert(rc == 0);
- /* XXX: Update connection MTU. */
+ if (req.bhamq_mtu < BLE_HS_ATT_MTU_DFLT) {
+ req.bhamq_mtu = BLE_HS_ATT_MTU_DFLT;
+ }
+
+ chan->blc_peer_mtu = req.bhamq_mtu;
+
/* XXX: Send response. */
return 0;
@@ -466,8 +475,8 @@ ble_hs_att_rx_find_info_req(struct ble_hs_conn *conn,
rc = ble_hs_att_find_info_req_parse(buf, sizeof buf, &req);
assert(rc == 0);
- /* Tx error response if start handle is greater than end handle or is 0.
- * (Vol. 3, Part F, 3.4.3.1).
+ /* Tx error response if start handle is greater than end handle or is equal
+ * to 0 (Vol. 3, Part F, 3.4.3.1).
*/
if (req.bhafq_start_handle > req.bhafq_end_handle ||
req.bhafq_start_handle == 0) {
@@ -484,7 +493,7 @@ ble_hs_att_rx_find_info_req(struct ble_hs_conn *conn,
rc = ble_hs_att_fill_info(
&req,
ble_hs_att_tx_buf + BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ,
- conn->bhc_att_mtu - BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ,
+ ble_l2cap_chan_mtu(chan) - BLE_HS_ATT_FIND_INFO_RSP_MIN_SZ,
&rsp_sz,
&rsp.bhafp_format);
if (rc != 0) {
@@ -527,8 +536,8 @@ ble_hs_att_tx_read_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
}
/* Vol. 3, part F, 3.2.9; don't send more than ATT_MTU-1 bytes of data. */
- if (attr_len > conn->bhc_att_mtu - 1) {
- data_len = conn->bhc_att_mtu - 1;
+ if (attr_len > ble_l2cap_chan_mtu(chan) - 1) {
+ data_len = ble_l2cap_chan_mtu(chan) - 1;
} else {
data_len = attr_len;
}
@@ -695,6 +704,7 @@ ble_hs_att_create_chan(void)
}
chan->blc_cid = BLE_L2CAP_CID_ATT;
+ chan->blc_default_mtu = BLE_HS_ATT_MTU_DFLT;
chan->blc_rx_fn = ble_hs_att_rx;
return chan;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_hs_att.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_att.h b/net/nimble/host/src/ble_hs_att.h
index 0323baa..b8b5fe4 100644
--- a/net/nimble/host/src/ble_hs_att.h
+++ b/net/nimble/host/src/ble_hs_att.h
@@ -17,11 +17,13 @@
#ifndef H_BLE_HS_ATT_
#define H_BLE_HS_ATT_
-#define BLE_HS_ATT_MTU_DFLT 23
+#define BLE_HS_ATT_MTU_DFLT 23 /* Also the minimum. */
#define BLE_HS_ATT_MTU_MAX 256 /* XXX: I'm making this up! */
-#define BLE_HS_ATT_ERR_INVALID_HANDLE 0x01
-#define BLE_HS_ATT_ERR_ATTR_NOT_FOUND 0x0a
+#define BLE_HS_ATT_ERR_INVALID_HANDLE 0x01
+#define BLE_HS_ATT_ERR_REQ_NOT_SUPPORTED 0x06
+#define BLE_HS_ATT_ERR_ATTR_NOT_FOUND 0x0a
+#define BLE_HS_ATT_ERR_INSUFFICIENT_RES 0x11
struct ble_hs_att_entry;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 23f218d..18fd05c 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -39,8 +39,6 @@ ble_hs_conn_alloc(void)
goto err;
}
- conn->bhc_att_mtu = BLE_HS_ATT_MTU_DFLT;
-
SLIST_INIT(&conn->bhc_channels);
chan = ble_hs_att_create_chan();
@@ -114,6 +112,20 @@ ble_hs_conn_first(void)
return SLIST_FIRST(&ble_hs_conns);
}
+struct ble_l2cap_chan *
+ble_hs_conn_chan_find(struct ble_hs_conn *conn, uint16_t cid)
+{
+ struct ble_l2cap_chan *chan;
+
+ SLIST_FOREACH(chan, &conn->bhc_channels, blc_next) {
+ if (chan->blc_cid == cid) {
+ return chan;
+ }
+ }
+
+ return NULL;
+}
+
int
ble_hs_conn_init(void)
{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index deb5879..ceb10c3 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -21,17 +21,19 @@
#include "ble_l2cap.h"
struct hci_le_conn_complete;
struct hci_create_conn;
+struct ble_l2cap_chan;
-struct ble_hs_conn *ble_host_find_connection(uint16_t con_handle);
+typedef uint8_t ble_hs_conn_flags;
+#define BLE_HS_CONN_F_CLIENT 0x01
struct ble_hs_conn {
SLIST_ENTRY(ble_hs_conn) bhc_next;
uint16_t bhc_handle;
- int bhc_fd; // XXX Temporary.
- uint16_t bhc_att_mtu;
uint8_t bhc_addr[BLE_DEV_ADDR_LEN];
struct ble_l2cap_chan_list bhc_channels;
+
+ ble_hs_conn_flags bhc_flags;
};
struct ble_hs_conn *ble_hs_conn_alloc(void);
@@ -40,6 +42,8 @@ void ble_hs_conn_insert(struct ble_hs_conn *conn);
void ble_hs_conn_remove(struct ble_hs_conn *conn);
struct ble_hs_conn *ble_hs_conn_find(uint16_t con_handle);
struct ble_hs_conn *ble_hs_conn_first(void);
+struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
+ uint16_t cid);
int ble_hs_conn_init(void);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_l2cap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c
index 6ec8b10..9accbb8 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -67,6 +67,23 @@ ble_l2cap_chan_free(struct ble_l2cap_chan *chan)
assert(rc == 0);
}
+uint16_t
+ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan)
+{
+ uint16_t mtu;
+
+ /* If either side has not exchanged MTU size, use the default. Otherwise,
+ * use the lesser of the two exchanged values.
+ */
+ if (chan->blc_my_mtu == 0 || chan->blc_peer_mtu == 0) {
+ mtu = chan->blc_default_mtu;
+ } else {
+ mtu = min(chan->blc_my_mtu, chan->blc_peer_mtu);
+ }
+
+ return mtu;
+}
+
int
ble_l2cap_parse_hdr(void *pkt, uint16_t len, struct ble_l2cap_hdr *l2cap_hdr)
{
@@ -112,20 +129,6 @@ ble_l2cap_write_hdr(void *dst, uint16_t len,
return 0;
}
-struct ble_l2cap_chan *
-ble_l2cap_chan_find(struct ble_hs_conn *conn, uint16_t cid)
-{
- struct ble_l2cap_chan *chan;
-
- SLIST_FOREACH(chan, &conn->bhc_channels, blc_next) {
- if (chan->blc_cid == cid) {
- return chan;
- }
- }
-
- return NULL;
-}
-
/**
* If the specified pointer points to null, this function attempts to allocate
* an mbuf from the l2cap mbuf pool and assigns the result to the pointer. No
@@ -200,7 +203,7 @@ ble_l2cap_rx(struct ble_hs_conn *conn,
return EMSGSIZE;
}
- chan = ble_l2cap_chan_find(conn, l2cap_hdr.blh_cid);
+ chan = ble_hs_conn_chan_find(conn, l2cap_hdr.blh_cid);
if (chan == NULL) {
return ENOENT;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/ble_l2cap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap.h b/net/nimble/host/src/ble_l2cap.h
index 300cd69..c2d0f08 100644
--- a/net/nimble/host/src/ble_l2cap.h
+++ b/net/nimble/host/src/ble_l2cap.h
@@ -47,6 +47,9 @@ struct ble_l2cap_chan
{
SLIST_ENTRY(ble_l2cap_chan) blc_next;
uint16_t blc_cid;
+ uint16_t blc_my_mtu; /* 0 if not exchanged. */
+ uint16_t blc_peer_mtu; /* 0 if not exchanged. */
+ uint16_t blc_default_mtu;
struct os_mbuf *blc_rx_buf;
struct os_mbuf *blc_tx_buf;
@@ -60,8 +63,7 @@ SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan);
struct ble_l2cap_chan *ble_l2cap_chan_alloc(void);
void ble_l2cap_chan_free(struct ble_l2cap_chan *chan);
-struct ble_l2cap_chan *ble_l2cap_chan_find(struct ble_hs_conn *conn,
- uint16_t cid);
+uint16_t ble_l2cap_chan_mtu(struct ble_l2cap_chan *chan);
int ble_l2cap_parse_hdr(void *pkt, uint16_t len,
struct ble_l2cap_hdr *l2cap_hdr);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/test/ble_hs_att_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_att_test.c b/net/nimble/host/src/test/ble_hs_att_test.c
index d267a6d..6b3c493 100644
--- a/net/nimble/host/src/test/ble_hs_att_test.c
+++ b/net/nimble/host/src/test/ble_hs_att_test.c
@@ -214,7 +214,7 @@ TEST_CASE(ble_hs_att_test_read)
conn = ble_hs_conn_find(2);
TEST_ASSERT_FATAL(conn != NULL);
- chan = ble_l2cap_chan_find(conn, BLE_L2CAP_CID_ATT);
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
TEST_ASSERT_FATAL(chan != NULL);
/*** Nonexistent attribute. */
@@ -277,7 +277,7 @@ TEST_CASE(ble_hs_att_test_write)
conn = ble_hs_conn_find(2);
TEST_ASSERT_FATAL(conn != NULL);
- chan = ble_l2cap_chan_find(conn, BLE_L2CAP_CID_ATT);
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
TEST_ASSERT_FATAL(chan != NULL);
/*** Nonexistent attribute. */
@@ -332,11 +332,12 @@ TEST_CASE(ble_hs_att_test_find_info)
conn = ble_hs_conn_find(2);
TEST_ASSERT_FATAL(conn != NULL);
- chan = ble_l2cap_chan_find(conn, BLE_L2CAP_CID_ATT);
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
TEST_ASSERT_FATAL(chan != NULL);
/* Increase the MTU to 128 bytes to allow testing of long responses. */
- conn->bhc_att_mtu = 128;
+ chan->blc_my_mtu = 128;
+ chan->blc_peer_mtu = 128;
/*** Start handle of 0. */
req.bhafq_op = BLE_HS_ATT_OP_FIND_INFO_REQ;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/126f083e/net/nimble/host/src/test/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_conn_test.c b/net/nimble/host/src/test/ble_hs_conn_test.c
index e1e4108..8b709d4 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -32,6 +32,7 @@
TEST_CASE(ble_hs_conn_test_master_direct_success)
{
struct hci_le_conn_complete evt;
+ struct ble_l2cap_chan *chan;
struct ble_hs_conn *conn;
uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
int rc;
@@ -65,8 +66,13 @@ TEST_CASE(ble_hs_conn_test_master_direct_success)
conn = ble_hs_conn_first();
TEST_ASSERT_FATAL(conn != NULL);
TEST_ASSERT(conn->bhc_handle == 2);
- TEST_ASSERT(conn->bhc_att_mtu == BLE_HS_ATT_MTU_DFLT);
TEST_ASSERT(memcmp(conn->bhc_addr, addr, 6) == 0);
+
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+ TEST_ASSERT_FATAL(chan != NULL);
+ TEST_ASSERT(chan->blc_my_mtu == 0);
+ TEST_ASSERT(chan->blc_peer_mtu == 0);
+ TEST_ASSERT(chan->blc_default_mtu == BLE_HS_ATT_MTU_DFLT);
}
TEST_CASE(ble_hs_conn_test_master_direct_hci_errors)
@@ -112,6 +118,7 @@ TEST_CASE(ble_hs_conn_test_master_direct_hci_errors)
TEST_CASE(ble_hs_conn_test_slave_direct_success)
{
struct hci_le_conn_complete evt;
+ struct ble_l2cap_chan *chan;
struct ble_hs_conn *conn;
uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
int rc;
@@ -154,8 +161,13 @@ TEST_CASE(ble_hs_conn_test_slave_direct_success)
conn = ble_hs_conn_first();
TEST_ASSERT_FATAL(conn != NULL);
TEST_ASSERT(conn->bhc_handle == 2);
- TEST_ASSERT(conn->bhc_att_mtu == BLE_HS_ATT_MTU_DFLT);
TEST_ASSERT(memcmp(conn->bhc_addr, addr, 6) == 0);
+
+ chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+ TEST_ASSERT_FATAL(chan != NULL);
+ TEST_ASSERT(chan->blc_my_mtu == 0);
+ TEST_ASSERT(chan->blc_peer_mtu == 0);
+ TEST_ASSERT(chan->blc_default_mtu == BLE_HS_ATT_MTU_DFLT);
}
TEST_SUITE(conn_suite)