Skip to content

Commit 9f61eb4

Browse files
committed
feat: added support for PPCP characteristic, binary format for hardware address
1 parent 30e2cac commit 9f61eb4

12 files changed

+158
-14
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
21
.DS_Store
2+
.vscode
3+
.github

src/BLEAdvertisingData.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ BLEAdvertisingData::BLEAdvertisingData() :
2929
_flags(0),
3030
_hasFlags(false),
3131
_localName(NULL),
32+
33+
_minimumConnectionInterval(0),
34+
_maximumConnectionInterval(0),
35+
_hasConnectionInterval(false),
36+
_TransmitPowerLevel(0),
37+
_hasTransmitPowerLevel(false),
38+
3239
_manufacturerData(NULL),
3340
_manufacturerDataLength(0),
3441
_manufacturerCompanyId(0),
@@ -73,6 +80,13 @@ void BLEAdvertisingData::clear()
7380
_rawDataLength = 0;
7481
_hasFlags = false;
7582
_localName = NULL;
83+
84+
_minimumConnectionInterval = 0;
85+
_maximumConnectionInterval = 0;
86+
_hasConnectionInterval = false;
87+
_TransmitPowerLevel = 0;
88+
_hasTransmitPowerLevel = false;
89+
7690
_manufacturerData = NULL;
7791
_manufacturerDataLength = 0;
7892
_hasManufacturerCompanyId = false;
@@ -90,6 +104,13 @@ void BLEAdvertisingData::copy(const BLEAdvertisingData& adv)
90104
_flags = adv._flags;
91105
_hasFlags = adv._hasFlags;
92106
_localName = adv._localName;
107+
108+
_minimumConnectionInterval = adv._minimumConnectionInterval;
109+
_maximumConnectionInterval = adv._maximumConnectionInterval;
110+
_hasConnectionInterval = adv._hasConnectionInterval;
111+
_TransmitPowerLevel = adv._TransmitPowerLevel;
112+
_hasTransmitPowerLevel = adv._hasTransmitPowerLevel;
113+
93114
_manufacturerData = adv._manufacturerData;
94115
_manufacturerDataLength = adv._manufacturerDataLength;
95116
_manufacturerCompanyId = adv._manufacturerCompanyId;
@@ -183,6 +204,29 @@ bool BLEAdvertisingData::setLocalName(const char *localName)
183204
return success;
184205
}
185206

207+
bool BLEAdvertisingData::setAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval)
208+
{
209+
int previousLength = (_hasConnectionInterval) ? ( sizeof(_minimumConnectionInterval) + sizeof(_maximumConnectionInterval) + AD_FIELD_OVERHEAD) : 0;
210+
bool success = updateRemainingLength(previousLength, (sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval) + AD_FIELD_OVERHEAD));
211+
if (success) {
212+
_hasConnectionInterval = true;
213+
_minimumConnectionInterval = minimumConnectionInterval;
214+
_maximumConnectionInterval = maximumConnectionInterval;
215+
}
216+
return success;
217+
}
218+
219+
bool BLEAdvertisingData::setAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel)
220+
{
221+
int previousLength = (_hasTransmitPowerLevel) ? ( sizeof(_TransmitPowerLevel) + AD_FIELD_OVERHEAD) : 0;
222+
bool success = updateRemainingLength(previousLength, (sizeof(TransmitPowerLevel) + AD_FIELD_OVERHEAD));
223+
if (success) {
224+
_hasTransmitPowerLevel = true;
225+
_TransmitPowerLevel = TransmitPowerLevel;
226+
}
227+
return success;
228+
}
229+
186230
bool BLEAdvertisingData::setRawData(const uint8_t* data, int length)
187231
{
188232
if (length > MAX_AD_DATA_LENGTH) {
@@ -248,6 +292,14 @@ bool BLEAdvertisingData::updateData()
248292
if (_localName) {
249293
success &= addLocalName(_localName);
250294
}
295+
// Try to add Slave Connection Interval into the current advertising packet
296+
if (_hasConnectionInterval) {
297+
success &= addAdvertisedConnectionInterval(_minimumConnectionInterval, _maximumConnectionInterval);
298+
}
299+
// Try to add Transmit Power Level into the current advertising packet
300+
if (_hasTransmitPowerLevel) {
301+
success &= addAdvertisedTransmitPowerLevel(_TransmitPowerLevel);
302+
}
251303
return success;
252304
}
253305

@@ -330,6 +382,19 @@ bool BLEAdvertisingData::addFlags(uint8_t flags)
330382
return addField(BLEFieldFlags, &flags, sizeof(flags));
331383
}
332384

385+
bool BLEAdvertisingData::addAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval)
386+
{
387+
uint8_t tempData[sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval)];
388+
memcpy(tempData, &minimumConnectionInterval, sizeof(minimumConnectionInterval));
389+
memcpy(&tempData[sizeof(minimumConnectionInterval)], &maximumConnectionInterval, sizeof(maximumConnectionInterval));
390+
return addField(BLEFieldConnectionInterval, tempData, sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval));
391+
}
392+
393+
bool BLEAdvertisingData::addAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel)
394+
{
395+
return addField(BLEFieldTransmitPowerLevel, &TransmitPowerLevel, sizeof(TransmitPowerLevel));
396+
}
397+
333398
bool BLEAdvertisingData::addField(BLEAdField field, const char* data)
334399
{
335400
int dataLength = strlen(data);

src/BLEAdvertisingData.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ enum BLEAdField {
4040
BLEFieldCompleteAdvertisedService128 = 0x07,
4141
BLEFieldShortLocalName = 0x08,
4242
BLEFieldCompleteLocalName = 0x09,
43+
44+
BLEFieldTransmitPowerLevel = 0x0A,
45+
BLEFieldConnectionInterval = 0x12,
46+
4347
BLEFieldServiceData = 0x16,
4448
BLEFieldManufacturerData = 0xFF,
4549

@@ -66,6 +70,10 @@ class BLEAdvertisingData {
6670
bool setManufacturerData(const uint8_t manufacturerData[], int manufacturerDataLength);
6771
bool setManufacturerData(const uint16_t companyId, const uint8_t manufacturerData[], int manufacturerDataLength);
6872
bool setLocalName(const char *localName);
73+
74+
bool setAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval);
75+
bool setAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel);
76+
6977
bool setAdvertisedServiceData(uint16_t uuid, const uint8_t data[], int length);
7078
bool setRawData(const uint8_t* data, int length);
7179
bool setRawData(const BLEAdvertisingRawData& data);
@@ -86,6 +94,10 @@ class BLEAdvertisingData {
8694
bool addManufacturerData(const uint8_t manufacturerData[], int manufacturerDataLength);
8795
bool addManufacturerData(const uint16_t companyId, const uint8_t manufacturerData[], int manufacturerDataLength);
8896
bool addLocalName(const char *localName);
97+
98+
bool addAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval);
99+
bool addAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel);
100+
89101
bool addAdvertisedServiceData(uint16_t uuid, const uint8_t data[], int length);
90102
bool addRawData(const uint8_t* data, int length);
91103
bool addFlags(uint8_t flags);
@@ -105,6 +117,12 @@ class BLEAdvertisingData {
105117
bool _hasFlags;
106118
const char* _localName;
107119

120+
uint16_t _minimumConnectionInterval;
121+
uint16_t _maximumConnectionInterval;
122+
bool _hasConnectionInterval;
123+
uint8_t _TransmitPowerLevel;
124+
bool _hasTransmitPowerLevel;
125+
108126
const uint8_t* _manufacturerData;
109127
int _manufacturerDataLength;
110128
uint16_t _manufacturerCompanyId;

src/BLEDevice.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ String BLEDevice::address() const
8282
return result;
8383
}
8484

85+
void BLEDevice::address(uint8_t address[6]) const
86+
{
87+
memcpy(address, _address, 6);
88+
}
89+
8590
bool BLEDevice::hasLocalName() const
8691
{
8792
return (localName().length() > 0);

src/BLEDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class BLEDevice {
4949

5050
virtual String address() const;
5151

52+
virtual void address(uint8_t address[6]) const;
53+
5254
bool hasLocalName() const;
5355

5456
bool hasAdvertisedServiceUuid() const;

src/BLEProperty.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,9 @@ enum BLE_GATT_PERM_ {
7575
WRITE_AUTHORIZATION = 1 << 10,
7676
};
7777

78+
#define DEFAULT_PPCP_minimumConnectionInterval 80 /* 100 ms */
79+
#define DEFAULT_PPCP_maximumConnectionInterval 160 /* 200 ms */
80+
#define DEFAULT_PPCP_slaveLatency 0 /* 0 ms */
81+
#define DEFAULT_PPCP_connectionSupervisionTimeout 1000 /* 1000 ms */
7882

7983
#endif

src/local/BLELocalCharacteristic.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,17 @@ void BLELocalCharacteristic::writeValue(BLEDevice device, const uint8_t value[],
223223
{
224224
_written = true;
225225

226+
if (_properties & BLEWriteWithoutResponse) {
227+
_valueLength = min(length, _valueSize);
228+
memcpy(_value, value, _valueLength);
229+
230+
if (_fixedLength) {
231+
_valueLength = _valueSize;
232+
}
233+
}
234+
else {
226235
writeValue(value, length);
236+
}
227237

228238
if (_eventHandlers[BLEWritten]) {
229239
_eventHandlers[BLEWritten](device, BLECharacteristic(this));

src/local/BLELocalDevice.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ String BLELocalDevice::address() const
272272
return result;
273273
}
274274

275+
void BLELocalDevice::address(uint8_t address[6]) const
276+
{
277+
HCI.readBdAddr(address);
278+
}
279+
275280
int BLELocalDevice::rssi()
276281
{
277282
BLEDevice central = ATT.central();
@@ -346,6 +351,11 @@ void BLELocalDevice::setAppearance(uint16_t appearance)
346351
GATT.setAppearance(appearance);
347352
}
348353

354+
void BLELocalDevice::setPPCP(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout)
355+
{
356+
GATT.setPPCP(minimumConnectionInterval, maximumConnectionInterval, slaveLatency, connectionSupervisionTimeout);
357+
}
358+
349359
void BLELocalDevice::addService(BLEService& service)
350360
{
351361
GATT.addService(service);

src/local/BLELocalDevice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class BLELocalDevice {
4545
virtual bool disconnect();
4646

4747
virtual String address() const;
48+
49+
virtual void address(uint8_t address[6]) const;
4850

4951
virtual int rssi();
5052

@@ -60,6 +62,7 @@ class BLELocalDevice {
6062

6163
virtual void setDeviceName(const char* deviceName);
6264
virtual void setAppearance(uint16_t appearance);
65+
virtual void setPPCP(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout);
6366

6467
virtual void addService(BLEService& service);
6568

src/utility/GATT.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ GATTClass::GATTClass() :
3131
_genericAccessService(NULL),
3232
_deviceNameCharacteristic(NULL),
3333
_appearanceCharacteristic(NULL),
34-
_genericAttributeService(NULL),
35-
_servicesChangedCharacteristic(NULL)
34+
35+
_PPCPCharacteristic(NULL),
36+
37+
_genericAttributeService(NULL)
38+
//_servicesChangedCharacteristic(NULL) // removed
3639
{
3740
}
3841

@@ -46,21 +49,30 @@ void GATTClass::begin()
4649
_genericAccessService = new BLELocalService("1800");
4750
_deviceNameCharacteristic = new BLELocalCharacteristic("2a00", BLERead, 20);
4851
_appearanceCharacteristic = new BLELocalCharacteristic("2a01", BLERead, 2);
52+
53+
_PPCPCharacteristic = new BLELocalCharacteristic("2a04", BLERead, 8);
54+
4955
_genericAttributeService = new BLELocalService("1801");
50-
_servicesChangedCharacteristic = new BLELocalCharacteristic("2a05", BLEIndicate, 4);
56+
//_servicesChangedCharacteristic = new BLELocalCharacteristic("2a05", BLEIndicate, 4); // removed
5157

5258
_genericAccessService->retain();
5359
_deviceNameCharacteristic->retain();
5460
_appearanceCharacteristic->retain();
61+
62+
_PPCPCharacteristic->retain();
63+
5564
_genericAttributeService->retain();
56-
_servicesChangedCharacteristic->retain();
65+
//_servicesChangedCharacteristic->retain(); // removed
5766

5867
_genericAccessService->addCharacteristic(_deviceNameCharacteristic);
5968
_genericAccessService->addCharacteristic(_appearanceCharacteristic);
60-
_genericAttributeService->addCharacteristic(_servicesChangedCharacteristic);
69+
_genericAccessService->addCharacteristic(_PPCPCharacteristic);
70+
//_genericAttributeService->addCharacteristic(_servicesChangedCharacteristic); // removed
6171

6272
setDeviceName("Arduino");
63-
setAppearance(0x000);
73+
setAppearance(0x0000);
74+
75+
setPPCP(DEFAULT_PPCP_minimumConnectionInterval, DEFAULT_PPCP_maximumConnectionInterval, DEFAULT_PPCP_slaveLatency, DEFAULT_PPCP_connectionSupervisionTimeout);
6476

6577
clearAttributes();
6678

@@ -79,11 +91,14 @@ void GATTClass::end()
7991
if (_appearanceCharacteristic->release() == 0)
8092
delete(_appearanceCharacteristic);
8193

94+
if (_PPCPCharacteristic->release() == 0)
95+
delete(_PPCPCharacteristic);
96+
8297
if (_genericAttributeService->release() == 0)
8398
delete(_genericAttributeService);
8499

85-
if (_servicesChangedCharacteristic->release() == 0)
86-
delete(_servicesChangedCharacteristic);
100+
//if (_servicesChangedCharacteristic->release() == 0) // removed
101+
// delete(_servicesChangedCharacteristic);
87102

88103
clearAttributes();
89104
}
@@ -98,6 +113,12 @@ void GATTClass::setAppearance(uint16_t appearance)
98113
_appearanceCharacteristic->writeValue((uint8_t*)&appearance, sizeof(appearance));
99114
}
100115

116+
void GATTClass::setPPCP(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout)
117+
{
118+
uint16_t PPCPData[] = { minimumConnectionInterval, maximumConnectionInterval, slaveLatency, connectionSupervisionTimeout };
119+
_PPCPCharacteristic->writeValue((uint8_t*)&PPCPData, sizeof(PPCPData));
120+
}
121+
101122
void GATTClass::addService(BLEService& service)
102123
{
103124
BLELocalService* localService = service.local();

0 commit comments

Comments
 (0)