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

No Write Events Generated

I am currently following the tutorial for creating custom services (https://github.com/NordicPlayground/nRF5x-custom-ble-service-tutorial). The only differences to this example is that I am using SDK v17 and SoftDevice s140.

Everything has been going fine until I reach Step 6 - Handling the Write Event from the SoftDevice. For some reason, the write event is not generated when I send it through nRF connect. What does generate this event, however, is subscribing to the characteristic. Adding logs to the on_ble_evt handler shows that no event is generated on write, so it's not a case of incorrectly handling the event id.

Parents
  • Hello,

     

    Adding logs to the on_ble_evt handler shows that no event is generated on write, so it's not a case of incorrectly handling the event id.

     Do you see any logs from your custom characteristics file? (ble_cus.c?) Try to add some logs in your init function, and see if they appear.

    If you see other logs, then it may be that your event handler is not called. What does your #define BLE_CUS_DEF(_name) implementation look like? Can you compare it to the ble_cus.h implementation from the github repository that you linked to?

    That is, this one.

    This definition is what tells the softdevice where to forward the ble events. In the file that I linked, it will be forwarded to the ble_cus_on_ble_evt().

    Best regards,

    Edvin

  • Hi Edvin,

    Yep, I get logs from the custom characteristics file.

    BLE_CUS_DEF is as follows

    #define BLE_CUS_DEF(_name)                         \
     static ble_cus_t _name;                            \
     NRF_SDH_BLE_OBSERVER(_name ## _obs,                \
                          BLE_HRS_BLE_OBSERVER_PRIO,    \
                          ble_cus_on_ble_evt, &_name)




    And the ble_cus.c event handler

    void ble_cus_on_ble_evt( ble_evt_t const * p_ble_evt, void * p_context){
    
        ble_cus_t * p_cus = (ble_cus_t *) p_context;
    
        if(p_cus == NULL || p_ble_evt == NULL){
          return;
        }
    
        NRF_LOG_INFO("EVT: %d",p_ble_evt->header.evt_id);
    
        switch(p_ble_evt->header.evt_id)
        {
          case BLE_GAP_EVT_CONNECTED:{
            NRF_LOG_INFO("GAP_EVT_CONNECTED");
            on_connect(p_cus, p_ble_evt);
            break;
          }
    
          case BLE_GAP_EVT_DISCONNECTED:{
          NRF_LOG_INFO("GAP_EVT_DISCONNECTED");
          on_disconnect(p_cus, p_ble_evt);
          break;
          }
            
    
          case BLE_GATTS_EVT_WRITE:{
            NRF_LOG_INFO("GATTS_EVT_WRITE");
            on_write(p_cus, p_ble_evt);
            break;
          }
            
    
          default:
          NRF_LOG_INFO("GAP_EVT_UNDEFINED");
            break;
        }
    
    }

    Those logs are triggered when I connect or disconnect through nRF Connect and the write event log is triggered when I subscribe or unsubscribe to the characteristic.

  • I have followed a similar guide before (not that exact one, but one written for a different SDK), and it worked in that case. Is there a way for me to reproduce this? Can you zip the project folder containing the main.c file, project file and your custom files and send them here?

    Best regards,

    Edvin

  • Does that contain the project folder that you are using? What IDE are you using? And I don't see any references to your custom service in services_init(). Are you sure you sent the correct folder?

  • Apologies, that's the wrong project! The correct one is attached. I'm building on the example for PCA10056 using SES.

    2021.ble_app_template.zip

  • Ah, ok. In services_init() in main.c, you set the:

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.write_perm);

    (and read perm, equally)

    before you memset cus_init to 0. So basically, that would be like:

    uint8_t a = 14;
    uint8_t b = 15;
    
    a = 0;
    b = 0;
    
    uint8_t c = a + b;
    
    NRF_LOG_INFO("c = %d", c);  //expect c = 29, but you have c = 0.

    Try moving it at least after memset(&cus_init,0,sizeof(cus_init);

    but even maybe inside ble_cus_init(&m_cus, &cus_init);

    This is also a common mistake when you reach step 7 in your guide. Make sure that this snippet:

     /* This code belongs in services_init in main.c*/
    
        // Set the cus event handler
        cus_init.evt_handler                = on_cus_evt;

    is set after memset(&cus_init,0,sizeof(cus_init)); or you will experience some weird behavior. 

    Best regards,

    Edvin

Reply
  • Ah, ok. In services_init() in main.c, you set the:

    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cus_init.custom_value_char_attr_md.write_perm);

    (and read perm, equally)

    before you memset cus_init to 0. So basically, that would be like:

    uint8_t a = 14;
    uint8_t b = 15;
    
    a = 0;
    b = 0;
    
    uint8_t c = a + b;
    
    NRF_LOG_INFO("c = %d", c);  //expect c = 29, but you have c = 0.

    Try moving it at least after memset(&cus_init,0,sizeof(cus_init);

    but even maybe inside ble_cus_init(&m_cus, &cus_init);

    This is also a common mistake when you reach step 7 in your guide. Make sure that this snippet:

     /* This code belongs in services_init in main.c*/
    
        // Set the cus event handler
        cus_init.evt_handler                = on_cus_evt;

    is set after memset(&cus_init,0,sizeof(cus_init)); or you will experience some weird behavior. 

    Best regards,

    Edvin

Children
Related