Skip to content

Commit 293a9cd

Browse files
committed
Fix Jira 588 - BLE Corrupted Long Write
1. Modify the BLECharacteristic to implement the Long write feature.
1 parent c5b6840 commit 293a9cd

File tree

5 files changed

+125
-6
lines changed

5 files changed

+125
-6
lines changed

libraries/CurieBLE/src/BLEAttribute.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ class BLEAttribute {
7474
void *buf, uint16_t len,
7575
uint16_t offset);
7676

77+
friend ssize_t profile_longwrite_process(struct bt_conn *conn,
78+
const struct bt_gatt_attr *attr,
79+
const void *buf, uint16_t len,
80+
uint16_t offset);
81+
friend int profile_longflush_process(struct bt_conn *conn,
82+
const struct bt_gatt_attr *attr,
83+
uint8_t flags);
84+
7785
BLEAttribute(const char* uuid, enum BLEAttributeType type);
7886

7987
BLEAttributeType type(void) const;

libraries/CurieBLE/src/BLECharacteristic.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,20 @@ BLECharacteristic::BLECharacteristic(const char* uuid,
3939
const unsigned short maxLength) :
4040
BLEAttribute(uuid, BLETypeCharacteristic),
4141
_value_length(0),
42+
_value_buffer(NULL),
4243
_written(false),
4344
_user_description(NULL),
4445
_presentation_format(NULL),
4546
_attr_chrc_declaration(NULL),
4647
_attr_chrc_value(NULL),
4748
_attr_cccd(NULL)
4849
{
49-
_value_size = maxLength > BLE_MAX_ATTR_DATA_LEN ? BLE_MAX_ATTR_DATA_LEN : maxLength;
50+
_value_size = maxLength > BLE_MAX_ATTR_LONGDATA_LEN ? BLE_MAX_ATTR_LONGDATA_LEN : maxLength;
5051
_value = (unsigned char*)malloc(_value_size);
52+
if (_value_size > BLE_MAX_ATTR_DATA_LEN)
53+
{
54+
_value_buffer = (unsigned char*)malloc(_value_size);
55+
}
5156

5257
memset(&_ccc_cfg, 0, sizeof(_ccc_cfg));
5358
memset(&_ccc_value, 0, sizeof(_ccc_value));
@@ -403,4 +408,32 @@ bool BLECharacteristic::write(BLEPeripheralHelper &peripheral,
403408
return (0 == retval);
404409
}
405410

411+
void BLECharacteristic::setBuffer(BLEHelper& blehelper,
412+
const uint8_t value[],
413+
uint16_t length,
414+
uint16_t offset)
415+
{
416+
if (length + offset > _value_size) {
417+
// Ignore the data
418+
return;
419+
}
420+
421+
memcpy(_value_buffer + offset, value, length);
422+
}
423+
424+
void BLECharacteristic::syncupBuffer2Value(BLEHelper& blehelper)
425+
{
426+
setValue(blehelper, _value_buffer, _value_size);
427+
}
428+
429+
void BLECharacteristic::discardBuffer()
430+
{
431+
memcpy(_value_buffer, _value, _value_size);
432+
}
433+
434+
bool BLECharacteristic::longCharacteristic()
435+
{
436+
return (_value_size > BLE_MAX_ATTR_DATA_LEN);
437+
}
438+
406439

libraries/CurieBLE/src/BLECharacteristic.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,27 @@ class BLECharacteristic : public BLEAttribute {
201201

202202
protected:
203203
friend class BLEProfile;
204+
friend int profile_longflush_process(struct bt_conn *conn,
205+
const struct bt_gatt_attr *attr,
206+
uint8_t flags);
207+
friend ssize_t profile_longwrite_process(struct bt_conn *conn,
208+
const struct bt_gatt_attr *attr,
209+
const void *buf, uint16_t len,
210+
uint16_t offset);
204211

205212
void addCharacteristicDeclaration(bt_gatt_attr_t *gatt_attr);
206213
void addCharacteristicValue(bt_gatt_attr_t *gatt_attr);
207214
void addCharacteristicConfigDescriptor(bt_gatt_attr_t *gatt_attr);
208215

216+
bool longCharacteristic();
217+
218+
void setBuffer(BLEHelper& blehelper,
219+
const uint8_t value[],
220+
uint16_t length,
221+
uint16_t offset);
222+
void discardBuffer();
223+
void syncupBuffer2Value(BLEHelper& blehelper);
224+
209225
/**
210226
* @brief Get the characteristic value handle
211227
*
@@ -297,6 +313,7 @@ class BLECharacteristic : public BLEAttribute {
297313
unsigned short _value_size;
298314
unsigned short _value_length;
299315
unsigned char* _value;
316+
unsigned char* _value_buffer;
300317
bool _written;
301318

302319
uint16_t _value_handle;

libraries/CurieBLE/src/BLECommon.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
* but this involves splitting it across multiple packets. For simplicity,
4343
* we will just limit this to 20 bytes for now, which will fit in a single packet
4444
*/
45-
#define BLE_MAX_ATTR_DATA_LEN 20
45+
#define BLE_MAX_ATTR_DATA_LEN 20
46+
#define BLE_MAX_ATTR_LONGDATA_LEN 512
4647

4748
/* Default device name prefix, applied only if user does not provide a name
4849
* If a factory-configured MAC address is defined, the last 2 bytes of the

libraries/CurieBLE/src/BLEProfile.cpp

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,56 @@ ssize_t profile_write_process(bt_conn_t *conn,
7171
return len;
7272
}
7373

74+
ssize_t profile_longwrite_process(struct bt_conn *conn,
75+
const struct bt_gatt_attr *attr,
76+
const void *buf, uint16_t len,
77+
uint16_t offset)
78+
{
79+
pr_info(LOG_MODULE_BLE, "%s1", __FUNCTION__);
80+
BLEAttribute *bleattr = (BLEAttribute *)attr->user_data;
81+
BLECharacteristic* blecharacteritic;
82+
BLEAttributeType type = bleattr->type();
83+
BLECentralHelper central = BLEPeripheralRole::instance()->central();
84+
if (BLETypeCharacteristic != type)
85+
{
86+
return 0;
87+
}
88+
89+
blecharacteritic = (BLECharacteristic*)bleattr;
90+
blecharacteritic->setBuffer(*((BLEHelper *)&central), (const uint8_t *) buf, len, offset);
91+
92+
return len;
93+
}
94+
95+
int profile_longflush_process(struct bt_conn *conn,
96+
const struct bt_gatt_attr *attr,
97+
uint8_t flags)
98+
{
99+
BLEAttribute *bleattr = (BLEAttribute *)attr->user_data;
100+
BLECharacteristic* blecharacteritic;
101+
BLEAttributeType type = bleattr->type();
102+
BLECentralHelper central = BLEPeripheralRole::instance()->central();
103+
if (BLETypeCharacteristic != type)
104+
{
105+
return 0;
106+
}
107+
108+
blecharacteritic = (BLECharacteristic*)bleattr;
109+
110+
switch (flags) {
111+
case BT_GATT_FLUSH_DISCARD:
112+
/* Discard buffer reseting it back with data */
113+
blecharacteritic->discardBuffer();
114+
return 0;
115+
case BT_GATT_FLUSH_SYNC:
116+
/* Sync buffer to data */
117+
blecharacteritic->syncupBuffer2Value(*((BLEHelper *)&central));
118+
return 0;
119+
}
120+
121+
return -EINVAL;
122+
}
123+
74124

75125
// Only for central
76126
uint8_t profile_notify_process (bt_conn_t *conn,
@@ -227,11 +277,21 @@ BLEProfile::addAttribute (BLEAttribute& attribute)
227277
memset(start, 0, sizeof(bt_gatt_attr_t));
228278
start->uuid = characteritic->uuid();
229279
start->perm = characteritic->getPermission();
230-
start->read = profile_read_process;
231-
start->write = profile_write_process;
232280
start->user_data = (void*)&attribute;
233281
characteritic->addCharacteristicValue(start);
282+
start->read = profile_read_process;
234283

284+
if (characteritic->longCharacteristic() == false)
285+
{
286+
// Normal characteristic MAX. 20
287+
start->write = profile_write_process;
288+
}
289+
else
290+
{
291+
// Long characteristic. MAX. 512
292+
start->write = profile_longwrite_process;
293+
start->flush = profile_longflush_process;
294+
}
235295
pr_info(LOG_MODULE_BLE, "desc-%p, uuid: 0x%x", start, ((bt_uuid_16_t*) start->uuid)->val);
236296

237297
start++;
@@ -333,8 +393,8 @@ void BLEProfile::descriptorDiscoverRsp(const bt_gatt_attr_t *attr, BLEAttribute*
333393
//CCCD
334394
bt_gatt_attr_t *attr_chrc = attr_dec + 1;
335395
bt_gatt_attr_t *attr_cccd = attr_dec + 2;
336-
bt_gatt_subscribe_params_t *sub_param_tmp = chrc->getSubscribeParams();
337-
bt_gatt_subscribe_params_t *sub_param = _sub_param + _sub_param_idx;
396+
bt_gatt_subscribe_params_t *sub_param_tmp = chrc->getSubscribeParams();
397+
bt_gatt_subscribe_params_t *sub_param = _sub_param + _sub_param_idx;
338398
bt_conn_t *conn = bt_conn_lookup_addr_le(_peripheral->bt_le_address());
339399
if (NULL == conn)
340400
{

0 commit comments

Comments
 (0)