To enable comparability with an existing client, I'm attempting to configure the nRF51822 to provide a GAP service that includes user description descriptors (UUID 0x2901) for both the device name and appearance characteristics.
I have tried to accomplish this in two different ways:
- Adding an additional user description descriptor after calling
sd_ble_gap_device_name_set()
void gap_params_init(void) {
uint32_t err_code;
ble_gap_conn_sec_mode_t sec_mode;
ble_gatts_attr_t attr;
ble_gatts_attr_md_t attr_md;
ble_uuid_t uuid;
uint16_t desc_handle;
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
err_code = sd_ble_gap_device_name_set(&sec_mode, (uint8_t *)deviceName, strlen(deviceName));
APP_ERROR_CHECK(err_code);
/* We now add a descriptor attribute for the user description of the device
* name. Here we configure its attribute's metadata to allow open reads but
* no writes. */
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
/* Indicate the that attribute is a user description descriptor */
BLE_UUID_BLE_ASSIGN(uuid, BLE_UUID_DESCRIPTOR_CHAR_USER_DESC);
/* Configure the value of the attribute. */
memset(&attr, 0, sizeof(attr));
attr.p_uuid = &uuid;
attr.p_attr_md = &attr_md;
attr.init_len = 11;
attr.init_offs = 0;
attr.max_len = 11;
attr.p_value = (uint8_t *)"Device Name";
err_code = sd_ble_gatts_descriptor_add(BLE_GATT_HANDLE_INVALID, &attr, &desc_handle);
APP_ERROR_CHECK(err_code);
In this case, the sd_ble_gatts_descriptor_add(BLE_GATT_HANDLE_INVALID, attr, &desc_handle)
call returns NRF_ERROR_FORBIDDEN
.
- Creating the GAP service myself:
void gap_params_init(void) {
uint32_t err_code;
ble_gatts_char_md_t char_md;
ble_gatts_attr_t attr;
ble_gatts_attr_md_t attr_md;
ble_uuid_t uuid;
uint16_t service_handle;
uint16_t char_handle;
/* Create the GAP service */
BLE_UUID_BLE_ASSIGN(uuid, BLE_UUID_GAP);
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service_handle);
APP_ERROR_CHECK(err_code);
/* We add two characteristics to the GAP serivce: */
/* The first characteristic is the device name, which should be read-able.
* Here, we use the characteristics metadata to make the device name
* characteristic readable. We also add a user description field stating
* what the characteristic represents. */
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.p_char_user_desc = (uint8_t *)"Device Name";
char_md.char_user_desc_max_size = 11;
char_md.char_user_desc_size = 11;
char_md.p_user_desc_md = NULL;
char_md.p_char_pf = NULL;
char_md.p_cccd_md = NULL;
char_md.p_sccd_md = NULL;
/* The attribute is the part of the characteristic that holds data, in this
* case, the device's actual name. Here we configure its attribute's
* metadata to allow open reads but no writes. */
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
/* Set the UUID of the device name attribute correctly */
BLE_UUID_BLE_ASSIGN(uuid, BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME);
/* Configure the device name attribute itself */
memset(&attr, 0, sizeof(attr));
attr.p_uuid = &uuid;
attr.p_attr_md = &attr_md;
attr.init_len = strlen(deviceName);
attr.init_offs = 0;
attr.max_len = strlen(deviceName);
attr.p_value = (uint8_t *)deviceName;
/* Finally, add the device name characteristic to the GAP service */
err_code = sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr, &char_handle);
APP_ERROR_CHECK(err_code);
/* Appearance characteristic would be added here */
In this case, the sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &service_handle)
call returns NRF_ERROR_FORBIDDEN
.
Can anyone suggest how to solve this problem?