diff --git a/examples/NimBLE_Server/main/main.cpp b/examples/NimBLE_Server/main/main.cpp index 01a95517..e76958c5 100644 --- a/examples/NimBLE_Server/main/main.cpp +++ b/examples/NimBLE_Server/main/main.cpp @@ -68,14 +68,14 @@ class ServerCallbacks : public NimBLEServerCallbacks { /** Handler class for characteristic actions */ class CharacteristicCallbacks : public NimBLECharacteristicCallbacks { - NimBLEGattStatus onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override { + uint8_t onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) override { printf("%s : onRead(), value: %s\n", pCharacteristic->getUUID().toString().c_str(), pCharacteristic->getValue().c_str()); return NimBLEGattStatus::Success; } - NimBLEGattStatus onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override { + uint8_t onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override { printf("%s : onWrite(), value: %s\n", pCharacteristic->getUUID().toString().c_str(), value.c_str()); @@ -112,12 +112,12 @@ class CharacteristicCallbacks : public NimBLECharacteristicCallbacks { /** Handler class for descriptor actions */ class DescriptorCallbacks : public NimBLEDescriptorCallbacks { - NimBLEGattStatus onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override { + uint8_t onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override { printf("Descriptor written value: %s\n", value.c_str()); return NimBLEGattStatus::Success; } - NimBLEGattStatus onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override { + uint8_t onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) override { printf("%s Descriptor read\n", pDescriptor->getUUID().toString().c_str()); return NimBLEGattStatus::Success; } diff --git a/src/NimBLECharacteristic.cpp b/src/NimBLECharacteristic.cpp index 995e9b16..e256203b 100644 --- a/src/NimBLECharacteristic.cpp +++ b/src/NimBLECharacteristic.cpp @@ -425,7 +425,7 @@ void NimBLECharacteristic::updatePeerStatus(const NimBLEConnInfo& peerInfo) cons * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @return The status of the read operation. */ -NimBLEGattStatus NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo) { +uint8_t NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo) { return m_pCallbacks->onRead(this, connInfo); } // readEvent @@ -435,8 +435,8 @@ NimBLEGattStatus NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo) { * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @return The status of the write operation. */ -NimBLEGattStatus NimBLECharacteristic::writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) { - NimBLEGattStatus rc = m_pCallbacks->onWrite(this, val, connInfo); +uint8_t NimBLECharacteristic::writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) { + uint8_t rc = m_pCallbacks->onWrite(this, val, connInfo); if (rc == NimBLEGattStatus::Success) { m_value = std::move(val); } @@ -492,7 +492,7 @@ std::string NimBLECharacteristic::toString() const { * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @return The status of the read operation, NimBLEGattStatus::Success if the read is accepted, or an error code otherwise. */ -NimBLEGattStatus NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { +uint8_t NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) { NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default"); return NimBLEGattStatus::Success; } // onRead @@ -502,14 +502,18 @@ NimBLEGattStatus NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCh * @param [in] pCharacteristic The characteristic that is the source of the event. * @param [in] value The value being written to the characteristic. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. - * @return The status of the write operation, NimBLEGattStatus::Success if the write is accepted, or an error code otherwise. - * @details If the write is rejected, the characteristic's value will not be updated, otherwise it will be updated with the new value. - * The value parameter contains the new value being written to the characteristic, it can be modified by the callback if needed. - * WARNING: Modifying the value parameter directly affects the value being written to the characteristic, - * if the max length of the value is modified, such as by assigning another value with a different max length, i.e. value = NimBLEAttValue(); - * it will change the max length used for the characteristic's value. + * @return The status of the write operation, NimBLEGattStatus::Success if the write is accepted, or an error code + * otherwise. + * @details If the write is rejected, the characteristic's value will not be updated, otherwise it will be updated with + * the new value. The value parameter contains the new value being written to the characteristic, it can be modified by + * the callback if needed. + * WARNING: Modifying the value parameter directly affects the value being written to the + * characteristic, if the max length of the value is modified, such as by assigning another value with a different max + * length, i.e. value = NimBLEAttValue(); it will change the max length used for the characteristic's value. */ -NimBLEGattStatus NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo) { +uint8_t NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, + NimBLEAttValue& value, + NimBLEConnInfo& connInfo) { NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default"); return NimBLEGattStatus::Success; } // onWrite diff --git a/src/NimBLECharacteristic.h b/src/NimBLECharacteristic.h index 0045064a..f81c2dde 100644 --- a/src/NimBLECharacteristic.h +++ b/src/NimBLECharacteristic.h @@ -272,13 +272,13 @@ class NimBLECharacteristic : public NimBLELocalValueAttribute { friend class NimBLEServer; friend class NimBLEService; - void setService(NimBLEService* pService); - NimBLEGattStatus readEvent(NimBLEConnInfo& connInfo) override; - NimBLEGattStatus writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) override; - bool sendValue(const uint8_t* value, - size_t length, - bool is_notification = true, - uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const; + void setService(NimBLEService* pService); + uint8_t readEvent(NimBLEConnInfo& connInfo) override; + uint8_t writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) override; + bool sendValue(const uint8_t* value, + size_t length, + bool is_notification = true, + uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const; struct SubPeerEntry { enum : uint8_t { AWAITING_SECURE = 1 << 0, SECURE = 1 << 1, SUB_NOTIFY = 1 << 2, SUB_INDICATE = 1 << 3 }; @@ -319,10 +319,10 @@ class NimBLECharacteristic : public NimBLELocalValueAttribute { class NimBLECharacteristicCallbacks { public: virtual ~NimBLECharacteristicCallbacks() {} - virtual NimBLEGattStatus onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo); - virtual NimBLEGattStatus onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo); - virtual void onStatus(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, int code); - virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue); + virtual uint8_t onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo); + virtual uint8_t onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo); + virtual void onStatus(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, int code); + virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue); }; #endif // CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL) diff --git a/src/NimBLEDescriptor.cpp b/src/NimBLEDescriptor.cpp index ef10e889..2e85c617 100644 --- a/src/NimBLEDescriptor.cpp +++ b/src/NimBLEDescriptor.cpp @@ -124,12 +124,12 @@ std::string NimBLEDescriptor::toString() const { return res; } // toString -NimBLEGattStatus NimBLEDescriptor::readEvent(NimBLEConnInfo& connInfo) { +uint8_t NimBLEDescriptor::readEvent(NimBLEConnInfo& connInfo) { return m_pCallbacks->onRead(this, connInfo); } // readEvent -NimBLEGattStatus NimBLEDescriptor::writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) { - NimBLEGattStatus rc = m_pCallbacks->onWrite(this, val, connInfo); +uint8_t NimBLEDescriptor::writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) { + uint8_t rc = m_pCallbacks->onWrite(this, val, connInfo); if (rc == NimBLEGattStatus::Success) { m_value = std::move(val); } @@ -142,7 +142,7 @@ NimBLEGattStatus NimBLEDescriptor::writeEvent(NimBLEAttValue& val, NimBLEConnInf * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @return The status of the read operation, NimBLEGattStatus::Success if the read is accepted, or an error code otherwise. */ -NimBLEGattStatus NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) { +uint8_t NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) { NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default"); return NimBLEGattStatus::Success; } // onRead @@ -152,14 +152,16 @@ NimBLEGattStatus NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor * @param [in] pDescriptor The descriptor that is the source of the event. * @param [in] value The value being written to the descriptor. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. - * @return The status of the write operation, NimBLEGattStatus::Success if the write is accepted, or an error code otherwise. - * @details If the write is rejected, the descriptor's value will not be updated, otherwise it will be updated with the new value. - * The value parameter contains the new value being written to the descriptor, it can be modified by the callback if needed. - * WARNING: Modifying the value parameter directly affects the value being written to the descriptor, - * if the max length of the value is modified, such as by assigning another value with a different max length, i.e. value = NimBLEAttValue(); - * it will change the max length used for the descriptor's value. + * @return The status of the write operation, NimBLEGattStatus::Success if the write is accepted, or an error code + * otherwise. + * @details If the write is rejected, the descriptor's value will not be updated, otherwise it will be updated with the + * new value. The value parameter contains the new value being written to the descriptor, it can be modified by the + * callback if needed. + * WARNING: Modifying the value parameter directly affects the value being written to the + * descriptor, if the max length of the value is modified, such as by assigning another value with a different max + * length, i.e. value = NimBLEAttValue(); it will change the max length used for the descriptor's value. */ -NimBLEGattStatus NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo) { +uint8_t NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo) { NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default"); return NimBLEGattStatus::Success; } // onWrite diff --git a/src/NimBLEDescriptor.h b/src/NimBLEDescriptor.h index 67de9a1d..bef6f30d 100644 --- a/src/NimBLEDescriptor.h +++ b/src/NimBLEDescriptor.h @@ -51,8 +51,8 @@ class NimBLEDescriptor : public NimBLELocalValueAttribute { friend class NimBLEService; void setCharacteristic(NimBLECharacteristic* pChar); - NimBLEGattStatus readEvent(NimBLEConnInfo& connInfo) override; - NimBLEGattStatus writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) override; + uint8_t readEvent(NimBLEConnInfo& connInfo) override; + uint8_t writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) override; NimBLEDescriptorCallbacks* m_pCallbacks{nullptr}; NimBLECharacteristic* m_pCharacteristic{nullptr}; @@ -68,8 +68,8 @@ class NimBLEDescriptor : public NimBLELocalValueAttribute { class NimBLEDescriptorCallbacks { public: virtual ~NimBLEDescriptorCallbacks() = default; - virtual NimBLEGattStatus onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo); - virtual NimBLEGattStatus onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo); + virtual uint8_t onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo); + virtual uint8_t onWrite(NimBLEDescriptor* pDescriptor, NimBLEAttValue& value, NimBLEConnInfo& connInfo); }; # include "NimBLE2904.h" diff --git a/src/NimBLELocalValueAttribute.h b/src/NimBLELocalValueAttribute.h index e8712c24..ed673ebc 100644 --- a/src/NimBLELocalValueAttribute.h +++ b/src/NimBLELocalValueAttribute.h @@ -52,7 +52,10 @@ typedef enum { INDICATE = BLE_GATT_CHR_F_INDICATE } NIMBLE_PROPERTY; -enum class NimBLEGattStatus : uint8_t { +// Status codes are scoped to the namespace (NimBLEGattStatus::Success) and convert implicitly to uint8_t and int. +// Callbacks return uint8_t so any value, including application-defined 0x80-0x9F, can be returned. +namespace NimBLEGattStatus { +enum : uint8_t { // Standard GATT Success State Success = 0x00, @@ -75,7 +78,7 @@ enum class NimBLEGattStatus : uint8_t { UnsupportedGroupType = 0x10, ///< The attribute type is not a supported grouping attribute. InsufficientResources = 0x11, ///< Temporary failure due to lack of device resources (RAM/buffers). DatabaseOutOfSync = 0x12, ///< The database is out of sync. - ValueNotAllowed = 0x13, ///< The parameter value written is outside the valid ranges of that application profile. + ValueNotAllowed = 0x13, ///< The parameter value written is outside the valid ranges of that application profile. // ------------------------------------------------------------------------- // User / Application Defined Errors (0x80 - 0x9F) @@ -93,6 +96,7 @@ enum class NimBLEGattStatus : uint8_t { AppErrorMax = 0x9F ///< Maximum boundary for custom application-specific errors. }; +} // namespace NimBLEGattStatus class NimBLEConnInfo; @@ -155,18 +159,20 @@ class NimBLELocalValueAttribute : public NimBLELocalAttribute, public NimBLEValu * @brief Callback function to support a read request. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @details This function is called by NimBLEServer when a read request is received. - * @return NimBLEGattStatus::Success or other error code to reject the read. + * @return GATT status code (uint8_t). + * @details the Enum NimBLEGattStatus defines the standard GATT status codes. Custom status codes can also be used. */ - virtual NimBLEGattStatus readEvent(NimBLEConnInfo& connInfo) = 0; + virtual uint8_t readEvent(NimBLEConnInfo& connInfo) = 0; /** * @brief Callback function to support a write request. * @param [in] val The value to write. * @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info. * @details This function is called by NimBLEServer when a write request is received. - * @return NimBLEGattStatus::Success or other error code to reject the write. + * @return GATT status code (uint8_t). + * @details the Enum NimBLEGattStatus defines the standard GATT status codes. Custom status codes can also be used. */ - virtual NimBLEGattStatus writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) = 0; + virtual uint8_t writeEvent(NimBLEAttValue& val, NimBLEConnInfo& connInfo) = 0; /** * @brief Get a reference to value of the attribute. diff --git a/src/NimBLEServer.cpp b/src/NimBLEServer.cpp index 26cebfc3..b51cfa47 100644 --- a/src/NimBLEServer.cpp +++ b/src/NimBLEServer.cpp @@ -751,13 +751,14 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_ // Don't call readEvent if the buffer len is 0 (this is a follow up to a previous read), // or if this is an internal read (handle is NONE) if (ctxt->om->om_len > 0 && connHandle != BLE_HS_CONN_HANDLE_NONE) { - NimBLEGattStatus status = pAtt->readEvent(peerInfo); + uint8_t status = pAtt->readEvent(peerInfo); if (status != NimBLEGattStatus::Success) { return static_cast(status); } } NimBLEAttValue::Lock lock; + int rc = os_mbuf_append(ctxt->om, val.data(), val.size()); return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } @@ -783,11 +784,11 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_ return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; } buf.append(next->om_data, next->om_len); - len += next->om_len; + len += next->om_len; if (buf.size() != len) { return BLE_ATT_ERR_INSUFFICIENT_RES; } - next = SLIST_NEXT(next, om_next); + next = SLIST_NEXT(next, om_next); } return static_cast(pAtt->writeEvent(buf, peerInfo)); diff --git a/src/NimBLEStream.cpp b/src/NimBLEStream.cpp index ac3e06eb..614f3d4e 100644 --- a/src/NimBLEStream.cpp +++ b/src/NimBLEStream.cpp @@ -817,9 +817,9 @@ bool NimBLEStreamServer::ready() const { * @return The user callback status, or success if no user callback is set. * @details Received data is pushed into the RX buffer only if the user callback succeeds. */ -NimBLEGattStatus NimBLEStreamServer::ChrCallbacks::onWrite(NimBLECharacteristic* pChr, NimBLEAttValue& value, NimBLEConnInfo& connInfo) { +uint8_t NimBLEStreamServer::ChrCallbacks::onWrite(NimBLECharacteristic* pChr, NimBLEAttValue& value, NimBLEConnInfo& connInfo) { if (m_userCallbacks) { - NimBLEGattStatus status = m_userCallbacks->onWrite(pChr, value, connInfo); + uint8_t status = m_userCallbacks->onWrite(pChr, value, connInfo); if (status != NimBLEGattStatus::Success) { return status; } diff --git a/src/NimBLEStream.h b/src/NimBLEStream.h index bf40e45e..d5dbc097 100644 --- a/src/NimBLEStream.h +++ b/src/NimBLEStream.h @@ -172,7 +172,7 @@ class NimBLEStreamServer : public NimBLEStream { struct ChrCallbacks : public NimBLECharacteristicCallbacks { ChrCallbacks(NimBLEStreamServer* parent) : m_parent(parent), m_userCallbacks(nullptr), m_peerHandle(BLE_HS_CONN_HANDLE_NONE) {} - NimBLEGattStatus onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override; + uint8_t onWrite(NimBLECharacteristic* pCharacteristic, NimBLEAttValue& value, NimBLEConnInfo& connInfo) override; void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue) override; void onStatus(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, int code) override;