I have a custom BLE characteristic that I want to use to allow an app to send commands to my device. I use an on-write() function that is called whenever a BLE_GATTS_EVT_WRITE event happens to detect the write to the command characteristic and process the command. The characteristic is set up to use my own data buffer instead of one within the BLE stack (called commandJSON). See code below.
The problem is that, while I'm processing one command, another command can come in and overwrite the one I'm working on. What is the "correct" way to prevent this from happening?
I'm using SDK 15.3.0 and the S140 soft device.
static void on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
NRF_LOG_INFO("on_write() called. Event write handle is = %d\r\n", p_evt_write->handle);
// Handle writes to json command characteristic
if (p_evt_write->handle == p_cus->custom_value_json_command_handles.value_handle)
NRF_LOG_DEBUG("Write to JSON command characteristic.");
commandJSON[p_evt_write->len] = 0; // Add a null terminator
It shouldn't be possible for a command to override "itself" like this. What I think is happening, is that when you are processing the JSONcommand, your application thinks that the on_write function is finished, and sends the next one. You should add a check of some kind that makes sure that you're finished parsing the first command before calling the on_write(); function again. So add a WAIT_FOR_FINISHED check that confirms that whatever the last function that finishes up processing your command is complete.
Thanks for the reply.
Are you suggesting I use a second characteristic to allow the App to be notified when it is okay to send another command?
I've changed the implementation so that once I've parsed and processed the JSON command I write a zero into the first byte of commandJSON. On the app side I read the command characteristic after I've written the JSON command to it to look for the zero byte and when I see it I know that the previous command has been processed and I can go ahead and send the next command. This works in that it synchronizes the writing of commands and the processing of them however it is extremely slow.
I figure there must be a better way.
I thought about moving data into a circular buffer from the commandJSON buffer so that it is removed quickly but I still would not be guaranteed that it doesn't get overwritten before I complete the transfer to the circular buffer.
What exactly in your process is it that's going slowly now? In order to make sure your writing procedure doesn't get overwritten you'll have to give some sort of signal in order to let the next command being written.