Skip to content
Open
24 changes: 20 additions & 4 deletions src/NimBLECharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# include "NimBLE2904.h"
# include "NimBLEDevice.h"
# include "NimBLELog.h"
# include "NimBLELocalValueAttribute.h"

static NimBLECharacteristicCallbacks defaultCallback;
static const char* LOG_TAG = "NimBLECharacteristic";
Expand Down Expand Up @@ -328,13 +329,17 @@ bool NimBLECharacteristic::sendValue(const uint8_t* value, size_t length, bool i
return true;
} // sendValue

void NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo) {
void NimBLECharacteristic::readEvent(NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) {
m_pCallbacks->onRead(this, connInfo);
m_pCallbacks->onRead(this, connInfo, args);
} // readEvent

void NimBLECharacteristic::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) {
setValue(val, len);
void NimBLECharacteristic::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
m_pCallbacks->onWrite(this, connInfo);
m_pCallbacks->onWrite(this, connInfo, args);
if(!args.isCanceled()) {
setValue(val, len);
}
} // writeEvent

/**
Expand Down Expand Up @@ -381,9 +386,21 @@ std::string NimBLECharacteristic::toString() const {
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
} // onRead

void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
} // onRead
/**
* @brief Callback function to support a write request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
} // onWrite

/**
* @brief Callback function to support a write request.
Expand All @@ -393,7 +410,6 @@ void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
} // onWrite

/**
* @brief Callback function to support a Notify/Indicate Status report.
* @param [in] pCharacteristic The characteristic that is the source of the event.
Expand Down
7 changes: 5 additions & 2 deletions src/NimBLECharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class NimBLEDescriptor;
class NimBLE2904;

# include "NimBLELocalValueAttribute.h"
# include "NimBLEDevice.h"

# include <string>
# include <vector>
Expand Down Expand Up @@ -226,8 +227,8 @@ class NimBLECharacteristic : public NimBLELocalValueAttribute {
friend class NimBLEService;

void setService(NimBLEService* pService);
void readEvent(NimBLEConnInfo& connInfo) override;
void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) override;
void readEvent(NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) override;
void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) override;
bool sendValue(const uint8_t* value,
size_t length,
bool is_notification = true,
Expand All @@ -249,7 +250,9 @@ class NimBLECharacteristicCallbacks {
public:
virtual ~NimBLECharacteristicCallbacks() {}
virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args);
virtual void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args);
virtual void onStatus(NimBLECharacteristic* pCharacteristic, int code);
virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue);
};
Expand Down
1 change: 1 addition & 0 deletions src/NimBLEConnInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#endif

#include "NimBLEAddress.h"
#include "buffer.h"

/**
* @brief Connection information.
Expand Down
34 changes: 29 additions & 5 deletions src/NimBLEDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#include "NimBLEDescriptor.h"
#if CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)

# include "NimBLELocalAttribute.h"
# include "NimBLEValueAttribute.h"
# include "NimBLELocalValueAttribute.h"
# include "NimBLEService.h"
# include "NimBLELog.h"

Expand Down Expand Up @@ -120,24 +123,45 @@ std::string NimBLEDescriptor::toString() const {
return res;
} // toString

void NimBLEDescriptor::readEvent(NimBLEConnInfo& connInfo) {
void NimBLEDescriptor::readEvent(NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) {
m_pCallbacks->onRead(this, connInfo);
m_pCallbacks->onRead(this, connInfo, args);
} // readEvent

void NimBLEDescriptor::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) {
setValue(val, len);
void NimBLEDescriptor::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
m_pCallbacks->onWrite(this, connInfo);
m_pCallbacks->onWrite(this, connInfo, args);
if(!args.isCanceled()) {
setValue(val, len);
}
} // writeEvent

/**
* @brief Callback function to support a read request.
* @param [in] pDescriptor The descriptor that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) {
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
} // onRead


/**
* @brief Callback function to support a read request.
* @param [in] pDescriptor The descriptor that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo) {
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default");
} // onRead
/**
* @brief Callback function to support a write request.
* @param [in] pDescriptor The descriptor that is the source of the event.
* @param [in] connInfo A reference to a NimBLEConnInfo instance containing the peer info.
*/
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
} // onWrite
/**
* @brief Callback function to support a write request.
* @param [in] pDescriptor The descriptor that is the source of the event.
Expand All @@ -147,4 +171,4 @@ void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLECon
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
} // onWrite

#endif // CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
#endif // CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
9 changes: 6 additions & 3 deletions src/NimBLEDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
#include "syscfg/syscfg.h"
#if CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)

# include "NimBLELocalValueAttribute.h"
#include "NimBLELocalValueAttribute.h"
# include "NimBLEDevice.h"
# include <string>

class NimBLECharacteristic;
Expand Down Expand Up @@ -49,8 +50,8 @@ class NimBLEDescriptor : public NimBLELocalValueAttribute {
friend class NimBLEService;

void setCharacteristic(NimBLECharacteristic* pChar);
void readEvent(NimBLEConnInfo& connInfo) override;
void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) override;
void readEvent(NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) override;
void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) override;

NimBLEDescriptorCallbacks* m_pCallbacks{nullptr};
NimBLECharacteristic* m_pCharacteristic{nullptr};
Expand All @@ -67,7 +68,9 @@ class NimBLEDescriptorCallbacks {
public:
virtual ~NimBLEDescriptorCallbacks() = default;
virtual void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
virtual void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args);
virtual void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args);
};

# include "NimBLE2904.h"
Expand Down
9 changes: 9 additions & 0 deletions src/NimBLEDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
* limitations under the License.
*/


#ifndef NIMBLE_CPP_DEVICE_H_
#define NIMBLE_CPP_DEVICE_H_

#include "nimconfig.h"
#include "syscfg/syscfg.h"
#if CONFIG_BT_NIMBLE_ENABLED
# ifdef ESP_PLATFORM
Expand Down Expand Up @@ -66,11 +68,18 @@ class NimBLEL2CAPServer;

# if MYNEWT_VAL(BLE_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_ROLE_CENTRAL)
class NimBLEConnInfo;

class buffer;
class NimBLEReadEventArgs;
class NimBLEWriteEventArgs;

# endif


class NimBLEAddress;
class NimBLEDeviceCallbacks;


# define BLEDevice NimBLEDevice
# define BLEClient NimBLEClient
# define BLERemoteService NimBLERemoteService
Expand Down
66 changes: 66 additions & 0 deletions src/NimBLEEventArgs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// Created by hoeflich on 30.07.2025.
//

#ifndef NIMBLEEVENTS_H
#define NIMBLEEVENTS_H

#if CONFIG_BT_ENABLED && (CONFIG_BT_NIMBLE_ROLE_PERIPHERAL || CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#include "buffer.h"
#include <cstring>
#include <string>

class NimBLEReadEventArgs{
public:
void overwriteReturnValue(const uint8_t* value, int size) {
data = new buffer(size);
std::memcpy(data->getPointer(), value, size);
}

bool isDataOverwritten() const { return data != nullptr; }

buffer* getData() { return data; }

NimBLEReadEventArgs() {}

~NimBLEReadEventArgs() {
if(data != nullptr)
delete data;
}
private:
buffer* data = nullptr;
};

class NimBLEWriteEventArgs{
public:
void Cancel(){
canceled = true;
}

bool isCanceled(){
return canceled;
}

std::string GetOldData(){
return oldData;
}

std::string GetNewData(){
return newData;
}

NimBLEWriteEventArgs(std::string oldData, std::string newData) {
this->oldData = oldData;
this->newData = newData;
}

~NimBLEWriteEventArgs() {
}
private:
std::string oldData;
std::string newData;
bool canceled = false;
};

#endif
#endif //NIMBLEEVENTS_H
1 change: 1 addition & 0 deletions src/NimBLEHIDDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "NimBLEHIDDevice.h"
#if CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_BROADCASTER) && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)

# include "NimBLEDevice.h"
# include "NimBLEServer.h"
# include "NimBLEService.h"
# include "NimBLE2904.h"
Expand Down
5 changes: 3 additions & 2 deletions src/NimBLELocalValueAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef enum {
# include "NimBLEValueAttribute.h"
# include "NimBLEAttValue.h"
# include <vector>
#include "NimBLEEventArgs.h"
class NimBLEConnInfo;

class NimBLELocalValueAttribute : public NimBLELocalAttribute, public NimBLEValueAttribute {
Expand Down Expand Up @@ -113,7 +114,7 @@ class NimBLELocalValueAttribute : public NimBLELocalAttribute, public NimBLEValu
* @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.
*/
virtual void readEvent(NimBLEConnInfo& connInfo) = 0;
virtual void readEvent(NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) = 0;

/**
* @brief Callback function to support a write request.
Expand All @@ -122,7 +123,7 @@ class NimBLELocalValueAttribute : public NimBLELocalAttribute, public NimBLEValu
* @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.
*/
virtual void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) = 0;
virtual void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) = 0;

/**
* @brief Get a pointer to value of the attribute.
Expand Down
21 changes: 17 additions & 4 deletions src/NimBLEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

# include "NimBLEDevice.h"
# include "NimBLELog.h"
#include "NimBLEEventArgs.h"

# if MYNEWT_VAL(BLE_ROLE_CENTRAL)
# include "NimBLEClient.h"
Expand Down Expand Up @@ -631,12 +632,19 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_
case BLE_GATT_ACCESS_OP_READ_CHR: {
// 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)
NimBLEReadEventArgs eventArgs = NimBLEReadEventArgs();
if (ctxt->om->om_len > 0 && connHandle != BLE_HS_CONN_HANDLE_NONE) {
pAtt->readEvent(peerInfo);
pAtt->readEvent(peerInfo, eventArgs);
}

ble_npl_hw_enter_critical();
int rc = os_mbuf_append(ctxt->om, val.data(), val.size());
int rc;
if(eventArgs.isDataOverwritten()) {
auto buffer = eventArgs.getData();
rc = os_mbuf_append(ctxt->om, buffer->getPointer(), buffer->getSize());
} else {
rc = os_mbuf_append(ctxt->om, val.data(), val.size());
}
ble_npl_hw_exit_critical(0);
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
Expand All @@ -652,18 +660,23 @@ int NimBLEServer::handleGattEvent(uint16_t connHandle, uint16_t attrHandle, ble_
uint8_t buf[maxLen];
memcpy(buf, ctxt->om->om_data, len);


os_mbuf* next;
next = SLIST_NEXT(ctxt->om, om_next);
while (next != NULL) {
if ((len + next->om_len) > maxLen) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
memcpy(&buf[len], next->om_data, next->om_len);
memcpy(&buf[len], next->om_data, next->om_len);
len += next->om_len;
next = SLIST_NEXT(next, om_next);
}

pAtt->writeEvent(buf, len, peerInfo);
auto oldData = std::string((char*)pAtt->getValue().data(), pAtt->getValue().length());
auto newData = std::string((char*)buf, len);

NimBLEWriteEventArgs eventArgs = NimBLEWriteEventArgs(oldData, newData);
pAtt->writeEvent(buf, len, peerInfo, eventArgs);
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions src/NimBLEServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

# include <vector>
# include <array>
# include "NimBLEEventArgs.h"

# define NIMBLE_ATT_REMOVE_HIDE 1
# define NIMBLE_ATT_REMOVE_DELETE 2
Expand Down
2 changes: 1 addition & 1 deletion src/NimBLEService.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class NimBLEService;

# include "NimBLEAttribute.h"
# include "NimBLEDevice.h"
# include "NimBLEServer.h"
# include "NimBLECharacteristic.h"

Expand Down
Loading