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

Trying to add handler for BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST to ble_app_blinky but get Invalid State from authorize_reply.

Trying ble_app_blinky with one phone (Goggle Pixel XL, Android 8) causes a BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST rather than the expected BLE_GATTS_EVT_WRITE.   I do get a Write with a Samsun Note 3 running Android version 5).  I'm using nRF Blinky app on both phones. Since the ble_lbs.c doesn't handle this event, I'm trying to add it.  Here is the updated ble_lbs_on_ble_evt handler:

void ble_lbs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err;
    ble_lbs_t * p_lbs = (ble_lbs_t *)p_context;

    NRF_LOG_INFO("lbs evt: %08lX",p_ble_evt->header.evt_id);
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GATTS_EVT_WRITE:
            on_write(p_lbs, p_ble_evt);
            break;
        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
          {
              const ble_gatts_evt_rw_authorize_request_t*  req;
              ble_gatts_rw_authorize_reply_params_t auth_reply;
              req = &p_ble_evt->evt.gatts_evt.params.authorize_request;
      
              if (req->type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
              {
                  if (req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                  {
                      auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                      auth_reply.params.write.update = 1;
                      auth_reply.params.write.len = req->request.write.len;
                      auth_reply.params.write.p_data = req->request.write.data;
                      auth_reply.params.write.offset = req->request.write.offset;
                      auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
                      
                      NRF_LOG_INFO("lbs evt auth write len: %d",req->request.write.len);
                      if (   (req->request.write.handle == p_lbs->led_char_handles.value_handle)
                          && (req->request.write.len == 1)
                          && (p_lbs->led_write_handler != NULL))
                      {
                          p_lbs->led_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_lbs, req->request.write.data[0]);
                      } else
                      {
                          auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED;   
                      }
                      
                      err = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,&auth_reply);

                      if (err != NRF_SUCCESS){
                          NRF_LOG_ERROR("reply  error! %08lX",err);
                      }
                   }
               }
           } 
           break;
        default:
            // No implementation needed.
            break;
    }
}

This manages to catch the authorize Write to turn on the LED but the call to sd_ble_gatts_rw_authorize_reply() returns code 8 (which, I believe, is INVALID_STATE).  What am I doing wrong? The write request is being handled properly and the LED is coming on (it won't go off since I'm not getting an 'OFF' request).

I'm using SDK 15.2.0 and N52 DK.

Tom

Parents
  • Hi,

    Please check the type of write operation in req->request.write.op. I suspect it's a queued write (MSC) and that you get invalid state error because the request was already processed by the qwr module.  

    Vidar

  • Yes, you are correct, the .op was BLE_GATTS_OP_PREP_WRITE_REQ. I wasn't aware of qwr module.

    However, my interpretation of your comment is that I could treat this as a simple write and not provide any reply.  If I do this, by commenting out the sd_ble_gatts_rw_authorize_reply, then the write LED On takes place (I can see the evt in the log), but when I turn the LED off in the Nordic Blinky app, I get no event at all.  I never get the write to 0.  

    Interestingly, if I use nRF Connect, then write to the characteristic, the Write Value dialog ALWAYS shows OFF, even if I've turned the LED on.  If I send the 'Off' anyway, I do get a '0' write request.  If I try to read the characteristic, I always get 0xff, as if there is no valid value returned from the app.  I think the Nordic_Blinky App is therefore confused and will never send an OFF write because it thinks the ON write didn't complete properly?

  • The BLE_GATTS_OP_PREP_WRITE_REQ operation must be handled (ie rejected or accepted). However, I think the problem is rather why the phone sends a prepare write request in the first place, it only adds overhead. 

    There is a new option in the latest nRF connect update that enable reliable write. Maybe you have this option enabled? It still doesn't explain why you get this event with the blinky app though, according to the app developer it does not support prepare write. 

    Please check if the Abort option is greyed out before you write to LED characteristic: 

     

Reply
  • The BLE_GATTS_OP_PREP_WRITE_REQ operation must be handled (ie rejected or accepted). However, I think the problem is rather why the phone sends a prepare write request in the first place, it only adds overhead. 

    There is a new option in the latest nRF connect update that enable reliable write. Maybe you have this option enabled? It still doesn't explain why you get this event with the blinky app though, according to the app developer it does not support prepare write. 

    Please check if the Abort option is greyed out before you write to LED characteristic: 

     

Children
  • Fascinating.  At your request I looked at the Reliable Write selection in NRF Connect and 'Abort' and 'Execute' were greyed out, 'Begin' was not.  I pressed Begin and then Execute and Abort were highlighted.  I pressed Abort and it went back to Begin.  So, not knowing what affect this was having, I tried to write the LED characteristic again.  The App is NOW receiving Write Requests instead of the BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST and the LED is toggling properly.  I can't explain it, but it's working now AND you did answer my original question. 

    Oddly enough, I tested Nordic Blinky again and it operates correctly, from my Pixel phone, as well.  Since I can't say if I actually retested Nordic Blinky that after updating the App on my device, I'm not sure what's going on there.  Regardless, thank you for your help!

    Tom

Related