sd_ble_gatts_characteristic_add invalid param

I need to add a custom BLE service with over 20 custom characteristics. During the gap nitialization step, I set the BLE security mode and security level like this:

sec_mode.sm = SECURITY_MODE;
sec_mode.lv = SECURITY_LEVEL;

sd_ble_gap_device_name_set(&sec_mode,
(const uint8_t *)DEVICE_NAME,
strlen(DEVICE_NAME));

I define the custom characteristics using the following pattern:

typedef struct
{
// 128-bit UUID (little endian)
ble_uuid128_t longUuid;
uint16_t shortUuid;
ble_gatts_char_handles_t* pCharacteristicHandles;
ble_gatts_attr_t attributes;
ble_gatts_attr_md_t attributeMetaData;
ble_gatt_char_props_t properties;
ble_gatts_char_md_t characteristicMetaData;
} bleAttribute;

// 128-bit UUID 81374d2f-4c44-4200-8bc7-b940 978f 3918
#define UUID_128 \
{ 0x18,0x39,0x8F,0x97,0x40,0xB9, \
0xC7,0x8B, \
0x00,0x42, \
0x44,0x4C, \
0x2F,0x4D,0x37,0x81}

#define USER_DESCRIPTION " Patient ID"

static ble_gatts_char_handles_t characteristicHandles;

static uint8_t patientId[MAX_PATIENT_ID_LENGTH] = "ABC";

const bleAttribute patientIdAttribute =
{
.longUuid.uuid128 = UUID_128,

.shortUuid = PatientIdUuid16,

.pCharacteristicHandles = &characteristicHandles,

// Pointer to the attribute's 16-bit UUID
.attributes.p_uuid = NULL,

// Pointer to the attribute metadata structure
.attributes.p_attr_md = NULL,

// Initial attribute value length in bytes
.attributes.init_len = 4,

// Initial attribute value offsset in bytes. If different from zero, the
// first init_offs bytes of the attribute value will be left uninitialized.
.attributes.init_offs = 0,

// Maximum attribute value length in bytes.
.attributes.max_len = MAX_PATIENT_ID_LENGTH,

// Pointer to the attribute data/value.
.attributes.p_value = patientId,

// Security Mode (1 or 2), 0 for no permissions at all.
.attributeMetaData.read_perm.sm = SECURITY_MODE,

// Level (1, 2, 3 or 4), 0 for no permissions at all.
.attributeMetaData.read_perm.lv = SECURITY_LEVEL,

// Security Mode (1 or 2), 0 for no permissions at all.
.attributeMetaData.write_perm.sm = SECURITY_MODE,

// Level (1, 2, 3 or 4), 0 for no permissions at all.
.attributeMetaData.write_perm.lv = SECURITY_LEVEL,

// Variable length attribute
.attributeMetaData.vlen = 1,

// Value location, see @ref BLE_GATTS_VLOCS.
.attributeMetaData.vloc = BLE_GATTS_VLOC_STACK,

// Read authorization and value will be requested from the application on
// every read operation (that means a read will generate an event).
.attributeMetaData.rd_auth = 1,

// Write authorization will be requested from the application on every
// Write Request operation (but not Write Command).
.attributeMetaData.wr_auth = 0,

// Broadcasting of the value permitted.
.properties.broadcast = 0,

// Reading OK
.properties.read = 1,

// Writing the value with Write Command permitted
.properties.write_wo_resp = 0,

// Writing the value with Write Request permitted.
.properties.write = 1,

// Notification of the value permitted.
.properties.notify = 0,

// Indications of the value permitted.
.properties.indicate = 0,

// Writing the value with Signed Write Command permitted.
.properties.auth_signed_wr = 0,

// Characteristic Properties.

.characteristicMetaData.char_props.read = 1,
.characteristicMetaData.char_props.write = 1,
.characteristicMetaData.char_props.write_wo_resp = 0,
.characteristicMetaData.char_props.notify = 0,
.characteristicMetaData.char_props.indicate = 0,
.characteristicMetaData.char_props.broadcast = 0,
.characteristicMetaData.char_props.write_wo_resp = 0,

//Characteristic Extended Properties.
.characteristicMetaData.char_ext_props = 0,

// Pointer to a UTF-8 encoded string (non-NULL terminated),
// NULL if the descriptor is not required.
.characteristicMetaData.p_char_user_desc = USER_DESCRIPTION,

// The maximum size in bytes of the user description descriptor.
.characteristicMetaData.char_user_desc_max_size = strlen( USER_DESCRIPTION ),

// The size of the user description, must be smaller or equal to
// char_user_desc_max_size.
.characteristicMetaData.char_user_desc_size = strlen( USER_DESCRIPTION ),

// Pointer to a presentation format structure
// or NULL if the CPF descriptor is not required.
.characteristicMetaData.p_char_pf = NULL,

// Attribute metadata for the User Description descriptor,
// or NULL for default values.
.characteristicMetaData.p_user_desc_md = NULL,

// Attribute metadata for the Client Characteristic Configuration Descriptor,
// or NULL for default values.
.characteristicMetaData.p_cccd_md = NULL,

// Attribute metadata for the Server Characteristic Configuration Descriptor,
// or NULL for default values.
.characteristicMetaData.p_sccd_md = NULL
};

After creating the custom service gets the custom characteristics, I add them using this code:

static void AddCharacteristicToNeoneur( bleAttribute* newAttribute)
{
ret_code_t errorCode;
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t char_uuid;
ble_gatts_attr_md_t attr_md;

BLE_UUID_BLE_ASSIGN(char_uuid, newAttribute->shortUuid);

ble_uuid128_t base_uuid = newAttribute->longUuid;

// Add the UUID to the BLE stack (it gets assigned "type" which is really
// and index for this particular UUID).
errorCode = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
APP_ERROR_CHECK(errorCode);

cccd_md = newAttribute->attributeMetaData;
char_md = newAttribute->characteristicMetaData;
char_md.p_cccd_md = &cccd_md;

attr_md = newAttribute->attributeMetaData;


attr_char_value = newAttribute->attributes;

attr_char_value.p_uuid = &char_uuid;
attr_char_value.p_attr_md = &attr_md;


errorCode = sd_ble_gatts_characteristic_add(neoneurService.serviceHandle,
&char_md,
&attr_char_value,
newAttribute->pCharacteristicHandles);

APP_ERROR_CHECK(errorCode);
}

Now, as long a SECURITY_MODE = 1 and SECURITY_LEVEL = 1, everything works great. A central device can connect up and read/write characteristics.

BUT... as soon as I change to SECURITY_MODE = 1 and SECURITY_LEVEL = 2,  sd_ble_gatts_characteristic_add() starts throwing an Invalid Param error.

Of course, this error code doesn't give me any insight as to which parameter is invalid. And because sd_ble_gatts_characteristic_add() is down in the softdevice

I can't use the debugger to trace the code. Did some googling and the usual explanation is some mismatch between metadata values, but that still doesn't give 

me enough insight to know what is misaligned.

Any help will be greatly appreciated.

Ed H.

Parents Reply Children
No Data
Related