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

Client without Notifications bricking device

Hey everyone, I have a device that's in production and everything is working great, however we have a customer that is creating their own software to interface with our sensor and they bricked a couple units because they did not turn notifications on. This causes the unit to seemingly  wait indefinitely waiting to get the thumbs up from the client that it received the packet, which never comes. We don't expect the unit to work without notifications on, but I don't want it to lock up like this... we have no hardware reset capability so the units are junk now.

I figure there has to be an event for a time out or the like that I could use to force a disconnect and start advertising again, I just can't seem to find it. I've tied BLE_GATTC_EVT_TIMEOUT, BLE_GATTS_EVT_TIMEOUT, and BLE_GAP_EVT_TIMEOUT. None of these seem to be triggered by the sensor not being able to send a packet.

Any thoughts?

Thanks,

Adam

  • I think you are rushing ahead:

     

    Adam Gerken said:
    When my application sends data to a client that doesn't have notifications enabled, the program hangs up and no interrupts work any more.

     Perhaps this is because the ble_nus_data_send() returns != 0?

     

    Edvin said:
    Are you able to see from your application when the notification is enabled?
  • Perhaps this is because the ble_nus_data_send() returns != 0?

    I'm not using nus, it's a custom service but is probably similar. I'm only processing two error codes right now, NRF_SUCCESS and NRF_ERROR_RESOURCES. If the "send_data" service returns success, I compile another packet and send it to the SD until I get an NRF_ERROR_RESOURCES, then I wait for the BLE_GATTS_EVT_HVN_TX_COMPLETE event, and do the whole process again.

    I just tried looking for other error codes and quitting the transmission if "send_data" returns something other than SUCCESS or ERROR_RESOURCES but it still hangs up before I can even look at what the code is.

    Are you able to see from your application when the notification is enabled?

    No. This is the whole point of this whole thread. I don't know how to do this. This is exactly what I want to do.

  • Hello Adam,

    Do you have "DEBUG" in the preprocessor symbols for your project? I suspect that your project is calling sd_ble_gatts_hvx and then asserting when it receives the NRF_ERROR_INVALID_STATE error code. If DEBUG was defined then this can put you into an infinite loop at the bottom of the default app_error_fault_handler, with all of your application's interrupts disabled. If you remove the DEBUG symbol then the assert handler will initiate a system reset instead.

  • I don't believe so. My preprocessor defines are just:

    CONFIG_GPIO_AS_PINRESET

    CONFIG_NFCT_PINS_AS_GPIOS

    FLOAT_ABI_HARD

    INITIALIZE_USER_SECTIONS

    NO_VTOR_CONFIG

    NRF52840_XXAA

    NRF_SD_BLE_API_VERSION=6

    S140

    SOFTDEVICE_PRESENT

    SWI_DISABLE0

    I do believe that I'm getting NRF_ERROR_INVALID_STATE back after I call my send_data, which does call sd_ble_gatts_hvx. The issue I'm running into now, is what do I do then? If I call sd_ble_gap_disconnect I also just get NRF_ERROR_INVALID_STATE back. I think this is where it's all hung up.

    I don't do an error check after calling my send data routine though, so I'm not sure why it would be getting hung up to the point of disabling all the interrupts. I only look for SUCCESS, or ERROR_RESOURCES for program logic stuff.

    Here's the routine that's calling my "send_data"

    void transmit_samples(void){
    
        ret_code_t            err_code;
        uint16_t              bytes_to_tx, packet_bytes_to_tx;
        uint8_t               ble_packet[DEFAULT_MAX_MTU_SIZE];
        uint8_t               checksum;
    
        //send packets until we've filled the buffer, or we're done.
        if (requested_samples > transmitted_samples){
    
          while((err_code != NRF_ERROR_RESOURCES) && (requested_samples > transmitted_samples)){
            
            /*FORM THE PACKET*/
    
            //send the packet!
            err_code = ble_ctcws_send_data(m_conn_handle, &m_ctcws, ble_packet, &packet_bytes_to_tx);
        
            //if we didn't get an error, and we're not done: incriment the number of samples and packets
            if (err_code == NRF_SUCCESS){
              transmitted_samples += (bytes_to_tx/2);
              packet_number ++;
            }
          }//while != NRF_ERROR_RESOURCES
    
        }//if (requested_samples > transmitted_samples)
    
        //if we're done, let the device know
        else {
            send_application_status(TRANSFER_DONE);
            #ifdef DEBUG
            printf("Transmission done, sent %d samples in %d packets\r\n",transmitted_samples, packet_number);
            #endif
            rtc_set(DEFAULT_TIMEOUT);
            requested_samples = 0;
        }
    
    }//transmit_samples

    Here's my "send_data":

    uint32_t ble_ctcws_send_status(uint16_t conn_handle, ble_ctcws_t * p_ctcws, uint8_t * p_data, uint16_t * p_length)
    {
        ble_gatts_hvx_params_t params;
    
        memset(&params, 0, sizeof(params));
        params.type   = BLE_GATT_HVX_NOTIFICATION;
        params.handle = p_ctcws->status_char_handles.value_handle;
        params.p_data = p_data;
        params.p_len  = p_length;
    
        return sd_ble_gatts_hvx(conn_handle, &params);
    }

  • Is your transmit_samples function called in an interrupt context? If so, no other interrupts can preempt it unless they are a strictly greater priority (lower number).

    If sd_ble_gap_disconnect is returning NRF_ERROR_INVALID_STATE then "Disconnection in progress or link has not been established." Not sure how you debugged it but maybe the first call to sd_ble_gap_disconnect succeeded and then the second call reported an error and got your attention?

Related