diff --git a/nimble/host/src/ble_att.c b/nimble/host/src/ble_att.c index 5e221824c..f5d758852 100644 --- a/nimble/host/src/ble_att.c +++ b/nimble/host/src/ble_att.c @@ -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) { diff --git a/nimble/host/src/ble_att_cmd_priv.h b/nimble/host/src/ble_att_cmd_priv.h index 78c60d5ef..2fc7aed03 100644 --- a/nimble/host/src/ble_att_cmd_priv.h +++ b/nimble/host/src/ble_att_cmd_priv.h @@ -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 diff --git a/nimble/host/src/ble_eatt.c b/nimble/host/src/ble_eatt.c index c15f545b6..bf88f4cc5 100644 --- a/nimble/host/src/ble_eatt.c +++ b/nimble/host/src/ble_eatt.c @@ -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;