Skip to content

Commit

Permalink
add write method for returning the num of bytes transferred
Browse files Browse the repository at this point in the history
  • Loading branch information
fabik111 committed Sep 23, 2024
1 parent 29bef40 commit e358f2d
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 12 deletions.
26 changes: 26 additions & 0 deletions src/BLECharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,32 @@ int BLECharacteristic::readValue(int32_t& value)
return readValue((uint8_t*)&value, sizeof(value));
}

int BLECharacteristic::write(const char* value, bool withResponse)
{
if (_local) {
return _local->write(value);
}

if (_remote) {
return _remote->write(value, withResponse);
}

return 0;
}

int BLECharacteristic::write(const uint8_t value[], int length, bool withResponse)
{
if (_local) {
return _local->write(value, length);
}

if (_remote) {
return _remote->write(value, length, withResponse);
}

return 0;
}

int BLECharacteristic::writeValue(const uint8_t value[], int length, bool withResponse)
{
if (_local) {
Expand Down
3 changes: 3 additions & 0 deletions src/BLECharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ class BLECharacteristic {
int writeValue(int16_t value, bool withResponse = true);
int writeValue(uint32_t value, bool withResponse = true);
int writeValue(int32_t value, bool withResponse = true);
int write(const uint8_t value[], int length, bool withResponse = true);
int write(const char* value, bool withResponse = true);


// deprecated, use writeValue(...)
int setValue(const uint8_t value[], int length) { return writeValue(value, length); }
Expand Down
45 changes: 43 additions & 2 deletions src/local/BLELocalCharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ int BLELocalCharacteristic::writeValue(const uint8_t value[], int length)
}

if ((_properties & BLEIndicate) && (_cccdValue & 0x0002)) {
return ATT.handleInd(valueHandle(), _value, _valueLength);
return ATT.handleInd(valueHandle(), _value,&_valueLength);
} else if ((_properties & BLENotify) && (_cccdValue & 0x0001)) {
return ATT.handleNotify(valueHandle(), _value, _valueLength);
return ATT.handleNotify(valueHandle(), _value, &_valueLength);
}

if (_broadcast) {
Expand All @@ -142,6 +142,47 @@ int BLELocalCharacteristic::writeValue(const char* value)
return writeValue((uint8_t*)value, strlen(value));
}

int BLELocalCharacteristic::write(const uint8_t value[], int length)
{
_valueLength = min(length, _valueSize);
memcpy(_value, value, _valueLength);

if (_fixedLength) {
_valueLength = _valueSize;
}

if ((_properties & BLEIndicate) && (_cccdValue & 0x0002)) {
uint8_t res = ATT.handleInd(valueHandle(), _value, &_valueLength);
if (res != 1){
return res;
}
return _valueLength;
} else if ((_properties & BLENotify) && (_cccdValue & 0x0001)) {
uint8_t res = ATT.handleNotify(valueHandle(), _value, &_valueLength);
if (res != 1){
return res;
}
return _valueLength;
}

if (_broadcast) {
uint16_t serviceUuid = GATT.serviceUuidForCharacteristic(this);

BLE.setAdvertisedServiceData(serviceUuid, value, length);

if (!ATT.connected() && GAP.advertising()) {
BLE.advertise();
}
}

return _valueLength;
}

int BLELocalCharacteristic::write(const char* value)
{
return write((uint8_t*)value, strlen(value));
}

int BLELocalCharacteristic::broadcast()
{
if (_properties & BLEBroadcast) {
Expand Down
2 changes: 2 additions & 0 deletions src/local/BLELocalCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class BLELocalCharacteristic : public BLELocalAttribute {

int writeValue(const uint8_t value[], int length);
int writeValue(const char* value);
int write(const uint8_t value[], int length);
int write(const char* value);

int broadcast();

Expand Down
53 changes: 53 additions & 0 deletions src/remote/BLERemoteCharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,59 @@ uint8_t BLERemoteCharacteristic::operator[] (int offset) const
return 0;
}

int BLERemoteCharacteristic::write(const uint8_t value[], int length, bool withResponse)
{
if (!ATT.connected(_connectionHandle)) {
return false;
}

uint16_t maxLength = ATT.mtu(_connectionHandle) - 3;

if (length > (int)maxLength) {
// cap to MTU max length
length = maxLength;
}

_value = (uint8_t*)realloc(_value, length);
if (_value == NULL) {
// realloc failed
return 0;
}

if ((_properties & BLEWrite) && withResponse) {
uint8_t resp[4];
int respLength = ATT.writeReq(_connectionHandle, _valueHandle, value, length, resp);

if (!respLength) {
return 0;
}

if (resp[0] == 0x01) {
// error
return 0;
}

memcpy(_value, value, length);
_valueLength = length;

return length;
} else if (_properties & BLEWriteWithoutResponse) {
ATT.writeCmd(_connectionHandle, _valueHandle, value, length);

memcpy(_value, value, length);
_valueLength = length;

return length;
}

return 0;
}

int BLERemoteCharacteristic::write(const char* value, bool withResponse)
{
return write((uint8_t*)value, strlen(value), withResponse);
}

int BLERemoteCharacteristic::writeValue(const uint8_t value[], int length, bool withResponse)
{
if (!ATT.connected(_connectionHandle)) {
Expand Down
2 changes: 2 additions & 0 deletions src/remote/BLERemoteCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class BLERemoteCharacteristic : public BLERemoteAttribute {

int writeValue(const uint8_t value[], int length, bool withResponse = true);
int writeValue(const char* value, bool withResponse = true);
int write(const uint8_t value[], int length, bool withResponse = true);
int write(const char* value, bool withResponse = true);

bool valueUpdated();
bool updatedValueRead();
Expand Down
17 changes: 9 additions & 8 deletions src/utility/ATT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ BLEDevice ATTClass::central()
return BLEDevice();
}

bool ATTClass::handleNotify(uint16_t handle, const uint8_t* value, int length)
bool ATTClass::handleNotify(uint16_t handle, const uint8_t* value, uint16_t *length)
{
int numNotifications = 0;

Expand All @@ -600,9 +600,9 @@ bool ATTClass::handleNotify(uint16_t handle, const uint8_t* value, int length)
memcpy(&notification[1], &handle, sizeof(handle));
notificationLength += sizeof(handle);

length = min((uint16_t)(_peers[i].mtu - notificationLength), (uint16_t)length);
memcpy(&notification[notificationLength], value, length);
notificationLength += length;
*length = min((uint16_t)(_peers[i].mtu - notificationLength), *length);
memcpy(&notification[notificationLength], value, *length);
notificationLength += *length;

/// TODO: Set encryption requirement on notify.
HCI.sendAclPkt(_peers[i].connectionHandle, ATT_CID, notificationLength, notification);
Expand All @@ -613,7 +613,7 @@ bool ATTClass::handleNotify(uint16_t handle, const uint8_t* value, int length)
return (numNotifications > 0);
}

bool ATTClass::handleInd(uint16_t handle, const uint8_t* value, int length)
bool ATTClass::handleInd(uint16_t handle, const uint8_t* value, uint16_t *length)
{
int numIndications = 0;

Expand All @@ -631,9 +631,10 @@ bool ATTClass::handleInd(uint16_t handle, const uint8_t* value, int length)
memcpy(&indication[1], &handle, sizeof(handle));
indicationLength += sizeof(handle);

length = min((uint16_t)(_peers[i].mtu - indicationLength), (uint16_t)length);
memcpy(&indication[indicationLength], value, length);
indicationLength += length;
*length = min((uint16_t)(_peers[i].mtu - indicationLength), *length);

memcpy(&indication[indicationLength], value, *length);
indicationLength += *length;

_cnf = false;

Expand Down
4 changes: 2 additions & 2 deletions src/utility/ATT.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ class ATTClass {

virtual BLEDevice central();

virtual bool handleNotify(uint16_t handle, const uint8_t* value, int length);
virtual bool handleInd(uint16_t handle, const uint8_t* value, int length);
virtual bool handleNotify(uint16_t handle, const uint8_t* value, uint16_t *length);
virtual bool handleInd(uint16_t handle, const uint8_t* value, uint16_t *length);

virtual void setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler);

Expand Down

0 comments on commit e358f2d

Please sign in to comment.