You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2016/08/11 21:27:47 UTC

[47/50] [abbrv] incubator-mynewt-core git commit: BLE Host - Send correct error code for unsup. n/i.

BLE Host - Send correct error code for unsup. n/i.

Previously, if a peer attempted to enable notifications or indications
for a characteristic that did not support them, the elicited error
response had an error code of 3 (BLE_ATT_ERR_WRITE_NOT_PERMITTED).

Now, the error response has a code of 6 (BLE_ATT_ERR_REQ_NOT_SUPPORTED).

The spec does not appear to indicate the correct error t osend in this
case.  I believe req-not-supported is more correct than
write-not-permitted.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/a2e20c8b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a2e20c8b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a2e20c8b

Branch: refs/heads/phyrx_no_mbuf
Commit: a2e20c8bb7c228de16dd2df2d77c1d896a6b4e61
Parents: 0008660
Author: Christopher Collins <cc...@apache.org>
Authored: Thu Aug 11 13:31:37 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Aug 11 14:26:27 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_gatts.c                 |  2 +-
 net/nimble/host/src/test/ble_att_svr_test.c     | 98 ++++++-------------
 .../host/src/test/ble_gatts_notify_test.c       | 99 +++++++++++++++++++-
 net/nimble/host/src/test/ble_hs_test_util.c     | 39 ++++++++
 net/nimble/host/src/test/ble_hs_test_util.h     |  3 +
 5 files changed, 167 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a2e20c8b/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 4bdc6c7..e6ff203 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -662,7 +662,7 @@ ble_gatts_clt_cfg_access_locked(struct ble_hs_conn *conn, uint16_t attr_handle,
 
         flags = le16toh(om->om_data);
         if ((flags & ~clt_cfg->allowed) != 0) {
-            return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
+            return BLE_ATT_ERR_REQ_NOT_SUPPORTED;
         }
 
         if (clt_cfg->flags != flags) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a2e20c8b/net/nimble/host/src/test/ble_att_svr_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_att_svr_test.c b/net/nimble/host/src/test/ble_att_svr_test.c
index 1509b41..d8dfb27 100644
--- a/net/nimble/host/src/test/ble_att_svr_test.c
+++ b/net/nimble/host/src/test/ble_att_svr_test.c
@@ -343,29 +343,6 @@ ble_att_svr_test_misc_verify_w_2(void *data, int data_len)
 }
 
 static void
-ble_att_svr_test_misc_verify_tx_err_rsp(uint8_t req_op, uint16_t handle,
-                                        uint8_t error_code)
-{
-    struct ble_att_error_rsp rsp;
-    struct os_mbuf *om;
-    uint8_t buf[BLE_ATT_ERROR_RSP_SZ];
-    int rc;
-
-    ble_hs_test_util_tx_all();
-
-    om = ble_hs_test_util_prev_tx_dequeue();
-
-    rc = os_mbuf_copydata(om, 0, sizeof buf, buf);
-    TEST_ASSERT(rc == 0);
-
-    ble_att_error_rsp_parse(buf, sizeof buf, &rsp);
-
-    TEST_ASSERT(rsp.baep_req_op == req_op);
-    TEST_ASSERT(rsp.baep_handle == handle);
-    TEST_ASSERT(rsp.baep_error_code == error_code);
-}
-
-static void
 ble_att_svr_test_misc_verify_tx_read_blob_rsp(uint8_t *attr_data, int attr_len)
 {
     struct os_mbuf *om;
@@ -481,23 +458,6 @@ ble_att_svr_test_misc_verify_all_read_mult(
                                                   attrs, num_attrs);
 }
 
-
-static void
-ble_att_svr_test_misc_verify_tx_write_rsp(void)
-{
-    struct os_mbuf *om;
-    uint8_t u8;
-    int rc;
-
-    ble_hs_test_util_tx_all();
-
-    om = ble_hs_test_util_prev_tx_dequeue();
-
-    rc = os_mbuf_copydata(om, 0, 1, &u8);
-    TEST_ASSERT(rc == 0);
-    TEST_ASSERT(u8 == BLE_ATT_OP_WRITE_RSP);
-}
-
 static void
 ble_att_svr_test_misc_verify_tx_mtu_rsp(uint16_t conn_handle)
 {
@@ -845,7 +805,7 @@ ble_att_svr_test_misc_prep_write(uint16_t conn_handle, uint16_t attr_handle,
                                                        data, data_len);
     } else {
         TEST_ASSERT(rc != 0);
-        ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_PREP_WRITE_REQ,
+        ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_PREP_WRITE_REQ,
                                                 attr_handle, error_code);
     }
 }
@@ -869,7 +829,7 @@ ble_att_svr_test_misc_exec_write(uint16_t conn_handle, uint8_t flags,
         ble_att_svr_test_misc_verify_tx_exec_write_rsp();
     } else {
         TEST_ASSERT(rc != 0);
-        ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_EXEC_WRITE_REQ,
+        ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_EXEC_WRITE_REQ,
                                                 error_handle, error_code);
     }
 }
@@ -1022,7 +982,7 @@ TEST_CASE(ble_att_svr_test_read)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, 0,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ, 0,
                                             BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Successful read. */
@@ -1066,7 +1026,7 @@ TEST_CASE(ble_att_svr_test_read)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc == BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN));
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_REQ,
                                             req.barq_handle,
                                             BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
 
@@ -1114,7 +1074,7 @@ TEST_CASE(ble_att_svr_test_read_blob)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_BLOB_REQ, 0,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_BLOB_REQ, 0,
                                             BLE_ATT_ERR_INVALID_HANDLE);
 
 
@@ -1198,7 +1158,7 @@ TEST_CASE(ble_att_svr_test_read_mult)
     /*** Single nonexistent attribute. */
     ble_att_svr_test_misc_rx_read_mult_req(
         conn_handle, ((uint16_t[]){ 100 }), 1, 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
                                             100, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Single attribute. */
@@ -1213,7 +1173,7 @@ TEST_CASE(ble_att_svr_test_read_mult)
     /*** Second attribute nonexistent; verify only error txed. */
     ble_att_svr_test_misc_rx_read_mult_req(
         conn_handle, ((uint16_t[]){ attrs[0].handle, 100 }), 2, 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_READ_MULT_REQ,
                                             100, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Response too long; verify only MTU bytes sent. */
@@ -1256,7 +1216,7 @@ TEST_CASE(ble_att_svr_test_write)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_WRITE_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Write not permitted if non-local. */
@@ -1272,7 +1232,7 @@ TEST_CASE(ble_att_svr_test_write)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc == BLE_HS_ENOTSUP);
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
                                             req.bawq_handle,
                                             BLE_ATT_ERR_WRITE_NOT_PERMITTED);
 
@@ -1296,7 +1256,7 @@ TEST_CASE(ble_att_svr_test_write)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_write_rsp();
+    ble_hs_test_util_verify_tx_write_rsp();
 
     /*** Write requires encryption. */
     /* Insufficient authentication. */
@@ -1312,7 +1272,7 @@ TEST_CASE(ble_att_svr_test_write)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc == BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN));
-    ble_att_svr_test_misc_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
+    ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
                                             req.bawq_handle,
                                             BLE_ATT_ERR_INSUFFICIENT_AUTHEN);
 
@@ -1333,7 +1293,7 @@ TEST_CASE(ble_att_svr_test_write)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc == 0);
-    ble_att_svr_test_misc_verify_tx_write_rsp();
+    ble_hs_test_util_verify_tx_write_rsp();
 }
 
 TEST_CASE(ble_att_svr_test_find_info)
@@ -1363,7 +1323,7 @@ TEST_CASE(ble_att_svr_test_find_info)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_INFO_REQ, 0, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** Start handle > end handle. */
@@ -1375,7 +1335,7 @@ TEST_CASE(ble_att_svr_test_find_info)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_INFO_REQ, 101, BLE_ATT_ERR_INVALID_HANDLE);
 
     /*** No attributes. */
@@ -1387,7 +1347,7 @@ TEST_CASE(ble_att_svr_test_find_info)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** Range too late. */
@@ -1403,7 +1363,7 @@ TEST_CASE(ble_att_svr_test_find_info)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_INFO_REQ, 200, BLE_ATT_ERR_ATTR_NOT_FOUND);
 
     /*** One 128-bit entry. */
@@ -1530,7 +1490,7 @@ TEST_CASE(ble_att_svr_test_find_type_value)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1543,7 +1503,7 @@ TEST_CASE(ble_att_svr_test_find_type_value)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1556,7 +1516,7 @@ TEST_CASE(ble_att_svr_test_find_type_value)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
@@ -1573,7 +1533,7 @@ TEST_CASE(ble_att_svr_test_find_type_value)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_FIND_TYPE_VALUE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
@@ -1712,7 +1672,7 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_TYPE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1727,7 +1687,7 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_TYPE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1742,7 +1702,7 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_TYPE_REQ, 1,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
@@ -1758,7 +1718,7 @@ ble_att_svr_test_misc_read_type(uint16_t mtu)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_TYPE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
@@ -1924,7 +1884,7 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_GROUP_TYPE_REQ, 0,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1939,7 +1899,7 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_GROUP_TYPE_REQ, 101,
         BLE_ATT_ERR_INVALID_HANDLE);
 
@@ -1953,7 +1913,7 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_GROUP_TYPE_REQ, 110,
         BLE_ATT_ERR_UNSUPPORTED_GROUP);
 
@@ -1968,7 +1928,7 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_GROUP_TYPE_REQ, 1,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 
@@ -1984,7 +1944,7 @@ TEST_CASE(ble_att_svr_test_read_group_type)
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
     TEST_ASSERT(rc != 0);
-    ble_att_svr_test_misc_verify_tx_err_rsp(
+    ble_hs_test_util_verify_tx_err_rsp(
         BLE_ATT_OP_READ_GROUP_TYPE_REQ, 200,
         BLE_ATT_ERR_ATTR_NOT_FOUND);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a2e20c8b/net/nimble/host/src/test/ble_gatts_notify_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gatts_notify_test.c b/net/nimble/host/src/test/ble_gatts_notify_test.c
index 4516e66..4e2d587 100644
--- a/net/nimble/host/src/test/ble_gatts_notify_test.c
+++ b/net/nimble/host/src/test/ble_gatts_notify_test.c
@@ -127,9 +127,9 @@ ble_gatts_notify_test_misc_read_notify(uint16_t conn_handle,
 }
 
 static void
-ble_gatts_notify_test_misc_enable_notify(uint16_t conn_handle,
-                                         uint16_t chr_def_handle,
-                                         uint16_t flags)
+ble_gatts_notify_test_misc_try_enable_notify(uint16_t conn_handle,
+                                             uint16_t chr_def_handle,
+                                             uint16_t flags, int fail)
 {
     struct ble_att_write_req req;
     uint8_t buf[BLE_ATT_WRITE_REQ_BASE_SZ + 2];
@@ -141,7 +141,25 @@ ble_gatts_notify_test_misc_enable_notify(uint16_t conn_handle,
     htole16(buf + BLE_ATT_WRITE_REQ_BASE_SZ, flags);
     rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
                                                 buf, sizeof buf);
-    TEST_ASSERT(rc == 0);
+    if (fail) {
+        TEST_ASSERT_FATAL(rc != 0);
+        ble_hs_test_util_verify_tx_err_rsp(BLE_ATT_OP_WRITE_REQ,
+                                           req.bawq_handle,
+                                           BLE_ATT_ERR_REQ_NOT_SUPPORTED);
+    } else {
+        TEST_ASSERT_FATAL(rc == 0);
+        ble_hs_test_util_verify_tx_write_rsp();
+    }
+}
+
+static void
+ble_gatts_notify_test_misc_enable_notify(uint16_t conn_handle,
+                                         uint16_t chr_def_handle,
+                                         uint16_t flags)
+{
+    ble_gatts_notify_test_misc_try_enable_notify(conn_handle,
+                                                 chr_def_handle,
+                                                 flags, 0);
 }
 
 static void
@@ -956,6 +974,77 @@ TEST_CASE(ble_gatts_notify_test_bonded_i_no_ack)
     TEST_ASSERT(!value_cccd.value_changed);
 }
 
+TEST_CASE(ble_gatts_notify_test_disallowed)
+{
+    uint16_t chr1_val_handle;
+    uint16_t chr2_val_handle;
+    uint16_t chr3_val_handle;
+    int rc;
+
+    const struct ble_gatt_svc_def svcs[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(1),
+            .access_cb = ble_gatts_notify_test_misc_access,
+            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
+            .val_handle = &chr1_val_handle,
+        }, {
+            .uuid128 = BLE_UUID16(2),
+            .access_cb = ble_gatts_notify_test_misc_access,
+            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE,
+            .val_handle = &chr2_val_handle,
+        }, {
+            .uuid128 = BLE_UUID16(3),
+            .access_cb = ble_gatts_notify_test_misc_access,
+            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY |
+                     BLE_GATT_CHR_F_INDICATE,
+            .val_handle = &chr3_val_handle,
+        }, {
+            0
+        } },
+    }, {
+        0
+    } };
+
+    ble_hs_test_util_init();
+
+    rc = ble_gatts_register_svcs(svcs, NULL, NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT_FATAL(chr1_val_handle != 0);
+    TEST_ASSERT_FATAL(chr2_val_handle != 0);
+    TEST_ASSERT_FATAL(chr3_val_handle != 0);
+
+    ble_gatts_start();
+
+    ble_hs_test_util_create_conn(2, ble_gatts_notify_test_peer_addr,
+                                 ble_gatts_notify_test_util_gap_event, NULL);
+
+    /* Attempt to enable notifications on chr1 should succeed. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr1_val_handle - 1, BLE_GATTS_CLT_CFG_F_NOTIFY, 0);
+
+    /* Attempt to enable indications on chr1 should fail. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr1_val_handle - 1, BLE_GATTS_CLT_CFG_F_INDICATE, 1);
+
+    /* Attempt to enable notifications on chr2 should fail. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr2_val_handle - 1, BLE_GATTS_CLT_CFG_F_NOTIFY, 1);
+
+    /* Attempt to enable indications on chr2 should succeed. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr2_val_handle - 1, BLE_GATTS_CLT_CFG_F_INDICATE, 0);
+
+    /* Attempt to enable notifications on chr3 should succeed. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr3_val_handle - 1, BLE_GATTS_CLT_CFG_F_NOTIFY, 0);
+
+    /* Attempt to enable indications on chr3 should succeed. */
+    ble_gatts_notify_test_misc_try_enable_notify(
+        2, chr3_val_handle - 1, BLE_GATTS_CLT_CFG_F_INDICATE, 0);
+}
+
 TEST_SUITE(ble_gatts_notify_suite)
 {
     tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
@@ -968,6 +1057,8 @@ TEST_SUITE(ble_gatts_notify_suite)
 
     ble_gatts_notify_test_bonded_i_no_ack();
 
+    ble_gatts_notify_test_disallowed();
+
     /* XXX: Test corner cases:
      *     o Bonding after CCCD configuration.
      *     o Disconnect prior to rx of indicate ack.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a2e20c8b/net/nimble/host/src/test/ble_hs_test_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c
index 30926b6..b5148e3 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -1133,6 +1133,45 @@ ble_hs_test_util_verify_tx_read_blob_rsp(uint8_t *attr_data, int attr_len)
 }
 
 void
+ble_hs_test_util_verify_tx_write_rsp(void)
+{
+    struct os_mbuf *om;
+    uint8_t u8;
+    int rc;
+
+    ble_hs_test_util_tx_all();
+
+    om = ble_hs_test_util_prev_tx_dequeue();
+
+    rc = os_mbuf_copydata(om, 0, 1, &u8);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(u8 == BLE_ATT_OP_WRITE_RSP);
+}
+
+void
+ble_hs_test_util_verify_tx_err_rsp(uint8_t req_op, uint16_t handle,
+                                   uint8_t error_code)
+{
+    struct ble_att_error_rsp rsp;
+    struct os_mbuf *om;
+    uint8_t buf[BLE_ATT_ERROR_RSP_SZ];
+    int rc;
+
+    ble_hs_test_util_tx_all();
+
+    om = ble_hs_test_util_prev_tx_dequeue();
+
+    rc = os_mbuf_copydata(om, 0, sizeof buf, buf);
+    TEST_ASSERT(rc == 0);
+
+    ble_att_error_rsp_parse(buf, sizeof buf, &rsp);
+
+    TEST_ASSERT(rsp.baep_req_op == req_op);
+    TEST_ASSERT(rsp.baep_handle == handle);
+    TEST_ASSERT(rsp.baep_error_code == error_code);
+}
+
+void
 ble_hs_test_util_set_static_rnd_addr(void)
 {
     uint8_t addr[6] = { 1, 2, 3, 4, 5, 0xc1 };

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a2e20c8b/net/nimble/host/src/test/ble_hs_test_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_test_util.h b/net/nimble/host/src/test/ble_hs_test_util.h
index 3320e9b..fa3b5e0 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.h
+++ b/net/nimble/host/src/test/ble_hs_test_util.h
@@ -142,6 +142,9 @@ void ble_hs_test_util_verify_tx_exec_write(uint8_t expected_flags);
 void ble_hs_test_util_verify_tx_read_rsp(uint8_t *attr_data, int attr_len);
 void ble_hs_test_util_verify_tx_read_blob_rsp(uint8_t *attr_data,
                                               int attr_len);
+void ble_hs_test_util_verify_tx_write_rsp(void);
+void ble_hs_test_util_verify_tx_err_rsp(uint8_t req_op, uint16_t handle,
+                                        uint8_t error_code);
 void ble_hs_test_util_set_static_rnd_addr(void);
 struct os_mbuf *ble_hs_test_util_om_from_flat(const void *buf, uint16_t len);
 int ble_hs_test_util_flat_attr_cmp(const struct ble_hs_test_util_flat_attr *a,