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.

  • //..

    case BLE_GATTC_EVT_WRITE_RSP:
                if ((p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION) ||
                    (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION))
                {
                    uint32_t err_code = dm_security_setup_req(&p_client->handle);
                    APP_ERROR_CHECK(err_code);
                }
                on_evt_write_rsp(p_ble_evt, p_client);
                break;
    

    So if you are using Device Manager module or your own code to manage link security it should be solved there. But as I said it's hard to debug something through the forum posts just based on few lines of code and UART debug (not saying I do want your full project, I don't have time to run it and debug for you anyway;)

  • After more trial and error I believe that the problem is that the connection is paired, but not bonded. The custom device requires bonding. The iOS and Android phones all bond automatically. I am going to move forward with attempting to implement the peer_manager to handle the bonding.

  • Thank you for all of your help endnode. I solved the issue several minutes ago.

    The issue was solved by adding all of the peer_manager code that was included in the HRS demo. With this the bonding would occur quite easily. Once bonded the commands worked immediately.

    I will note that if anyone has trouble bonding you have to make sure to remove the handling of

    BLE_GAP_EVT_SEC_PARAMS_REQUEST by the on_ble_evt event handler. Both the event handler and peer_manager were trying to respond to the event causing the processor to reset. This took me several hours to figure out. The peer manager handles all of the security requests.

  • Glad to help and good to hear that peer_manager works well for you!

Related