This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Inserting a custom service/characteristic into Central/Peripheral example

I've been playing around with the multi-central central/peripheral examples and I thought I would modify the peripheral to instead use a service I had written for another application, but simply notifies with one byte as the example does.

Not really understanding a great deal of the configuration finer points from the peripheral example, I copied over the service and characteristic initialisation from main.c and used it in place of my original in core_service.c where my service and service functions reside.

It all works fine, with the timer triggering a TWI read which then has a callback to get the data and pass it to the function that updates the characteristic. When it hits the sd_ble_gatts_hvx() it errors out. For some reason it won't send the error over UART, so I debugged to read the error code (0x00003003).

I understand this error is something to do with attribute handles, but as far as I can see it's all set up correctly and should be working fine.

Below is a copy of the service initialisation and the characteristic update function.

void core_service_init(void)
{
   

    uint32_t            err_code;
	
    ble_uuid_t          service_uuid;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr;
    ble_gatts_attr_md_t attr_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_md_t char_ud_md;
    uint16_t            svc_test;

    static uint8_t peripheral_data;
    static uint8_t peripheral_ud[] = "Modifiable multilink_peripheral Data";

    ble_uuid128_t base_uuid = BLE_UUID_CORE_BASE_UUID;

    err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
    APP_ERROR_CHECK(err_code);

    service_uuid.uuid = BLE_UUID_CORE_SERVICE;

    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, 
										&service_uuid, 
										&m_core_service.service_handle);
    APP_ERROR_CHECK(err_code);
	
	// characteristic setup //

    service_uuid.uuid = BLE_UUID_RH_CHAR_UUID;

    memset(&attr, 0, sizeof(ble_gatts_attr_t));
    attr.p_uuid    = &service_uuid;
    attr.p_attr_md = &attr_md;
    attr.max_len   = 1;
    attr.p_value   = &peripheral_data;
    attr.init_len  = sizeof(peripheral_data);

    memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
    attr_md.vloc = BLE_GATTS_VLOC_STACK;
    attr_md.vlen = 0;

    memset(&cccd_md, 0, sizeof(ble_gatts_attr_md_t));
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
    cccd_md.vloc = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
    char_md.p_cccd_md               = &cccd_md;
    char_md.char_props.notify       = 1;
    char_md.char_props.indicate     = 1;
    char_md.char_props.read         = 1;
    char_md.char_props.write        = 1;
    char_md.char_ext_props.wr_aux   = 1;
    char_md.p_user_desc_md          = &char_ud_md;
    char_md.p_char_user_desc        = peripheral_ud;
    char_md.char_user_desc_size     = (uint8_t)strlen((char *)peripheral_ud);
    char_md.char_user_desc_max_size = (uint8_t)strlen((char *)peripheral_ud);

    memset(&char_ud_md, 0, sizeof(ble_gatts_attr_md_t));
    char_ud_md.vloc = BLE_GATTS_VLOC_STACK;
    char_ud_md.vlen = 1;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_ud_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_ud_md.write_perm);

    err_code = sd_ble_gatts_characteristic_add(BLE_GATT_HANDLE_INVALID,
                                               &char_md,
                                               &attr,
                                               &m_core_service.rh_handles);
	
	// initialise timer
	timer_init();
}

The characteristic update/notify function

static void sensor_rh_characteristic_update(uint32_t * p_char_value)
{
	uint32_t err_code;
	
    // Update characteristic value
	if (m_core_service.conn_handle != BLE_CONN_HANDLE_INVALID)
	{
		uint16_t len = 1;
		
		ble_gatts_hvx_params_t hvx_params;
		memset(&hvx_params, 0, sizeof(hvx_params));

		hvx_params.handle = m_core_service.rh_handles.value_handle;
		hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
		hvx_params.offset = 0;
		hvx_params.p_len  = &len;
		hvx_params.p_data = (uint8_t*)p_char_value; //characteristic_value;  

		err_code = sd_ble_gatts_hvx(m_core_service.conn_handle, &hvx_params);
		APP_ERROR_CHECK(err_code);
	}    
	
}
Parents Reply Children
No Data
Related