Skip to content
Closed
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"cmake.ignoreCMakeListsMissing": true
}
66 changes: 65 additions & 1 deletion src/BLEAdvertisingData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "BLEAdvertisingData.h"

#define AD_FIELD_OVERHEAD (2)
#define AD_NAME_LENGTH (19)

BLEAdvertisingData::BLEAdvertisingData() :
_dataLength(0),
Expand All @@ -29,6 +30,11 @@ BLEAdvertisingData::BLEAdvertisingData() :
_flags(0),
_hasFlags(false),
_localName(NULL),
_minimumConnectionInterval(0),
_maximumConnectionInterval(0),
_hasConnectionInterval(false),
_TransmitPowerLevel(0),
_hasTransmitPowerLevel(false),
_manufacturerData(NULL),
_manufacturerDataLength(0),
_manufacturerCompanyId(0),
Expand Down Expand Up @@ -73,6 +79,11 @@ void BLEAdvertisingData::clear()
_rawDataLength = 0;
_hasFlags = false;
_localName = NULL;
_minimumConnectionInterval = 0;
_maximumConnectionInterval = 0;
_hasConnectionInterval = false;
_TransmitPowerLevel = 0;
_hasTransmitPowerLevel = false;
_manufacturerData = NULL;
_manufacturerDataLength = 0;
_hasManufacturerCompanyId = false;
Expand All @@ -90,6 +101,11 @@ void BLEAdvertisingData::copy(const BLEAdvertisingData& adv)
_flags = adv._flags;
_hasFlags = adv._hasFlags;
_localName = adv._localName;
_minimumConnectionInterval = adv._minimumConnectionInterval;
_maximumConnectionInterval = adv._maximumConnectionInterval;
_hasConnectionInterval = adv._hasConnectionInterval;
_TransmitPowerLevel = adv._TransmitPowerLevel;
_hasTransmitPowerLevel = adv._hasTransmitPowerLevel;
_manufacturerData = adv._manufacturerData;
_manufacturerDataLength = adv._manufacturerDataLength;
_manufacturerCompanyId = adv._manufacturerCompanyId;
Expand Down Expand Up @@ -183,6 +199,29 @@ bool BLEAdvertisingData::setLocalName(const char *localName)
return success;
}

bool BLEAdvertisingData::setAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval)
{
int previousLength = (_hasConnectionInterval) ? ( sizeof(_minimumConnectionInterval) + sizeof(_maximumConnectionInterval) + AD_FIELD_OVERHEAD) : 0;
bool success = updateRemainingLength(previousLength, (sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval) + AD_FIELD_OVERHEAD));
if (success) {
_hasConnectionInterval = true;
_minimumConnectionInterval = minimumConnectionInterval;
_maximumConnectionInterval = maximumConnectionInterval;
}
return success;
}

bool BLEAdvertisingData::setAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel)
{
int previousLength = (_hasTransmitPowerLevel) ? ( sizeof(_TransmitPowerLevel) + AD_FIELD_OVERHEAD) : 0;
bool success = updateRemainingLength(previousLength, (sizeof(TransmitPowerLevel) + AD_FIELD_OVERHEAD));
if (success) {
_hasTransmitPowerLevel = true;
_TransmitPowerLevel = TransmitPowerLevel;
}
return success;
}

bool BLEAdvertisingData::setRawData(const uint8_t* data, int length)
{
if (length > MAX_AD_DATA_LENGTH) {
Expand Down Expand Up @@ -248,6 +287,14 @@ bool BLEAdvertisingData::updateData()
if (_localName) {
success &= addLocalName(_localName);
}
// Try to add Slave Connection Interval into the current advertising packet
if (_hasConnectionInterval) {
success &= addAdvertisedConnectionInterval(_minimumConnectionInterval, _maximumConnectionInterval);
}
// Try to add Transmit Power Level into the current advertising packet
if (_hasTransmitPowerLevel) {
success &= addAdvertisedTransmitPowerLevel(_TransmitPowerLevel);
}
return success;
}

Expand All @@ -272,7 +319,11 @@ bool BLEAdvertisingData::addLocalName(const char *localName)
if (strlen(localName) > (MAX_AD_DATA_LENGTH - AD_FIELD_OVERHEAD)) {
success = addField(BLEFieldShortLocalName, (uint8_t*)localName, (MAX_AD_DATA_LENGTH - AD_FIELD_OVERHEAD));
} else {
success = addField(BLEFieldCompleteLocalName, localName);
uint8_t tempData[AD_NAME_LENGTH];
uint8_t tempDataLength = strlen(localName);
memcpy(tempData, (uint8_t*)localName, tempDataLength + 1);
memset(&tempData[tempDataLength + 1], 0x20, AD_NAME_LENGTH - tempDataLength - 1);
success = addField(BLEFieldCompleteLocalName, tempData, AD_NAME_LENGTH);
}
return success;
}
Expand Down Expand Up @@ -330,6 +381,19 @@ bool BLEAdvertisingData::addFlags(uint8_t flags)
return addField(BLEFieldFlags, &flags, sizeof(flags));
}

bool BLEAdvertisingData::addAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval)
{
uint8_t tempData[sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval)];
memcpy(tempData, &minimumConnectionInterval, sizeof(minimumConnectionInterval));
memcpy(&tempData[sizeof(minimumConnectionInterval)], &maximumConnectionInterval, sizeof(maximumConnectionInterval));
return addField(BLEFieldConnectionInterval, tempData, sizeof(minimumConnectionInterval) + sizeof(maximumConnectionInterval));
}

bool BLEAdvertisingData::addAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel)
{
return addField(BLEFieldTransmitPowerLevel, &TransmitPowerLevel, sizeof(TransmitPowerLevel));
}

bool BLEAdvertisingData::addField(BLEAdField field, const char* data)
{
int dataLength = strlen(data);
Expand Down
12 changes: 12 additions & 0 deletions src/BLEAdvertisingData.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ enum BLEAdField {
BLEFieldCompleteAdvertisedService128 = 0x07,
BLEFieldShortLocalName = 0x08,
BLEFieldCompleteLocalName = 0x09,
BLEFieldTransmitPowerLevel = 0x0A,
BLEFieldConnectionInterval = 0x12,
BLEFieldServiceData = 0x16,
BLEFieldManufacturerData = 0xFF,

Expand All @@ -66,6 +68,8 @@ class BLEAdvertisingData {
bool setManufacturerData(const uint8_t manufacturerData[], int manufacturerDataLength);
bool setManufacturerData(const uint16_t companyId, const uint8_t manufacturerData[], int manufacturerDataLength);
bool setLocalName(const char *localName);
bool setAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval);
bool setAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel);
bool setAdvertisedServiceData(uint16_t uuid, const uint8_t data[], int length);
bool setRawData(const uint8_t* data, int length);
bool setRawData(const BLEAdvertisingRawData& data);
Expand All @@ -86,6 +90,8 @@ class BLEAdvertisingData {
bool addManufacturerData(const uint8_t manufacturerData[], int manufacturerDataLength);
bool addManufacturerData(const uint16_t companyId, const uint8_t manufacturerData[], int manufacturerDataLength);
bool addLocalName(const char *localName);
bool addAdvertisedConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval);
bool addAdvertisedTransmitPowerLevel(uint8_t TransmitPowerLevel);
bool addAdvertisedServiceData(uint16_t uuid, const uint8_t data[], int length);
bool addRawData(const uint8_t* data, int length);
bool addFlags(uint8_t flags);
Expand All @@ -105,6 +111,12 @@ class BLEAdvertisingData {
bool _hasFlags;
const char* _localName;

uint16_t _minimumConnectionInterval;
uint16_t _maximumConnectionInterval;
bool _hasConnectionInterval;
uint8_t _TransmitPowerLevel;
bool _hasTransmitPowerLevel;

const uint8_t* _manufacturerData;
int _manufacturerDataLength;
uint16_t _manufacturerCompanyId;
Expand Down
4 changes: 4 additions & 0 deletions src/BLEProperty.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,9 @@ enum BLE_GATT_PERM_ {
WRITE_AUTHORIZATION = 1 << 10,
};

#define GAP_PPCP_MIN_CONN_INTERVAL (80) /* 100 ms */
#define GAP_PPCP_MAX_CONN_INTERVAL (160) /* 200 ms */
#define GAP_PPCP_SLAVE_LATENCY (0) /* 0 ms */
#define GAP_PPCP_SUPERVISION_TMO (1000) /* 1000 ms */

#endif
10 changes: 10 additions & 0 deletions src/local/BLELocalCharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,17 @@ void BLELocalCharacteristic::writeValue(BLEDevice device, const uint8_t value[],
{
_written = true;

if (_properties & BLEWriteWithoutResponse) {
_valueLength = min(length, _valueSize);
memcpy(_value, value, _valueLength);

if (_fixedLength) {
_valueLength = _valueSize;
}
}
else {
writeValue(value, length);
}

if (_eventHandlers[BLEWritten]) {
_eventHandlers[BLEWritten](device, BLECharacteristic(this));
Expand Down
5 changes: 5 additions & 0 deletions src/local/BLELocalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ void BLELocalDevice::setAppearance(uint16_t appearance)
GATT.setAppearance(appearance);
}

void BLELocalDevice::setPreferredConnectionParameters(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout)
{
GATT.setPreferredConnectionParameters(minimumConnectionInterval, maximumConnectionInterval, slaveLatency, connectionSupervisionTimeout);
}

void BLELocalDevice::addService(BLEService& service)
{
GATT.addService(service);
Expand Down
1 change: 1 addition & 0 deletions src/local/BLELocalDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class BLELocalDevice {

virtual void setDeviceName(const char* deviceName);
virtual void setAppearance(uint16_t appearance);
virtual void setPreferredConnectionParameters(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout);

virtual void addService(BLEService& service);

Expand Down
34 changes: 25 additions & 9 deletions src/utility/GATT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ GATTClass::GATTClass() :
_genericAccessService(NULL),
_deviceNameCharacteristic(NULL),
_appearanceCharacteristic(NULL),
_genericAttributeService(NULL),
_servicesChangedCharacteristic(NULL)
_preferredConnectionParametersCharacteristic(NULL),
_genericAttributeService(NULL)
//_servicesChangedCharacteristic(NULL)
{
}

Expand All @@ -46,21 +47,25 @@ void GATTClass::begin()
_genericAccessService = new BLELocalService("1800");
_deviceNameCharacteristic = new BLELocalCharacteristic("2a00", BLERead, 20);
_appearanceCharacteristic = new BLELocalCharacteristic("2a01", BLERead, 2);
_preferredConnectionParametersCharacteristic = new BLELocalCharacteristic("2a04", BLERead, 8);
_genericAttributeService = new BLELocalService("1801");
_servicesChangedCharacteristic = new BLELocalCharacteristic("2a05", BLEIndicate, 4);
//_servicesChangedCharacteristic = new BLELocalCharacteristic("2a05", BLEIndicate, 4);

_genericAccessService->retain();
_deviceNameCharacteristic->retain();
_appearanceCharacteristic->retain();
_preferredConnectionParametersCharacteristic->retain();
_genericAttributeService->retain();
_servicesChangedCharacteristic->retain();
//_servicesChangedCharacteristic->retain();

_genericAccessService->addCharacteristic(_deviceNameCharacteristic);
_genericAccessService->addCharacteristic(_appearanceCharacteristic);
_genericAttributeService->addCharacteristic(_servicesChangedCharacteristic);
_genericAccessService->addCharacteristic(_preferredConnectionParametersCharacteristic);
//_genericAttributeService->addCharacteristic(_servicesChangedCharacteristic);

setDeviceName("Arduino");
setAppearance(0x000);
setPreferredConnectionParameters(GAP_PPCP_MIN_CONN_INTERVAL, GAP_PPCP_MAX_CONN_INTERVAL, GAP_PPCP_SLAVE_LATENCY, GAP_PPCP_SUPERVISION_TMO);

clearAttributes();

Expand All @@ -85,16 +90,21 @@ void GATTClass::end()
_appearanceCharacteristic = NULL;
}

if (_preferredConnectionParametersCharacteristic &&_preferredConnectionParametersCharacteristic->release() == 0) {
delete(_preferredConnectionParametersCharacteristic);
_preferredConnectionParametersCharacteristic = NULL;
}

if (_genericAttributeService && _genericAttributeService->release() == 0) {
delete(_genericAttributeService);
_genericAttributeService = NULL;
}

/*
if (_servicesChangedCharacteristic && _servicesChangedCharacteristic->release() == 0) {
delete(_servicesChangedCharacteristic);
_servicesChangedCharacteristic = NULL;
delete(_servicesChangedCharacteristic);
_servicesChangedCharacteristic = NULL;
}

*/
clearAttributes();
}

Expand All @@ -108,6 +118,12 @@ void GATTClass::setAppearance(uint16_t appearance)
_appearanceCharacteristic->writeValue((uint8_t*)&appearance, sizeof(appearance));
}

void GATTClass::setPreferredConnectionParameters(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout)
{
uint16_t PPCPData[] = {minimumConnectionInterval, maximumConnectionInterval, slaveLatency, connectionSupervisionTimeout};
_preferredConnectionParametersCharacteristic->writeValue((uint8_t*)&PPCPData, sizeof(PPCPData));
}

void GATTClass::addService(BLEService& service)
{
BLELocalService* localService = service.local();
Expand Down
4 changes: 3 additions & 1 deletion src/utility/GATT.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class GATTClass {

virtual void setDeviceName(const char* deviceName);
virtual void setAppearance(uint16_t appearance);
virtual void setPreferredConnectionParameters(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval, uint16_t slaveLatency, uint16_t connectionSupervisionTimeout);

virtual void addService(BLEService& service);

Expand All @@ -64,8 +65,9 @@ class GATTClass {
BLELocalService* _genericAccessService;
BLELocalCharacteristic* _deviceNameCharacteristic;
BLELocalCharacteristic* _appearanceCharacteristic;
BLELocalCharacteristic* _preferredConnectionParametersCharacteristic;
BLELocalService* _genericAttributeService;
BLELocalCharacteristic* _servicesChangedCharacteristic;
//BLELocalCharacteristic* _servicesChangedCharacteristic;
};

extern GATTClass& GATT;
Expand Down
Loading