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

Service Event Double Trigger

Hello,

I have 2 custom service running each with one characteristic. When data is written to the characteristic one (io_controle.c) the write event is triggered twice. The other characteristic (device_info.c) works as expected with only one trigger.

The service init function

/**@brief Function for initializing the . */
uint32_t ble_io_controle_service_init(
		ble_io_controle_service_t * p_service,
		const ble_io_controle_service_init_t * p_service_init) {

	uint32_t err_code;
	ble_uuid_t ble_uuid;

	// Initialize service structure
	p_service->evt_handler = p_service_init->evt_handler;
	p_service->conn_handle = BLE_CONN_HANDLE_INVALID;

	// Add a custom base UUID.
	ble_uuid128_t bds_base_uuid = IO_CONTROLE_SERVICE_UUID;
	// uint8_t       uuid_type;
	err_code = sd_ble_uuid_vs_add(&bds_base_uuid, &p_service->uuid_type);
	if (err_code != NRF_SUCCESS) {
		SEGGER_RTT_printf(0, "[%s %s %d]error: %d\n\r",__FILE__,__func__,__LINE__,err_code);
		return err_code;
	}
	ble_uuid.type = p_service->uuid_type;
	ble_uuid.uuid = IO_CONTROLE_SERVICE;

	// Add dfu service
	err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_service->service_handle);
	if (err_code != NRF_SUCCESS) {
		SEGGER_RTT_printf(0, "[%s %s %d]error: %d\n\r",__FILE__,__func__,__LINE__,err_code);
		return err_code;
	}

	// Add DFU characteristic
	ble_gpio_state_t gpio0_state_initial_value = p_service_init->ble_gpio0_initial_value;

	uint8_t gpio0_state_encoded_value[sizeof(ble_gpio_state_t)];
	ble_add_char_params_t gpio0_state_params;
	memset(&gpio0_state_params, 0,sizeof(gpio0_state_params));

	gpio0_state_params.uuid 				= IO_CONTROLE_GPIO0;
	gpio0_state_params.uuid_type 			= ble_uuid.type;
	gpio0_state_params.max_len 				= sizeof(ble_gpio_state_t);
	gpio0_state_params.init_len 			= ble_gpio_state_encode(&gpio0_state_initial_value, gpio0_state_encoded_value);
	gpio0_state_params.p_init_value 		= gpio0_state_encoded_value;
	//gpio0_state_params.char_props.notify 	= 1;
	gpio0_state_params.char_props.read	= 1;
	gpio0_state_params.char_props.write	= 1;
	//gpio0_state_params.cccd_write_access 	= SEC_OPEN;
	gpio0_state_params.read_access 	= SEC_OPEN;
	gpio0_state_params.write_access 	= SEC_OPEN;
	// 1 for variable length and 0 for fixed length.
	gpio0_state_params.is_var_len = 1;

	err_code = characteristic_add(p_service->service_handle,
			&gpio0_state_params,
			&(p_service->ble_gpio0_state_handles));
	if (err_code != NRF_SUCCESS) {
		SEGGER_RTT_printf(0, "[%s %s %d]error: %d\n\r",__FILE__,__func__,__LINE__,err_code);
		return err_code;
	}

	return NRF_SUCCESS;
}


 
Debug Printout
 0> [./service_hal.c device_info_evt_handler 37]BLE_DEVICE_INFO_DFU_EVT_WRITE 0x01 //works fine
 0> [./service_hal.c io_controle_evt_handler 53]BLE_IO_CONTROLE_GPIO0_EVT_WRITE 0x01 //first write
 0> [./service_hal.c io_controle_evt_handler 53]BLE_IO_CONTROLE_GPIO0_EVT_WRITE 0x01 //same write



io_controle.c is effectively a copy paste of device_info.c.

I know I am overlooking something simple but I have spent more time than I'm willing to admit compering the files.

In later versions of the code device_info.c has the same bug.

Attached is a project to replicate the bug.

Additional info
SDK 15.3
Compiler: GNU Tools ARM Embedded 7 2018-q2-update (7.3.1)
Device: nRF52832

Regards

svr_template_test.zip

Parents
  • Hi Luloff, 

    I think it is because you have added the 

    BLE_IO_CONTROLE_SERVICE_DEF(io_controle);
    macro to service_hal.h. Which is included in both the service_hal.c and main.c. This means that the 
    NRF_SDH_BLE_OBSERVER macro will register the ble_io_controle_service_on_ble_evt callback twice. 
    You should add it the same way as BLE_DEVICE_INFO_SERVICE_DEF, i.e. in service_hal.c.
    Best regards
    Bjørn
Reply
  • Hi Luloff, 

    I think it is because you have added the 

    BLE_IO_CONTROLE_SERVICE_DEF(io_controle);
    macro to service_hal.h. Which is included in both the service_hal.c and main.c. This means that the 
    NRF_SDH_BLE_OBSERVER macro will register the ble_io_controle_service_on_ble_evt callback twice. 
    You should add it the same way as BLE_DEVICE_INFO_SERVICE_DEF, i.e. in service_hal.c.
    Best regards
    Bjørn
Children
  • Hi Bjørn,

    I have move all the code that interface with services and characteristics handles to the service_hal.c files (this is in the main app). The macro is still in the .h file. The only global data is the information that will get sent to the service.

    Making the veritable static broke the definitions in main.c. The characteristics had garbage in as there init values.

    PS: Can I ask you to use my screen name please as this is a public ticket.

    Regards

Related