Hi,
I implemented two services, now I have the following problem. Each service is working standalone, but when I put both together only the first initialized service works. The other service returns inconsistent err_codes by the function sd_ble_gatts_hvx (5,7,4).
static void char_add(const uint8_t uuid_type)
{
uint32_t err_code;
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;
uint8_t * char_user_desc_string = "Localization Notification";
memset(&cccd_md, 0, sizeof(cccd_md));
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);
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.notify = 1;
char_md.char_props.indicate = 1;
char_md.p_char_user_desc = char_user_desc_string;
char_md.char_user_desc_size = strlen(char_user_desc_string);
char_md.char_user_desc_max_size = char_md.char_user_desc_size;
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 = uuid_type;
ble_uuid.uuid =LOCAL_CHAR_UUID;
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;
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(uint8_t)*2;
attr_char_value.init_offs = 0;
attr_char_value.max_len = APP_CFG_CHAR_LEN;
attr_char_value.p_value = m_char_value;
err_code = sd_ble_gatts_characteristic_add(m_service_handle,
&char_md,
&attr_char_value,
&m_char_handles);
APP_ERROR_CHECK(err_code)};
Here is the characteristic of the second:
static uint32_t acc_service_add_characteristic(inertial_service_t *inertial_service, const inertial_service_init_t * p_inertial_service_init)
{
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;
ble_gatts_char_pf_t char_presentation_format;
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_STACK;
memset(&char_md, 0, sizeof(char_md));
uint8_t * p_char_user_desc_string = "Acceleration";
char_md.char_props.read = 1;
char_md.char_props.notify = 1;
char_md.char_props.indicate = 1;
char_md.p_char_user_desc = p_char_user_desc_string;
char_md.char_user_desc_size = strlen(p_char_user_desc_string);
char_md.char_user_desc_max_size = char_md.char_user_desc_size;
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_inertial_service->uuid_type;
ble_uuid.uuid = INERTIAL_SERVICE_UUID_ACC_CHARACTERISITC;
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;
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(uint8_t)*2;
attr_char_value.init_offs = 0;
attr_char_value.max_len = sizeof(inertial_service_acc_characteristic_data_t);
attr_char_value.p_value = NULL;
return sd_ble_gatts_characteristic_add(p_inertial_service->acc_service_handle, &char_md,
&attr_char_value,
&p_inertial_service->acc_chararcteristic_handles);
}
When I make the request update the device trys to retry the connection twice and then disconnect. Maybe I'am looking in the wrong section. Thanks for your advice :)
Here is the notifcation of the first service
static void inertial_service_timer_handler(void * p_context){
ble_gatts_hvx_params_t params;
lsm9ds0_sensor_data_t sensor_data;
static inertial_service_acc_characteristic_data_t acc_characteristic_data = {0,0};
if(!m_inertial_service.acc_test_pattern){
m_inertial_service.acc_test_pattern_counter=0;
lsm9ds0_get_output_acc(&sensor_data);
} else {
uint32_t ticks = m_inertial_service.acc_test_pattern_counter;
app_timer_cnt_get(&ticks);
sensor_data.x = (ticks & 0xffff) - 0x7fff;
sensor_data.y = ((ticks + 0x4000) & 0xffff) - 0x7fff;
sensor_data.z = ((ticks + 0x2000) & 0xffff) - 0x7fff;
m_inertial_service.acc_test_pattern_counter++;;
}
acc_characteristic_data.data[acc_characteristic_data.cnt].x = sensor_data.x; //Discard lower byte
acc_characteristic_data.data[acc_characteristic_data.cnt].y = sensor_data.y;
acc_characteristic_data.data[acc_characteristic_data.cnt].z = sensor_data.z;
acc_characteristic_data.cnt++;
if(acc_characteristic_data.cnt == INERTIAL_SERVICE_ACC_CHARACTERISTIC_NUM_SENSOR_DATA){
uint16_t len_sensor_data = 2*sizeof(uint8_t) + sizeof(inertial_service_acc_sensor_data_t) * acc_characteristic_data.cnt;
nrf_gpio_pin_clear(LED_RED);
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = m_inertial_service.acc_chararcteristic_handles.value_handle;
params.p_data = (uint8_t*)&acc_characteristic_data;
params.p_len = &len_sensor_data;
uint32_t err = sd_ble_gatts_hvx(m_inertial_service.conn_handle, ¶ms);
//Increase sequence counter and reset data counter
acc_characteristic_data.sequence++;
acc_characteristic_data.cnt = 0;
nrf_gpio_pin_set(LED_RED);
}
}
and here the handler of the second service:
static void notification_timer_handler(void * p_context)
{
uint32_t err_code;
uint16_t len = 2*sizeof(uint8_t) + APP_CFG_CHAR_LEN;
timeout_handler(rssi_buffer);
uint8_t index = min_rssi_index(rssi_buffer);
ble_gatts_hvx_params_t hvx_params;
if(((memcmp(last_notification.addr.addr, rssi_buffer[index].addr.addr, BLE_GAP_ADDR_LEN) == 0) && abs(rssi_buffer[index].avg - last_notification.val) >= CHANGE_TRIGGER)
|| ((memcmp(last_notification.addr.addr, rssi_buffer[index].addr.addr, BLE_GAP_ADDR_LEN) != 0) && rssi_buffer[index].avg > last_notification.val))
{
memcpy(last_notification.addr.addr, rssi_buffer[index].addr.addr, BLE_GAP_ADDR_LEN );
last_notification.val = rssi_buffer[index].avg;
memcpy(&m_char_value, last_notification.addr.addr, BLE_GAP_ADDR_LEN);
m_char_value[BLE_GAP_ADDR_LEN] = last_notification.val;
memset(&hvx_params, 0, sizeof(hvx_params));
len = sizeof(uint8_t) * APP_CFG_CHAR_LEN;
hvx_params.handle = m_char_handles.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = 0;
hvx_params.p_len = &len;
hvx_params.p_data = m_char_value;
err_code = sd_ble_gatts_hvx(*p_conn_handle, &hvx_params);
//char_notify(*p_conn_handle);
}
}