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

Unable to Send Messages NRF52 BLE Central Custom Device

Currently I am using the NRF52 device to connect with a custom peripheral. The current goal I am trying to reach is toggling an LED by sending the command 0x8900 through Service UUID 0x0001 with Characterisic ID 0x0002.
This is a write command that I have tested using the LightBlue phone app. The app successfully toggles the peripheral LED.

I began with the BLE UART Central code and modified the NUS service routine to be custom. The terminal shown below is the output I receive when pair and discover the device.

Terminal Output

I assign the write characteristic 0x0002 with Handle value 0x000E to the TX Handler. Once completed I initiate a message that is sent successfully.

The function for the message send code is here:

uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)

{ int i; VERIFY_PARAM_NOT_NULL(p_ble_nus_c);

if (length > BLE_NUS_MAX_DATA_LEN)
{
    return NRF_ERROR_INVALID_PARAM;
}
if ( p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
{
    return NRF_ERROR_INVALID_STATE;
}

const ble_gattc_write_params_t write_params = {
    .write_op = BLE_GATT_OP_WRITE_CMD,
    .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
    .handle   = p_ble_nus_c->handles.nus_control_handle,
    .offset   = 0,
    .len      = length,
    .p_value  = p_string
};
	printf("\r\nMessage: %02x ",write_params.write_op);
	printf("%02x ",write_params.flags);
	printf("%02x ",write_params.handle >> 8);
	printf("%02x ",write_params.handle & 0x00FF);
	printf("%02x ",write_params.offset >> 8);
	printf("%02x ",write_params.offset & 0x00FF);
	printf("%02x ",write_params.len >> 8);
	printf("%02x ",write_params.len & 0x00FF);

	for(i=0; i<  write_params.len;i++)
	{
			printf("%02x ",write_params.p_value[i]);
	}
	printf("\r\n");
	
return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);

}

The message is a length of two bytes simply containing 0x8900. I am extremely new to BLE and don't know what the proper development steps are to prove that each step in the setup is performing properly. I do believe that the discovery and pairing is working correctly.

It just doesn't seem like the function sd_ble_gattc_write() is working correctly with the parameters I am passing in. Please let me know if the information I provided is not helpful. I can add anything that may be of value.

Additional Information 1: I changed the write from BLE_GATT_OP_WRITE_CMD to BLE_GATT_OP_WRITE_REQ and printed out the value in p_ble_evt->evt.gattc_evt.gatt_status from the response.

The GATT Status is 0x0105 which corresponds to BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION. I am working on resolving this at the moment. I appreciate any input.

  • It looks like your characteristics are not "open" but they have certain permissions set on ATT/GATT layer and your connection doesn't have authorization (typically didn't pass some Security Manager pairing/bonding procedure).

  • I am working on solving the permission issue, but I am not having any luck. I am trying to call:

    error = sd_ble_gap_authenticate(p_ble_evt->evt.gattc_evt.conn_handle, &security_params);

    When I receive the security failure. I am leaning towards implementing the Peer Manager software. It appears that the peer manager performs the security and bonding that is not included in the UART BLE example. Does this seem like good route to take?

  • Hard to say when not seeing what is really happening on BLE radio but if you are not sure if pairing is completed in your custom code then using peer_manager module from SDK might help. I personally don't us it but if you are starting from scratch it might be the fastest route.

  • Since both the LightBlue app and the nRF connect app can immediately discover all of the services and perform any operation I don't believe that a security issue is occurring. I don't think that I need anything in that realm.

    I have discovered two services, but I have not called:

    uint32_t characteristic_add(uint16_t service_handle, ble_add_char_params_t * p_char_props, ble_gatts_char_handles_t * p_char_handle)

    with either of them. Is this a step that has to occur before I can start writing to the characteristics? It just seems like I have discovered them, but as you said they are not 'open'. It has to be something on my end.

  • Well my assumption that GATT object you are targeting requires some pairing step which you haven't pass is based on BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION error you get as Write result. The fact that mobile apps are OK can be simply caused by proper pairing of your device with that phone. Now when I look into nRF5 SDK v13 there is an example .\examples\ble_central\ble_app_multilink_central\client_handling.c where BLE event handler contains following code:

    //...
    
Related