Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
Revision 259:323f588e5f57, committed 2016-09-15
- Comitter:
- Vincent Coubard
- Date:
- Thu Sep 15 10:51:21 2016 +0100
- Branch:
- 70f819844d61400a7b6772dcc911a63fc73af09e
- Parent:
- 258:e5ef65120b06
- Child:
- 260:e93cbde933ce
- Commit message:
- Sync with 70f819844d61400a7b6772dcc911a63fc73af09e
2016-07-08 12:18:26+01:00: Vincent Coubard
Fix ServiceInstantiation_test_xx
Fix the last handle set for characteristics
Fix discovery order.
From a user perspective, the service tree is traversed in deep.
The previous behavior was:
for service in services:
service_callback(callback)
for characteristic in characteristics:
characteristic_callback(characteristic)
The new behavior is:
for service in services:
service_callback(callback)
for characteristic in service.characteristics:
characteristic_callback(characteristic)
Reserve the valid count of attribute records when declaring a service.
Report error when it is not possible to add a service.
Changed in this revision
--- a/source/BlueNRGDiscoveredCharacteristic.cpp Thu Sep 15 10:51:20 2016 +0100
+++ b/source/BlueNRGDiscoveredCharacteristic.cpp Thu Sep 15 10:51:21 2016 +0100
@@ -62,3 +62,7 @@
props._indicate = propsIn.indicate();
props._authSignedWrite = propsIn.authSignedWrite();
}
+
+ void BlueNRGDiscoveredCharacteristic::setLastHandle(GattAttribute::Handle_t lastHandleIn) {
+ lastHandle = lastHandleIn;
+ }
\ No newline at end of file
--- a/source/BlueNRGGap.cpp Thu Sep 15 10:51:20 2016 +0100
+++ b/source/BlueNRGGap.cpp Thu Sep 15 10:51:21 2016 +0100
@@ -501,9 +501,9 @@
);
if (err) {
- printf("impossible to set advertising parameters\n\r");
- printf("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
- printf("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
+ PRINTF("impossible to set advertising parameters\n\r");
+ PRINTF("advInterval min: %u, advInterval max: %u\n\r", advInterval, advInterval + 1);
+ PRINTF("advType: %u, advFilterPolicy: %u\n\r", params.getAdvertisingType(), advFilterPolicy);
return BLE_ERROR_INVALID_PARAM;
}
@@ -1352,7 +1352,7 @@
advIntMS = (conn_min_interval*1.25)-GUARD_INT;
advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
- printf("conn_min_interval is equal to %u\r\n", conn_min_interval);
+ PRINTF("conn_min_interval is equal to %u\r\n", conn_min_interval);
} else {
advInterval = _advParams.getIntervalInADVUnits();
}
--- a/source/BlueNRGGattClient.cpp Thu Sep 15 10:51:20 2016 +0100
+++ b/source/BlueNRGGattClient.cpp Thu Sep 15 10:51:21 2016 +0100
@@ -15,7 +15,7 @@
*/
/**
******************************************************************************
- * @file BlueNRGGattServer.cpp
+ * @file BlueNRGGattServer.cpp
* @author STMicroelectronics
* @brief Implementation of BlueNRG BLE_API GattServer Class
******************************************************************************
@@ -29,13 +29,13 @@
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
+ */
+
/** @defgroup BlueNRGGATTClient
* @brief BlueNRG BLE_API GattClient Adaptation
* @{
*/
-
+
#include "BlueNRGGattClient.h"
#include "mbed-drivers/mbed.h"
#include "BlueNRGGap.h"
@@ -59,10 +59,10 @@
_currentState = GATT_IDLE;
return;
}
-
+
// Service Discovery complete
/*
- if(_currentState != GATT_IDLE &&
+ if(_currentState != GATT_IDLE &&
_currentState != GATT_DISCOVERY_TERMINATED &&
_currentState != GATT_WRITE_CHAR &&
_currentState != GATT_READ_CHAR) {
@@ -86,7 +86,7 @@
_currentState = GATT_IDLE;
}
}
-
+
void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
uint8_t event_data_length,
uint8_t attribute_data_length,
@@ -107,13 +107,13 @@
// UUID Type
if (attribute_data_length == 6) {
-
+
PRINTF("UUID_TYPE_16\n\r");
uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
-
+
} else {
-
+
PRINTF("UUID_TYPE_128\n\r");
uuid.setupLong(attribute_data_list+offset+4, UUID::LSB);
@@ -125,17 +125,12 @@
}
#endif
PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
-
+
}
-
+
PRINTF("Setup serviceIndex = %d\n\r", _numServices);
discoveredService[_numServices].setup(uuid, startHandle, endHandle);
-
- if(serviceDiscoveryCallback) {
- if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
- serviceDiscoveryCallback(&discoveredService[_numServices]);
- }
- }
+
_numServices++;
offset += attribute_data_length;
@@ -181,12 +176,9 @@
}
discoveredService[i].setup(uuid, startHandle, endHandle);
-
- if(serviceDiscoveryCallback) {
- serviceDiscoveryCallback(&discoveredService[_numServices]);
- }
+
_numServices++;
-
+
offset += 4;
}
}
@@ -225,10 +217,10 @@
PRINTF("\r\n");
#endif
}
-
+
// Properties
DiscoveredCharacteristic::Properties_t p;
-
+
p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
@@ -263,9 +255,14 @@
valueHandle,
lastHandle);
- if(characteristicDiscoveryCallback) {
- characteristicDiscoveryCallback(&discoveredChar[_numChars]);
+ if (_numChars != 0) {
+ discoveredChar[_numChars - 1].setLastHandle(declHandle - 1);
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+ }
}
+
_numChars++;
offset += handle_value_pair_length;
@@ -280,9 +277,9 @@
// Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
UUID uuid;
-
+
PRINTF("serviceCharByUUIDCB\n\r");
-
+
// UUID Type
if (event_data_length == 7) {
PRINTF("Char UUID_TYPE_16\n\r");
@@ -303,7 +300,7 @@
// Properties
DiscoveredCharacteristic::Properties_t p;
-
+
p._broadcast = (props_mask[0] & attr_value[0]);
p._read = (props_mask[1] & attr_value[0])>>1;
p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
@@ -336,7 +333,7 @@
declHandle,
valueHandle,
lastHandle);
-
+
if(characteristicDiscoveryCallback) {
characteristicDiscoveryCallback(&discoveredChar[_numChars]);
}
@@ -346,24 +343,37 @@
ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
{
PRINTF("findServiceChars\n\r");
-
+
tBleStatus ret;
uint8_t uuid_type = UUID_TYPE_16;
uint8_t short_uuid[2];
uint8_t *uuid = NULL;
-
+
DiscoveredService *service;
-
+
+ // complete the discovery of the last characteristic of the previous service.
+ // Its last handle wasn't known before this point
+ // update the handle and call the characteristic discovery callback.
+ if (_servIndex != 0 && _numChars != 0) {
+ discoveredChar[_numChars - 1].setLastHandle(discoveredService[_servIndex - 1].getEndHandle());
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars - 1]);
+ }
+ }
+
+ _numChars = 0;
+
// We finished chars discovery for all services
if(_servIndex >= _numServices) {
PRINTF("!!!We finished chars discovery for all services!!!\n\r");
//_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
-
+
terminateServiceDiscovery();
-
+
return BLE_ERROR_NONE;
}
-
+
service = &discoveredService[_servIndex];
/*
if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
@@ -377,55 +387,59 @@
PRINTF("\r\n");
}
*/
-
+
+ if(serviceDiscoveryCallback) {
+ serviceDiscoveryCallback(service);
+ }
+
PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
//ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
- if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
- PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
- ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
- } else {
-
- uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
-
- if(type == UUID::UUID_TYPE_SHORT) {
- STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
-
- uuid_type = UUID_TYPE_16;
- uuid = short_uuid;
+ if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
+ PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
+ ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+ } else {
+
+ uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
+
+ if(type == UUID::UUID_TYPE_SHORT) {
+ STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
+
+ uuid_type = UUID_TYPE_16;
+ uuid = short_uuid;
#ifdef DEBUG
- PRINTF("findServiceChars C UUID-");
- for(unsigned i = 0; i < 2; i++) {
- PRINTF("%02X", short_uuid[i]);
- }
- PRINTF("\n\r");
+ PRINTF("findServiceChars C UUID-");
+ for(unsigned i = 0; i < 2; i++) {
+ PRINTF("%02X", short_uuid[i]);
+ }
+ PRINTF("\n\r");
#endif
- } else if(type==UUID::UUID_TYPE_LONG) {
-
- uuid_type = UUID_TYPE_128;
- uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
+ } else if(type==UUID::UUID_TYPE_LONG) {
+
+ uuid_type = UUID_TYPE_128;
+ uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
#ifdef DEBUG
- PRINTF("(findServiceChars) C UUID-");
- for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
- PRINTF("%02X", uuid[i]);
- }
- PRINTF("\r\n");
+ PRINTF("(findServiceChars) C UUID-");
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", uuid[i]);
+ }
+ PRINTF("\r\n");
#endif
+ }
+
+ ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
+ service->getStartHandle(),
+ service->getEndHandle(),
+ uuid_type,
+ uuid);
}
- ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
- service->getStartHandle(),
- service->getEndHandle(),
- uuid_type,
- uuid);
- }
-
if(ret == BLE_STATUS_SUCCESS) {
_servIndex++;
}
-
+
PRINTF("findServiceChars ret=%d\n\r", ret);
-
+
return BLE_ERROR_NONE;
}
@@ -436,7 +450,7 @@
const UUID &matchingCharacteristicUUIDIn)
{
PRINTF("launchServiceDiscovery\n\r");
-
+
tBleStatus ret;
uint8_t uuid_type = UUID_TYPE_16;
uint8_t short_uuid[2];
@@ -466,17 +480,17 @@
for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
}
-
+
if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
-
+
// Wildcard: search for all services
ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
-
+
} else {
-
+
uint8_t type = matchingServiceUUID.shortOrLong();
//PRINTF("AddService(): Type:%d\n\r", type);
-
+
if(type == UUID::UUID_TYPE_SHORT) {
STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
#ifdef DEBUG
@@ -486,10 +500,10 @@
}
PRINTF("\n\r");
#endif
-
+
uuid_type = UUID_TYPE_16;
uuid = short_uuid;
-
+
} else if(type==UUID::UUID_TYPE_LONG) {
uuid_type = UUID_TYPE_128;
@@ -503,18 +517,18 @@
PRINTF("\n\r");
#endif
}
-
+
// search for specific service by UUID
ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)connectionHandle, uuid_type, uuid);
//ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
}
-
+
if(ret == BLE_STATUS_SUCCESS) {
_currentState = GATT_SERVICE_DISCOVERY;
}
-
+
PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
-
+
return BLE_ERROR_NONE;
}
@@ -558,7 +572,7 @@
_currentState == GATT_WRITE_CHAR ) {
return false;
}
-
+
return true;
*/
}
@@ -566,7 +580,7 @@
void BlueNRGGattClient::terminateServiceDiscovery(void)
{
_currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
-
+
if (terminationCallback) {
terminationCallback(_connectionHandle);
}
@@ -590,18 +604,18 @@
(void)offset;
tBleStatus ret;
-
+
BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-
- // Save the attribute_handle not provided by evt_att_read_resp
+
+ // Save the attribute_handle not provided by evt_att_read_resp
gattc->readCBParams.handle = attributeHandle;
-
+
// FIXME: We need to wait for a while before starting a read
// due to BlueNRG process queue handling
Clock_Wait(100);
ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
-
+
if(ret == BLE_STATUS_SUCCESS) {
gattc->_currentState = GATT_READ_CHAR;
return BLE_ERROR_NONE;
@@ -639,7 +653,7 @@
(void)event_data_length;
writeCBParams.connHandle = connHandle;
-
+
BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
}
@@ -653,9 +667,9 @@
(void)cmd;
tBleStatus ret;
-
+
BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-
+
// We save the write response params (used by the callback) because
// when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
gattc->writeCBParams.connHandle = connHandle;
@@ -664,10 +678,10 @@
gattc->writeCBParams.offset = 0;
gattc->writeCBParams.len = length;
gattc->writeCBParams.data = value;
-
+
ret = aci_gatt_write_charac_value(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
//ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
-
+
if (ret == BLE_STATUS_SUCCESS) {
gattc->_currentState = GATT_WRITE_CHAR;
return BLE_ERROR_NONE;
@@ -694,7 +708,7 @@
handle_uuid_length = 18; //Handle + UUID_128
numCharacDesc = (event_data_length - 1) / handle_uuid_length;
-
+
offset = 0;
for (i=0; i<numCharacDesc; i++) {
@@ -702,13 +716,13 @@
// UUID Type
if (handle_uuid_length == 4) {
-
+
PRINTF("UUID_TYPE_16\n\r");
uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
-
+
} else {
-
+
PRINTF("UUID_TYPE_128\n\r");
uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
#ifdef DEBUG
@@ -812,5 +826,4 @@
memset(discoveredChar, 0, sizeof(discoveredChar));
return BLE_ERROR_NONE;
-}
-
+}
\ No newline at end of file
--- a/source/BlueNRGGattServer.cpp Thu Sep 15 10:51:20 2016 +0100
+++ b/source/BlueNRGGattServer.cpp Thu Sep 15 10:51:21 2016 +0100
@@ -76,8 +76,17 @@
const uint8_t *base_uuid;
const uint8_t *base_char_uuid;
- uint8_t charsCount = 0;
- uint8_t maxAttrRecords = 0;
+ uint8_t charsCount = service.getCharacteristicCount();
+ const uint8_t available_characteristics = BLE_TOTAL_CHARACTERISTICS - characteristicCount;
+
+ // check that there is enough characteristics left in the
+ // characteristic array.
+ if (charsCount > available_characteristics) {
+ PRINTF("charCount = %u and characteristicCount = %u\r\n", charsCount, available_characteristics);
+ return BLE_ERROR_NO_MEM;
+ }
+
+ const uint16_t maxAttrRecords = computeAttributesRecord(service);
type = (service.getUUID()).shortOrLong();
PRINTF("AddService(): Type:%d\n\r", type);
@@ -92,17 +101,14 @@
COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],primary_short_uuid[1],primary_short_uuid[0],base_uuid[11],base_uuid[10],base_uuid[9],base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]);
}
- charsCount = service.getCharacteristicCount();
- //1(service record)+2records*char+1record*char_desc
- maxAttrRecords = 1+3*charsCount;
-
if(type==UUID::UUID_TYPE_SHORT) {
ret = aci_gatt_add_serv(UUID_TYPE_16,
primary_short_uuid,
PRIMARY_SERVICE,
maxAttrRecords/*7*/,
&servHandle);
- PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
+ PRINTF("aci_gatt_add_serv UUID_TYPE_SHORT ret=%d\n\r", ret);
+
}
else if(type==UUID::UUID_TYPE_LONG) {
ret = aci_gatt_add_serv(UUID_TYPE_128,
@@ -113,6 +119,25 @@
PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret);
}
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ break;
+
+ case BLE_STATUS_INVALID_PARAMETER:
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_OUT_OF_HANDLE:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case ERR_UNSPECIFIED_ERROR:
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_ERROR:
+ default:
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
+ }
+
+
+
service.setHandle(servHandle);
//serviceHandleVector.push_back(servHandle);
PRINTF("added servHandle handle =%u\n\r", servHandle);
@@ -191,6 +216,40 @@
p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
}
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ break;
+
+ case ERR_UNSPECIFIED_ERROR:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case BLE_STATUS_OUT_OF_HANDLE:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ case BLE_STATUS_CHARAC_ALREADY_EXISTS:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_ERROR:
+ default:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
+ }
+
bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
p_characteristics[characteristicCount++] = p_char;
@@ -199,9 +258,13 @@
PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle());
if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
- write(p_char->getValueAttribute().getHandle(),
+ ble_error_t err = write(p_char->getValueAttribute().getHandle(),
p_char->getValueAttribute().getValuePtr(),
p_char->getValueAttribute().getLength(), false /* localOnly */);
+ if (err) {
+ PRINTF("ERROR HERE !!!!\r\n");
+ return err;
+ }
}
// add descriptors now
@@ -226,12 +289,45 @@
CHAR_ATTRIBUTE_LEN_IS_FIXED,
&descHandle);
PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
- if(ret==(tBleStatus)0) {
- PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
- descriptor->setHandle(descHandle);
+
+ switch (ret) {
+ case BLE_STATUS_SUCCESS:
+ PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
+ descriptor->setHandle(descHandle);
+ break;
+
+ case ERR_UNSPECIFIED_ERROR:
+ case BLE_STATUS_INSUFFICIENT_RESOURCES:
+ case BLE_STATUS_OUT_OF_HANDLE:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_NO_MEM;
+
+ case BLE_STATUS_INVALID_HANDLE:
+ case BLE_STATUS_INVALID_PARAMETER:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INVALID_PARAM;
+
+ case BLE_STATUS_INVALID_OPERATION:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+
+ case BLE_STATUS_ERROR:
+ default:
+ // TODO remove characteristics and the service previously added.
+ // remove service in the stack by using: Aci_Gatt_Del_Service
+ // remove characteristics in the stack by using: Aci_Gatt_Del_Char
+ // update service counter
+ // destroy registered characteristic and updat echaracteristic counter
+ return BLE_ERROR_INTERNAL_STACK_FAILURE;
}
}
-
}
serviceCount++;
@@ -528,4 +624,45 @@
characteristicCount = 0;
return BLE_ERROR_NONE;
+}
+
+
+/// compute the number of attributes needed by this service.
+uint16_t BlueNRGGattServer::computeAttributesRecord(GattService& service) {
+ uint16_t attribute_records = 1;
+
+ for (uint8_t characteristic_index = 0; characteristic_index < service.getCharacteristicCount(); ++characteristic_index) {
+ // add two attributes, one for the characteristic declaration
+ // and the other for the characteristic value.
+ attribute_records += 2;
+
+ const GattCharacteristic* characteristic = service.getCharacteristic(characteristic_index);
+ const uint8_t properties = characteristic->getProperties();
+ // if notify or indicate are present, two attributes are
+ // needed
+ if ((properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ||
+ (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
+ attribute_records += 2;
+ }
+
+ // if broadcast is set, two attributes are needed
+ if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_BROADCAST) {
+ attribute_records += 2;
+ }
+
+ // if extended properties flag is set, two attributes are needed
+ if (properties & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_EXTENDED_PROPERTIES) {
+ attribute_records += 2;
+ }
+
+ attribute_records += characteristic->getDescriptorCount();
+ }
+
+ // for some reason, if there is just a service, this value should
+ // be equal to 5
+ if (attribute_records == 1) {
+ attribute_records = 5;
+ }
+
+ return attribute_records;
}
\ No newline at end of file
--- a/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Thu Sep 15 10:51:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Thu Sep 15 10:51:21 2016 +0100
@@ -30,7 +30,7 @@
GattAttribute::Handle_t declHandleIn,
GattAttribute::Handle_t valueHandleIn,
GattAttribute::Handle_t lastHandleIn);
-
+
void setup(BlueNRGGattClient *gattcIn,
Gap::Handle_t connectionHandleIn,
UUID uuidIn,
@@ -38,6 +38,9 @@
GattAttribute::Handle_t declHandleIn,
GattAttribute::Handle_t valueHandleIn,
GattAttribute::Handle_t lastHandleIn);
+
+
+ void setLastHandle(GattAttribute::Handle_t lastHandleIn);
};
-#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
+#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
\ No newline at end of file
--- a/x-nucleo-idb0xa1/BlueNRGGattServer.h Thu Sep 15 10:51:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGGattServer.h Thu Sep 15 10:51:21 2016 +0100
@@ -15,7 +15,7 @@
*/
/**
******************************************************************************
- * @file BlueNRGGattServer.cpp
+ * @file BlueNRGGattServer.cpp
* @author STMicroelectronics
* @brief Header file for BLE_API GattServer Class
******************************************************************************
@@ -30,7 +30,7 @@
*
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
*/
-
+
#ifndef __BLUENRG_GATT_SERVER_H__
#define __BLUENRG_GATT_SERVER_H__
@@ -53,13 +53,13 @@
static BlueNRGGattServer m_instance;
return m_instance;
}
-
+
enum HandleEnum_t {
CHAR_HANDLE = 0,
CHAR_VALUE_HANDLE,
CHAR_DESC_HANDLE
};
-
+
/* Functions that must be implemented from GattServer */
virtual ble_error_t addService(GattService &);
virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
@@ -67,13 +67,13 @@
virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
virtual ble_error_t initializeGATTDatabase(void);
-
+
virtual bool isOnDataReadAvailable() const {
return true;
}
virtual ble_error_t reset(void);
-
+
/* BlueNRG Functions */
void eventCallback(void);
//void hwCallback(void *pckt);
@@ -83,8 +83,13 @@
void HCIDataReadEvent(const GattReadCallbackParams *params);
void HCIEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle);
void HCIDataSentEvent(unsigned count);
-
+
private:
+
+ // compute the number of attribute record needed by a service
+ static uint16_t computeAttributesRecord(GattService& service);
+
+
static const int MAX_SERVICE_COUNT = 10;
uint8_t serviceCount;
uint8_t characteristicCount;
@@ -101,12 +106,12 @@
BlueNRGGattServer(BlueNRGGattServer const &);
void operator=(BlueNRGGattServer const &);
-
- static const int CHAR_DESC_TYPE_16_BIT=0x01;
- static const int CHAR_DESC_TYPE_128_BIT=0x02;
+
+ static const int CHAR_DESC_TYPE_16_BIT=0x01;
+ static const int CHAR_DESC_TYPE_128_BIT=0x02;
static const int CHAR_DESC_SECURITY_PERMISSION=0x00;
- static const int CHAR_DESC_ACCESS_PERMISSION=0x03;
- static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00;
+ static const int CHAR_DESC_ACCESS_PERMISSION=0x03;
+ static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00;
};
-#endif
+#endif
\ No newline at end of file
