nimble/att: Fix response for unknown opcode

Fixes MYNEWT-886

With this patch if unknown ATT request come to ATT channel, Nimble
replies with ATT Error Response with error code Request Not Supported.

That should fix GATT/SR/UNS/BI-01-C

X-Original-Commit: 768633db326ebb8596181cb563028bca2f38d2ef
This commit is contained in:
Łukasz Rymanowski
2018-01-17 09:19:22 +01:00
parent 714d4d2a25
commit 17a663eb0d
4 changed files with 52 additions and 2 deletions
+21 -1
View File
@@ -461,6 +461,22 @@ ble_att_chan_mtu(const struct ble_l2cap_chan *chan)
return mtu;
}
static void
ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle,
struct os_mbuf **om)
{
/* If this is command (bit6 is set to 1), do nothing */
if (op & 0x40) {
return;
}
os_mbuf_adj(*om, OS_MBUF_PKTLEN(*om));
ble_att_svr_tx_error_rsp(conn_handle, *om, op, 0,
BLE_ATT_ERR_REQ_NOT_SUPPORTED);
*om = NULL;
}
static int
ble_att_rx(struct ble_l2cap_chan *chan)
{
@@ -485,7 +501,8 @@ ble_att_rx(struct ble_l2cap_chan *chan)
entry = ble_att_rx_dispatch_entry_find(op);
if (entry == NULL) {
return BLE_HS_EINVAL;
ble_att_rx_handle_unknown_request(op, conn_handle, om);
return BLE_HS_ENOTSUP;
}
ble_att_inc_rx_stat(op);
@@ -495,6 +512,9 @@ ble_att_rx(struct ble_l2cap_chan *chan)
rc = entry->bde_fn(conn_handle, om);
if (rc != 0) {
if (rc == BLE_HS_ENOTSUP) {
ble_att_rx_handle_unknown_request(op, conn_handle, om);
}
return rc;
}
+3
View File
@@ -222,6 +222,9 @@ int ble_att_svr_init(void);
void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle);
void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom,
uint8_t req_op, uint16_t handle,
uint8_t error_code);
/*** $clt */
/** An information-data entry in a find information response. */
+1 -1
View File
@@ -573,7 +573,7 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle,
return 0;
}
static int
int
ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom,
uint8_t req_op, uint16_t handle, uint8_t error_code)
{
+27
View File
@@ -2052,6 +2052,32 @@ TEST_CASE(ble_att_svr_test_oom)
TEST_ASSERT_FATAL(rc == 0);
}
TEST_CASE(ble_att_svr_test_unsupported_req)
{
uint16_t conn_handle;
int rc;
uint8_t buf[] = {0x3f, 0x00, 0x00, 0x01, 0x02, 0x03};
conn_handle = ble_att_svr_test_misc_init(0);
/* Put handle into buf */
(*(uint16_t *)&buf[1]) = htole16(conn_handle);
rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
buf, sizeof buf);
TEST_ASSERT(rc != 0);
ble_hs_test_util_verify_tx_err_rsp(0x3f, 0,
BLE_ATT_ERR_REQ_NOT_SUPPORTED);
/* Check for no response when unknown command is sent */
buf[0] = 0x4f;
rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
buf, sizeof buf);
TEST_ASSERT(rc != 0);
/* Ensure no response sent. */
TEST_ASSERT(ble_hs_test_util_prev_tx_dequeue() == NULL);
}
TEST_SUITE(ble_att_svr_suite)
{
/* When checking for mbuf leaks, ensure no stale prep entries. */
@@ -2077,6 +2103,7 @@ TEST_SUITE(ble_att_svr_suite)
ble_att_svr_test_notify();
ble_att_svr_test_indicate();
ble_att_svr_test_oom();
ble_att_svr_test_unsupported_req();
}
int