Skip to content

Commit

Permalink
nimble/host: add eatt opcode check in ble_eatt_l2cap_event_fn
Browse files Browse the repository at this point in the history
Att opcode check caused l2cap disconnection when opcode included
in received data was write command which is supported and can be used
on eatt. Also, the comment seemed irrelevant. Fixes GATT/SR/GAW/BV-01-C
  • Loading branch information
piotrnarajowski committed Oct 1, 2024
1 parent caecb2c commit 1cf68d3
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 8 deletions.
45 changes: 45 additions & 0 deletions nimble/host/src/ble_att.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,51 @@ ble_att_create_chan(uint16_t conn_handle)
return chan;
}

bool
ble_eatt_supported_op(uint8_t opcode)
{
switch (opcode) {
case BLE_ATT_OP_WRITE_CMD:
case BLE_ATT_OP_FIND_INFO_REQ:
case BLE_ATT_OP_FIND_TYPE_VALUE_REQ:
case BLE_ATT_OP_READ_TYPE_REQ:
case BLE_ATT_OP_READ_REQ:
case BLE_ATT_OP_READ_BLOB_REQ:
case BLE_ATT_OP_READ_MULT_REQ:
case BLE_ATT_OP_READ_GROUP_TYPE_REQ:
case BLE_ATT_OP_WRITE_REQ:
case BLE_ATT_OP_PREP_WRITE_REQ:
case BLE_ATT_OP_EXEC_WRITE_REQ:
case BLE_ATT_OP_INDICATE_REQ:
case BLE_ATT_OP_READ_MULT_VAR_REQ:
case BLE_ATT_OP_NOTIFY_MULTI_REQ:
return true;
}
return false;
}

bool
ble_eatt_supported_rsp(uint8_t opcode)
{
switch (opcode) {
case BLE_ATT_OP_ERROR_RSP:
case BLE_ATT_OP_FIND_INFO_RSP:
case BLE_ATT_OP_FIND_TYPE_VALUE_RSP:
case BLE_ATT_OP_READ_TYPE_RSP:
case BLE_ATT_OP_INDICATE_RSP:
case BLE_ATT_OP_READ_RSP:
case BLE_ATT_OP_READ_BLOB_RSP:
case BLE_ATT_OP_READ_MULT_RSP:
case BLE_ATT_OP_READ_GROUP_TYPE_RSP:
case BLE_ATT_OP_WRITE_RSP:
case BLE_ATT_OP_PREP_WRITE_RSP:
case BLE_ATT_OP_EXEC_WRITE_RSP:
case BLE_ATT_OP_READ_MULT_VAR_RSP:
return true;
}
return false;
}

bool
ble_att_is_request_op(uint8_t opcode)
{
Expand Down
2 changes: 2 additions & 0 deletions nimble/host/src/ble_att_cmd_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ int ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
struct os_mbuf *txom);
bool ble_att_is_response_op(uint8_t opcode);
bool ble_att_is_request_op(uint8_t opcode);
bool ble_eatt_supported_op(uint8_t opcode);
bool ble_eatt_supported_rsp(uint8_t opcode);
#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 9 additions & 8 deletions nimble/host/src/ble_eatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,15 +266,16 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
assert(eatt->chan == event->receive.chan);
opcode = event->receive.sdu_rx->om_data[0];
if (ble_att_is_response_op(opcode)) {
if (ble_eatt_supported_rsp(opcode)) {
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev);
} else if (!ble_att_is_request_op(opcode)) {
/* As per BLE 5.4 Standard, Vol. 3, Part F, section 5.3.2
* (ENHANCED ATT BEARER L2CAP INTEROPERABILITY REQUIREMENTS:
* Channel Requirements):
* All packets sent on this L2CAP channel shall be Attribute PDUs.
*
* Disconnect peer with invalid behavior.
} else if (!ble_eatt_supported_op(opcode)) {
/* If an ATT PDU is supported on any ATT bearer, then it shall be
* supported on all supported ATT bearers with the following
* exceptions:
* • The Exchange MTU sub-procedure shall only be supported on the
* LE Fixed Channel Unenhanced ATT bearer.
* • The Signed Write Without Response sub-procedure shall only be
* supported on the LE Fixed Channel Unenhanced ATT bearer.
*/
ble_l2cap_disconnect(eatt->chan);
return BLE_HS_EREJECT;
Expand Down

0 comments on commit 1cf68d3

Please sign in to comment.