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

no BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL

I'm handling the entire prepared write sequence myself, returning NULL for the memory request and dealing with the Prepare Write and Exec Write etc.

I found that if I send back an error during a Prepare Write (in this case I'm sending the Insufficient Resources error) that gets sent to the client correctly and the client then sends a Execute Write Request with the 'Cancel All' flags set. I can see this on the sniffer.

However I don't receive the BLT_GATTS_OP_EXEC_WRITE_REQ_CANCEL rw_auth event. Firstly I'm logging all events and secondly I have a breakpoint right on the line and it's not hit.

switch( write_request->op )
	{
		case BLE_GATTS_OP_WRITE_REQ:
		case BLE_GATTS_OP_WRITE_CMD:
		case BLE_GATTS_OP_SIGN_WRITE_CMD:
			// send an internal write event for all these
			status = rdk_ble_events_send_internal_write( write_request );
			if( status == RDK_BLE_EVENTS_NOT_HANDLED )
				status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED;
			break;

		case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL:
			// cancel the queue and return success
			rdk_ble_events_clear_prepared_write_info(); // <-- breakpoint not hit
			status = BLE_GATT_STATUS_SUCCESS;
			break;

		case BLE_GATTS_OP_PREP_WRITE_REQ:
			status = rdk_ble_events_handle_prepare_write( write_request );
			break;

I was expecting the sequence would finish with either a Commit or a Cancel and expected to do some cleanup in the cancel handler.

Is this expected? The only reason I can think of for not receiving the event is that I've returned an error for one of the prepared writes, the stack at that point internally marks this prepared write as errored and complete and when the Cancel All comes in from the client, it thinks there's no prepared write going on, so it doesn't send me the event.

I can work around it by cleaning up at the time I send the error, but I'd like to know if I should be getting the cancel event or not.

  • @RK: I'm sorry for the late response. We were pretty busy on the training to prepare for the "game changer" in the last few days :)

    I tried to reproduce the sequence you mentioned but not quite successful.

    Attached is the sniffer trace and the test code. What I got was just the "Rcvd Error Response with Insufficient Resource" after Immediately Write All. I don't think there will be any event after the reply on BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST.

    If what I did was not what you were doing could you send me a sniffer trace ?

    The trace:

    test1.pcapng

    Test Code (SDK v8.1):

    ble_app_uart - LongWrite.zip

  • Here's a pcap and a log from the app. The log logs every SOC and every BLE event from the softdevice, doesn't log the replies, just the events. It also logs some internal events I generate myself which you can ignore. The interesting handle here is 0x0019 which has a max length of 24 bytes.

    There are three writes attempted to it. The first is a normal short write of 20 bytes, the SD emits a rw_auth request which is confirmed. No problem.

    The second is a 21 byte write, we get the user mem request, a prepare write with 18 bytes, a prepare write with 3 bytes and a write now request. That is also ok-ed. You can see the two prepares and the write now both in the event log and on the pcap. Similarly - no problem.

    The third write is 26 bytes long, which is too long. You see the same sequence of events, user mem, prepared write with 18 bytes then prepared write with 8 bytes. That second prepared write request is failed, I return 'insufficient resources' because there's no buffer space to write it. (note I would return prepared write queue full if I could but that return isn't available, so insufficient resources is returned).

    It's what happens now that I was asking about. You can see on the pcap that the client (iOS in this instance) receives the error on the prepared write and sends a 'cancel all'. It then re-reads the handle just because that's what lightblue does after a write. However the softdevice never sends the cancel all event, you can see that from the text log, the next thing I get is the read request.

    My question was, why doesn't the cancel all event get sent? Is it because I've already replied to a prepare write request with an error so internally the softdevice has 'cancelled' that long write and so when it gets the cancel from the client, it has no current long write to cancel, so it just eats the event? Or is it something else? I'm very confident that the logging code would have logged it if it came in and breakpointing in the cancel all code never gets hit.

    I expected every prepared write sequence would end with either a Write All or a Cancel All event from the SD, however it seems that's not the case. Just want to know if that's expected after I send an error reply to a prepared write, or a bug.

    Note: highly useful wireshark filter for this is "btle.data_header.length > 0

    "Capture1.txt

    Capture1.pcapng

  • @RK: Thanks for your trace. I was testing with the dongle on PC so there was no CANCEL ALL execute write request in my case. I managed to reproduce here with iOS device, and confirmed the missing of the event.

    Could be a bug with our stack, we are doing some investigation on this and will let you know when we have an update.

  • Great - thanks - it's quite easy to work around, I do my clean up either when I send an error, when I get a cancel or if I miss all those, when a new request starts. However it would be good to find out what the proper sequence should be. I haven't yet tried doing a real cancel (because that's harder to engineer) ie doing a few prepares which succeed, but cancelling the write instead of committing it from the client side. I hope at least in that case the cancel comes.

    Will wait to see what you find. I can open a case if you'd like to track it 'officially' - let me know.

  • Hi all,

    This has been confirmed as an issue in the SD. A fix for this is being worked on.

    Thanks for reporting and investigating!

    Carles

Related