I am getting an NRF_ERROR_INVALID_PARAM when calling sd_ble_gatts_characteristic_add. This is the 12th characteristic added and follows the same general style of numerous other characteristics. The documentation mentions constraints but does not explain what those are.
Here is my code
static uint32_t button_status_char_add(ble_service_t * p_service, const ble_service_init_t * p_service_init) { /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */ ble_gatts_char_md_t char_md; ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; ble_uuid_t ble_uuid; ble_gatts_attr_md_t attr_md;
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_USER;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.notify = 1;
char_md.char_props.read = 1;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = &cccd_md;
char_md.p_sccd_md = NULL;
ble_uuid.type = p_service->uuid_type;
ble_uuid.uuid = BLE_UUID_SERVICE_BUTTON_STATUS;
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
attr_md.vloc = BLE_GATTS_VLOC_USER;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 0;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = sizeof(ble_service_button_status_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = sizeof(ble_service_button_status_t);
attr_char_value.p_value = (uint8_t*) &(p_service->button_status);
return sd_ble_gatts_characteristic_add(p_service->service_handle,
&char_md,
&attr_char_value,
&p_service->button_status_handles);
/**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
}