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

When to call sd_ble_gatts_hvx

Hello

I am using Android and BLE communication with nRF52832 (BLENano2) now.

I am using SDK 15.0.0 with keil uversion.

Central is Android and peripheral is nRF52832.

Use the SDK "ble_app_blinky".

I now want to send arbitrary data from peripheral to central.

So I added a characteristic based on "ble_app_blinky".
The following program was created for that characteristic.

uint32_t send_value(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t sensor_value)
{
	
	if (p_lbs == NULL)
    {
        return NRF_ERROR_NULL;
    }
		
	
	uint32_t err_code = NRF_SUCCESS;
	ble_gatts_value_t gatts_value;
	
	// Initialize value struct.
  memset(&gatts_value, 0, sizeof(gatts_value));

	gatts_value.len     = sizeof(uint8_t);
  gatts_value.offset  = 0;
  gatts_value.p_value = &sensor_value;

	// Update database.
  err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_ALL,////////////
                                      p_lbs->sensor_char_handles.value_handle,
                                      &gatts_value);

	
		
		if (err_code != NRF_SUCCESS)
		{
				return err_code;
		}


	
	// Send value if connected and notifying.
    if ((conn_handle != BLE_CONN_HANDLE_INVALID)) 
    {
        ble_gatts_hvx_params_t hvx_params;

        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_lbs->sensor_char_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        hvx_params.p_len  = &gatts_value.len;
        hvx_params.p_data = gatts_value.p_value;

        err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }
		return err_code;
}

By calling this "send_value" function
It turned out that a value is set by "sd_ble_gatts_value_set" and a value is notified by "sd_ble_gatts_hvx".

There is something I do not understand here, but I want to know when to call this function.

I found out that I have to be called when notification is enabled.

How should I program when notification is valid?

Please give me an answer

Parents
  • You can call it whenever you want to update the value of a characteristic and send it to the client.

    There are no preconditions to be able to call the function. Whether it actually sends the notification and returns success that's another question.

    How should I program when notification is valid?

    I don't understand that question.

    You should read the documentation for sd_ble_gatts_hvx(). It explains what it does very clearly. In a nutshell, it will send a notification as long as all the parameters have been setup correctly and there's space in the notification buffer (and there's a connection with notifications enabled) or otherwise it will update the attribute table (what sd_ble_gatts_value_set() does) when there's no connection or the notifications are not enabled.

    You don't need to call sd_ble_gatts_value_set() beforehand.

Reply
  • You can call it whenever you want to update the value of a characteristic and send it to the client.

    There are no preconditions to be able to call the function. Whether it actually sends the notification and returns success that's another question.

    How should I program when notification is valid?

    I don't understand that question.

    You should read the documentation for sd_ble_gatts_hvx(). It explains what it does very clearly. In a nutshell, it will send a notification as long as all the parameters have been setup correctly and there's space in the notification buffer (and there's a connection with notifications enabled) or otherwise it will update the attribute table (what sd_ble_gatts_value_set() does) when there's no connection or the notifications are not enabled.

    You don't need to call sd_ble_gatts_value_set() beforehand.

Children
  • Thank you for reply!

    We want to call the "send_value" function every second using a timer.
    Created a timer to call "send_value". "app_timer_start" to main () 's advertising_start ();
    If you write immediately after and execute, "nRFConnect" will not be able to SCAN. I can not find the peripheral when I try to scan.
    Therefore, I can not think that it is always good to call it. Is there any cause?

  • "app_timer_start" to main () 's advertising_start ();

    What?

    If you write immediately after and execute, "nRFConnect" will not be able to SCAN. I can not find the peripheral when I try to scan.

    What do you mean with write and execute? If you can't find the peripheral with nRF Connect that means that the device is not advertising. You should investigate why this is the case.

Related