Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V10 helper func #97

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion module.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
],
"dependencies": {
"ble": "^2.1.16",
"nrf51-sdk": "^1.0.0"
"nrf51-sdk": "^2.0.0"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LiyouZhou: There seems to be a conflict with this PR, I think the problem is that the required nordic sdk version has already been updated in develop for this module.

},
"extraIncludes": [
"source/btle",
Expand Down
202 changes: 27 additions & 175 deletions source/btle/custom/custom_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,184 +178,36 @@ error_t custom_decode_uuid_base(uint8_t const *const p_uuid_base,

/**************************************************************************/
/*!
@brief Adds a new characteristic to the custom service, assigning
properties, a UUID add-on value, etc.

@param[in] service_handle
@param[in] p_uuid The 16-bit value to add to the base UUID
for this characteristic (normally >1
since 1 is typically used by the primary
service).
@param[in] char_props The characteristic properties, as
defined by ble_gatt_char_props_t
@param[in] max_length The maximum length of this characeristic
@param[in] has_variable_len Whether the characteristic data has
variable length.
@param[out] p_char_handle

@returns
@retval ERROR_NONE Everything executed normally
@brief Convert a SecurityManager::SecurityMode_t enum to
a nordic security_req_t enum
@param[in] securityMode The security mod in a SecurityManager::SecurityMode_t enum
@returns the corresponding security mode in a security_req_t enum type
*/
/**************************************************************************/
error_t custom_add_in_characteristic(uint16_t service_handle,
ble_uuid_t *p_uuid,
uint8_t properties,
SecurityManager::SecurityMode_t requiredSecurity,
uint8_t *p_data,
uint16_t length,
uint16_t max_length,
bool has_variable_len,
const uint8_t *userDescriptionDescriptorValuePtr,
uint16_t userDescriptionDescriptorValueLen,
bool readAuthorization,
bool writeAuthorization,
ble_gatts_char_handles_t *p_char_handle)
security_req_t custom_convert_to_nordic_seq_req(SecurityManager::SecurityMode_t securityMode)
{
/* Characteristic metadata */
ble_gatts_attr_md_t cccd_md;
ble_gatt_char_props_t char_props;

memcpy(&char_props, &properties, 1);

if (char_props.notify || char_props.indicate) {
/* Notification requires cccd */
memclr_( &cccd_md, sizeof(ble_gatts_attr_md_t));
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
security_req_t seqReq = SEC_NO_ACCESS;

switch (securityMode) {
case SecurityManager::SECURITY_MODE_NO_ACCESS:
seqReq = SEC_NO_ACCESS;
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
seqReq = SEC_OPEN;
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
seqReq = SEC_JUST_WORKS;
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
seqReq = SEC_MITM;
break;
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
seqReq = SEC_SIGNED;
break;
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
seqReq = SEC_SIGNED_MITM;
break;
}

ble_gatts_char_md_t char_md = {0};

char_md.char_props = char_props;
char_md.p_cccd_md =
(char_props.notify || char_props.indicate) ? &cccd_md : NULL;
if ((userDescriptionDescriptorValueLen > 0) && (userDescriptionDescriptorValuePtr != NULL)) {
char_md.p_char_user_desc = const_cast<uint8_t *>(userDescriptionDescriptorValuePtr);
char_md.char_user_desc_max_size = userDescriptionDescriptorValueLen;
char_md.char_user_desc_size = userDescriptionDescriptorValueLen;
}

/* Attribute declaration */
ble_gatts_attr_md_t attr_md = {0};

attr_md.rd_auth = readAuthorization;
attr_md.wr_auth = writeAuthorization;

attr_md.vloc = BLE_GATTS_VLOC_STACK;
/* Always set variable size */
attr_md.vlen = has_variable_len;

if (char_props.read || char_props.notify || char_props.indicate) {
switch (requiredSecurity) {
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.read_perm);
break;
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.read_perm);
break;
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.read_perm);
break;
default:
break;
};
}

if (char_props.write || char_props.write_wo_resp) {
switch (requiredSecurity) {
case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK :
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM :
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
break;
case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM :
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(&attr_md.write_perm);
break;
case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM :
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(&attr_md.write_perm);
break;
case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM :
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(&attr_md.write_perm);
break;
default:
break;
};
}

ble_gatts_attr_t attr_char_value = {0};

attr_char_value.p_uuid = p_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = length;
attr_char_value.max_len = max_length;
attr_char_value.p_value = p_data;

ASSERT_STATUS ( sd_ble_gatts_characteristic_add(service_handle,
&char_md,
&attr_char_value,
p_char_handle));

return ERROR_NONE;
}



/**************************************************************************/
/*!
@brief Adds a new descriptor to the custom service, assigning
value, a UUID add-on value, etc.

@param[in] char_handle
@param[in] p_uuid The 16-bit value to add to the base UUID
for this descriptor (normally >1
since 1 is typically used by the primary
service).
@param[in] max_length The maximum length of this descriptor
@param[in] has_variable_len Whether the characteristic data has
variable length.

@returns
@retval ERROR_NONE Everything executed normally
*/
/**************************************************************************/
error_t custom_add_in_descriptor(uint16_t char_handle,
ble_uuid_t *p_uuid,
uint8_t *p_data,
uint16_t length,
uint16_t max_length,
bool has_variable_len,
uint16_t *p_desc_handle)
{
/* Descriptor metadata */
ble_gatts_attr_md_t desc_md = {0};

desc_md.vloc = BLE_GATTS_VLOC_STACK;
/* Always set variable size */
desc_md.vlen = has_variable_len;

/* Make it readable and writable */
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_md.write_perm);

ble_gatts_attr_t attr_desc = {0};

attr_desc.p_uuid = p_uuid;
attr_desc.p_attr_md = &desc_md;
attr_desc.init_len = length;
attr_desc.max_len = max_length;
attr_desc.p_value = p_data;

ASSERT_STATUS ( sd_ble_gatts_descriptor_add(char_handle,
&attr_desc,
p_desc_handle));

return ERROR_NONE;
return seqReq;
}
27 changes: 5 additions & 22 deletions source/btle/custom/custom_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include "ble/UUID.h"
#include "ble/GattCharacteristic.h"

extern "C" {
#include "ble_srv_common.h"
}

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -30,28 +34,7 @@ uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base);
error_t custom_decode_uuid(uint8_t const *const p_uuid_base,
ble_uuid_t *p_uuid);
ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid);

error_t custom_add_in_characteristic(uint16_t service_handle,
ble_uuid_t *p_uuid,
uint8_t properties,
SecurityManager::SecurityMode_t requiredSecurity,
uint8_t *p_data,
uint16_t length,
uint16_t max_length,
bool has_variable_len,
const uint8_t *userDescriptionDescriptorValuePtr,
uint16_t userDescriptionDescriptorValueLen,
bool readAuthorization,
bool writeAuthorization,
ble_gatts_char_handles_t *p_char_handle);

error_t custom_add_in_descriptor(uint16_t char_handle,
ble_uuid_t *p_uuid,
uint8_t *p_data,
uint16_t length,
uint16_t max_length,
bool has_variable_len,
uint16_t *p_desc_handle);
security_req_t custom_convert_to_nordic_seq_req(SecurityManager::SecurityMode_t securityMode);

#ifdef __cplusplus
}
Expand Down
92 changes: 63 additions & 29 deletions source/nRF5xGattServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
#include "common/common.h"
#include "btle/custom/custom_helper.h"

extern "C" {
#include "ble_srv_common.h"
}

#include "nRF5xn.h"

/**************************************************************************/
Expand Down Expand Up @@ -73,36 +77,53 @@ ble_error_t nRF5xGattServer::addService(GattService &service)
continue;
}

nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());

/* The user-description descriptor is a special case which needs to be
* handled at the time of adding the characteristic. The following block
* is meant to discover its presence. */
ble_add_char_user_desc_t u_desc;
memset(&u_desc, 0, sizeof(u_desc));

const uint8_t *userDescriptionDescriptorValuePtr = NULL;
uint16_t userDescriptionDescriptorValueLen = 0;
for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
GattAttribute *p_desc = p_char->getDescriptor(j);
if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
userDescriptionDescriptorValueLen = p_desc->getLength();
u_desc.p_char_user_desc = (uint8_t *) p_desc->getValuePtr();
u_desc.max_size = p_desc->getLength();
u_desc.size = p_desc->getLength();
}
}

ASSERT ( ERROR_NONE ==
custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
&nordicUUID,
p_char->getProperties(),
p_char->getRequiredSecurity(),
p_char->getValueAttribute().getValuePtr(),
p_char->getValueAttribute().getLength(),
p_char->getValueAttribute().getMaxLength(),
p_char->getValueAttribute().hasVariableLength(),
userDescriptionDescriptorValuePtr,
userDescriptionDescriptorValueLen,
p_char->isReadAuthorizationEnabled(),
p_char->isWriteAuthorizationEnabled(),
&nrfCharacteristicHandles[characteristicCount]),
BLE_ERROR_PARAM_OUT_OF_RANGE );
ble_gatt_char_props_t char_props;
uint8_t properties = p_char->getProperties();
memcpy(&char_props, &properties, 1);

security_req_t seqReq;
seqReq = custom_convert_to_nordic_seq_req(p_char->getRequiredSecurity());
nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());

ble_add_char_params_t char_params;
memset(&char_params, 0, sizeof(ble_add_char_params_t));

char_params.uuid = nordicUUID.uuid; /*Characteristic UUID (16 bits UUIDs).*/
char_params.uuid_type = nordicUUID.type; /*Base UUID.*/
char_params.max_len = p_char->getValueAttribute().getMaxLength(); /*Maximum length of the characteristic value.*/
char_params.init_len = p_char->getValueAttribute().getLength(); /*Initial length of the characteristic value.*/
char_params.p_init_value = p_char->getValueAttribute().getValuePtr(); /*Initial encoded value of the characteristic.*/
char_params.is_var_len = true; // always set variable length /*Indicates if the characteristic value has variable length.*/
char_params.char_props = char_props; /*Characteristic properties.*/
char_params.is_defered_read = p_char->isReadAuthorizationEnabled(); /*Indicate if deferred read operations are supported.*/
char_params.is_defered_write = p_char->isWriteAuthorizationEnabled(); /*Indicate if deferred write operations are supported.*/
char_params.read_access = seqReq; /*Security requirement for reading the characteristic value.*/
char_params.write_access = seqReq; /*Security requirement for writing the characteristic value.*/
char_params.cccd_write_access = seqReq; /*Security requirement for writing the characteristic's CCCD.*/
char_params.is_value_user = false; // always set BLE_GATTS_VLOC_STACK /*Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
char_params.p_user_descr = &u_desc; /*Pointer to user descriptor if needed*/

ASSERT (ERROR_NONE == characteristic_add(BLE_GATT_HANDLE_INVALID,
&char_params,
&nrfCharacteristicHandles[characteristicCount]),
BLE_ERROR_PARAM_OUT_OF_RANGE );

/* Update the characteristic handle */
p_characteristics[characteristicCount] = p_char;
Expand All @@ -121,17 +142,30 @@ ble_error_t nRF5xGattServer::addService(GattService &service)
continue;
}

nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
ble_add_descr_params_t descr_props;

ASSERT(ERROR_NONE ==
custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
&nordicUUID,
p_desc->getValuePtr(),
p_desc->getLength(),
p_desc->getMaxLength(),
p_desc->hasVariableLength(),
&nrfDescriptorHandles[descriptorCount]),
BLE_ERROR_PARAM_OUT_OF_RANGE);
nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
seqReq = custom_convert_to_nordic_seq_req(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK);

memset(&descr_props, 0, sizeof(descr_props));

descr_props.uuid = nordicUUID.uuid; /*descriptor UUID (16 bits UUIDs).*/
descr_props.uuid_type = nordicUUID.type; /*Base UUID.*/
descr_props.is_defered_read = false; /*Indicate if deferred read operations are supported.*/
descr_props.is_defered_write = false; /*Indicate if deferred write operations are supported.*/
descr_props.is_var_len = p_desc->hasVariableLength(); /*Indicates if the descriptor value has variable length.*/
descr_props.read_access = seqReq; /*Security requirement for reading the descriptor value.*/
descr_props.write_access = seqReq; /*Security requirement for writing the descriptor value.*/
descr_props.is_value_user = false; /*Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
descr_props.init_len = p_desc->getLength(); /*Initial descriptor value length in bytes.*/
descr_props.init_offs = 0; /*Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized.*/
descr_props.max_len = p_desc->getMaxLength(); /*Maximum descriptor value length in bytes, see BLE_GATTS_ATTR_LENS_MAX for maximum values.*/
descr_props.p_value = p_desc->getValuePtr(); /*Pointer to the value of the descriptor*/

ASSERT(ERROR_NONE == descriptor_add(BLE_GATT_HANDLE_INVALID,
&descr_props,
&nrfDescriptorHandles[descriptorCount]),
BLE_ERROR_PARAM_OUT_OF_RANGE);

p_descriptors[descriptorCount++] = p_desc;
p_desc->setHandle(nrfDescriptorHandles[descriptorCount]);
Expand Down