Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/NimBLECharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,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 @@ -321,13 +322,15 @@ bool NimBLECharacteristic::sendValue(const uint8_t* value, size_t length, bool i
return true;
} // sendValue

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

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

/**
Expand Down Expand Up @@ -374,7 +377,7 @@ 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) {
void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default");
} // onRead

Expand All @@ -383,7 +386,7 @@ void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic
* @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) {
void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default");
} // onWrite

Expand Down
9 changes: 5 additions & 4 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 @@ -248,8 +249,8 @@ class NimBLECharacteristic : public NimBLELocalValueAttribute {
class NimBLECharacteristicCallbacks {
public:
virtual ~NimBLECharacteristicCallbacks() {}
virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args);
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
19 changes: 12 additions & 7 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_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL

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

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

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

void NimBLEDescriptor::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) {
setValue(val, len);
m_pCallbacks->onWrite(this, connInfo);
void NimBLEDescriptor::writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
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

Expand All @@ -143,7 +148,7 @@ void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor, NimBLEConn
* @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) {
void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEWriteEventArgs& args) {
NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default");
} // onWrite

Expand Down
11 changes: 6 additions & 5 deletions src/NimBLEDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
#include "nimconfig.h"
#if CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_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 @@ -66,8 +67,8 @@ class NimBLEDescriptor : public NimBLELocalValueAttribute {
class NimBLEDescriptorCallbacks {
public:
virtual ~NimBLEDescriptorCallbacks() = default;
virtual void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
virtual void onWrite(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo);
virtual void onRead(NimBLEDescriptor* pDescriptor, NimBLEConnInfo& connInfo, NimBLEReadEventArgs& args);
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"
#if CONFIG_BT_ENABLED
# ifdef ESP_PLATFORM
Expand Down Expand Up @@ -66,11 +68,18 @@ class NimBLEL2CAPServer;

# if CONFIG_BT_NIMBLE_ROLE_PERIPHERAL || CONFIG_BT_NIMBLE_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_ENABLED && CONFIG_BT_NIMBLE_ROLE_BROADCASTER && CONFIG_BT_NIMBLE_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 CONFIG_BT_NIMBLE_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
Loading