Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Write with authorization of one byte results in UnlikelyError

Hi,

we configure a GATT Server with a characteristic that is configuered for write with authorization. If we then try to write one byte to this characteristic from the client, we get an ErrorResponse with UnlikelyError.

The Error seems to be send directly from the softdevice, since it is send even before we can handle the authorization request. If the characteristic is configuered for write without authorization it works fine, so do writes of multiple bytes. We also tried using NRFConnect on PC and Mobile as Clients to make sure its not caused by our client Firmware.

This only happened after we migrated from SDK12.2 with SoftDevice 3.1 to SDK15 with SoftDevice 6.1. If we revert to the old state it works.

If someone has an idea what could have been changed since SDK12.2 with Softdevice3.1 that could cause this issue, I would appreciate some help.

Best regards,

Niclas

Parents
  • Hi,

    Where exactly are you receiving this "ErrorResponse with UnlikelyError." ? What function?

  • Hi Sigurd,

    we can see the UnlikelyError in the ATT ErrorResponse over Bluetooth and it is reported by the nrfConnect App, when trying to write one byte.

    On the server we get no notification about this error or why it is happening, just the normal BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. If we then send the sd_ble_gatts_rw_authorize_reply we get a wrongState Error (most likely because the softdevice already ended the authorization request when sending the UnlikelyError).

    Even if we ignore the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, the error is sent immediately in the next connection event following the received write request.

    Thanks for looking into it.

    Best regards,

    Niclas

  • Hi,

    Have you enable the Service Changed characteristic? (NRF_SDH_BLE_SERVICE_CHANGED set to 1 in sdk_config)

    Could you try to "Refresh device cache" using nRF Connect ?

  • Hi Sigurd,

    yes we have enabled service changed.

    We normally use our own Client Firmware to do the write operation and just used nRF Connect to verify it's not caused by our Client FW. What exactly does Refresh device cache do with the server? Or is it just something for the nRF Connect Client?

    It would cause some hassle to rewrite the code again to work with nRFConnect and through our tests with multiple client-softwares we are confident it's not caused by the Client behaviour, so I want to make sure.

    Could you maybe also look into the softdevice code what even can cause an Unlikely Error, so we can look at those parts? As the name implies I imagine there can't be many occurences. Especially since it already triggered the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. I would think that all checks are done before sending the event, not after since it gets obsolete if a check fails and the authorisation procedure is canceled.

    Best regards,

    Niclas

  • Hi Sigurd,

    since there was no further answer to my question we tried to refresh the device cache, but it didn't work.

    If you have any other idea, what could cause this I would be grateful. Please also regard my other reply with the open question on softdevice behaviour.

    Thanks,

    Niclas

  • Hi,

    What exactly does Refresh device cache do with the server? Or is it just something for the nRF Connect Client?

    Smartphones will typically cache the attributes(service and characteristics) it discovered last time it connected to the BLE device(server). In that way, it doesn’t need to do the service discovery procedure each time it connects to a known device. Refresh device cache will clear/refresh this cache.

    1) Do you have a sniffer log showing the sequence of packets leading to this error? (nRF sniffer v2 link)

    2)

    we configure a GATT Server with a characteristic that is configuered for write with authorization

    Could you post some code that shows how the service and characteristic is configured?

    3)

    BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. If we then send the sd_ble_gatts_rw_authorize_reply we get a wrongState Error

    From the SD API doc, this means that there is either a "Invalid Connection State or no authorization request pending.". Could you post the code on how you use the sd_ble_gatts_rw_authorize_reply() ?

    4) You reproduced this with using nRF Connect for desktop as the central ?

Reply
  • Hi,

    What exactly does Refresh device cache do with the server? Or is it just something for the nRF Connect Client?

    Smartphones will typically cache the attributes(service and characteristics) it discovered last time it connected to the BLE device(server). In that way, it doesn’t need to do the service discovery procedure each time it connects to a known device. Refresh device cache will clear/refresh this cache.

    1) Do you have a sniffer log showing the sequence of packets leading to this error? (nRF sniffer v2 link)

    2)

    we configure a GATT Server with a characteristic that is configuered for write with authorization

    Could you post some code that shows how the service and characteristic is configured?

    3)

    BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. If we then send the sd_ble_gatts_rw_authorize_reply we get a wrongState Error

    From the SD API doc, this means that there is either a "Invalid Connection State or no authorization request pending.". Could you post the code on how you use the sd_ble_gatts_rw_authorize_reply() ?

    4) You reproduced this with using nRF Connect for desktop as the central ?

Children
  • Hi Sigurd,

    thank you for the explanation, since we do a full chip erase before the test on both Client and Server I think we are save.

    to 1)

    20181121_WriteResp_UnlikelyError.zip

    to 2)

    Since we use a two-chip approach and additionally control the parameters over our testing environment I can't  copy our code directly, but i will try to combine it so you can see how we configure the characteristic:

    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_md_t attr_md;
    ble_gatts_attr_t    attr_char_value;
    ble_gatts_char_handles_t tmphandles;
    
    memset(&char_md, 0, sizeof(char_md));
    memset(&cccd_md,0, sizeof(cccd_md));
    memset(&attr_md, 0, sizeof(attr_md));
    memset(&attr_char_value, 0, sizeof(attr_char_value));
    
    /*Set CCCD*/
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    
    cccd_md.write_perm.sm = 1;  
    cccd_md.write_perm.lv = 1;
    cccd_md.vloc       = BLE_GATTS_VLOC_STACK;
    
    /*Set Char*/
    char_md.char_props.broadcast     = 0;
    char_md.char_props.read          = 0;
    char_md.char_props.write         = 1;
    char_md.char_props.write_wo_resp = 0;
    char_md.char_props.notify        = 0;
    char_md.char_props.indicate      = 1;
    char_md.char_props.auth_signed_wr = 0;
    
    char_md.p_char_user_desc = NULL;
    char_md.p_char_pf        = NULL;
    char_md.p_user_desc_md   = NULL;
    char_md.p_cccd_md        = &cccd_md;
    char_md.p_sccd_md        = NULL;
    
    /* Set Attr */
    attr_md.read_perm.sm = 0;
    attr_md.read_perm.lv = 0;
    attr_md.write_perm.sm = 1;
    attr_md.write_perm.lv = 1;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.vlen       = 1;
    
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 1;
    
    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = 20;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = 20;
    attr_char_value.p_value   = NULL;
    
    err_code = sd_ble_gatts_characteristic_add(service_handle,
          &char_md,
          &attr_char_value,
          &tmphandles);
    
    

    to 3)

    As the UnlikelyError happens indepent of sending the sd_ble_gatts_rw_authorize_reply(). We can see that we are still in a connection, but with sending the ATT-Error we think the authorization request is cancelled. So most likely "no authorization request pending" is the cause of the wrong state. This should be resolved automatically if we can prevent the UnlikelyError.

    to 4)

    As I said, our default usecase is having our own Firmware for Client/Central and Server/Peripheral. Just to be sure we modiefied our tests, so we could use nRFConnect as a Client/Central. This we tried with an Android Phone as well as with PC using a Nordic Dongle.

    Thank you,

    Niclas

  • Thank you for the sniffer log.

    Q1) After you get the event BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, do you call any other sd_* function except for the sd_ble_gatts_rw_authorize_reply() function?

    Q2) Are you calling sd_ble_gatts_hvx() ? If yes, under what conditions are you calling it?

Related