Multiple interrupt during data transmition

Hello All

during developmenmt we meet some strange phenomen.

the device send to PC 135 bytes on responce command READ.

During transmitrion 135 bytes the softdevice generate ble read event (<debug> nrf_sdh_ble: BLE event: 0x51.)

five time though it should be one.

We add the custom service

custom_serv_add_char(WRITE_CHAR, m_ble_measurements_service.service_handle,
                         MEASUREMENTS_WHITE_REF_CHAR, m_ble_measurements_service.uuid_type,
                         &m_ble_measurements_service.white_ref_char_handle, CHAR_EMPTY_SIZE,
                         135
                        );

static void custom_serv_add_char(custom_char_t char_type, uint16_t service_handle, uint16_t uuid,
                                 uint16_t p_uuid_type, ble_gatts_char_handles_t *p_handles,
                                 uint16_t init_len, uint16_t max_len)
{
    ble_uuid_t ble_char_uuid;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t attr_char_value;
    ble_gatts_attr_md_t attr_md;

    memset(&char_md, 0, sizeof(char_md));
    char_md.char_props.read = 1;
    char_md.char_props.write = 0;

    ble_char_uuid.type = p_uuid_type;
    ble_char_uuid.uuid = uuid;

    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.rd_auth = 1;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
    if (char_type == READ_ONLY)
    {
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
    }
    else
    {
        char_md.char_props.write = 1;
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    }

    attr_md.vloc = BLE_GATTS_VLOC_STACK;
    attr_md.vlen = ALLOW_VOLATILE_CHAR_LENGTH;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid = &ble_char_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len = init_len;
    attr_char_value.max_len = max_len;
    attr_char_value.p_value = 0;

    APP_ERROR_CHECK(sd_ble_gatts_characteristic_add(service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               p_handles));
}

Body function which send the data on responce to theread event

   ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
    auth_reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
    auth_reply.params.read.update = 1;

  auth_reply->params.read.p_data = get_calibraion_buff;
        auth_reply->params.read.len = 135;
        DEBUG_MSG("Size Of Spectrum = %d", auth_reply->params.read.len);

 sd_ble_gatts_rw_authorize_reply(conn_handle, auth_reply);
 

The MTU is

INFO ATT MTU updated for device E4:28:FA:49:40:AB, new value is 31

Softdevice 132

SoC is  nRF52832

Why softdevice  generate five 5 although it should generate only one?

Best regards

Andrii

Parents
  • Hello

    It's not entirely clear to me what your code is doing here, but if you're sending 135 bytes with an MTU of 31 the data would have to be split into 5 packets, so perhaps it's not so strange that 5 events are triggered?

    Best regards,

    Einar

  • Hello Einar

    I understand this one. Strange there is something that I send all 135 bytes in respose to this event so all data is provided completely as it declared at the add custom service . So logicaly,  soft device should split it to 5 packets and send it without generation additional events because it has all data to transnit. But in actulal case,  event handler duplicates the same 135 bytes  5 time due to unnecessary events .  From other side, logicaly, the high level application does not  must to know details of low level  for example what  size of  MTU is. it should send data and count of data that is all.

    Best regards

    Andrii

  • Are you sure all of the 135 bytes are actually duplicated for each event? Can you elaborate on how you came to this conclusion?

    What version of the SDK are you using? Can you link me to the documentation of these event handlers?

    -Einar

  • Yes I am sure :-)  because this event handler was developed by our company and registered as observer :-)

    static void measurements_service_event_handler(ble_evt_t const *p_ble_evt, void *p_context)
    {
        ble_measurements_service_t *service_context = (ble_measurements_service_t *)p_context;
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_WRITE:
                on_write(service_context, p_ble_evt);
                break;
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                const ble_gatts_evt_rw_authorize_request_t*  req;
                
                req = &p_ble_evt->evt.gatts_evt.params.authorize_request;
                if (req->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
                {
                    on_read(p_ble_evt->evt.common_evt.conn_handle, service_context, req->request.read.handle);
                }
                break;
            }
            default:
                // No implementation needed.
                break;
        }
    }

    registration is

    NRF_SDH_BLE_OBSERVER(ble_service_name_obs, BLE_LBS_BLE_OBSERVER_PRIO,
                             measurements_service_event_handler, &m_ble_measurements_service);

    the BLE_GATTS_AUTHORIZE_TYPE_READ has value 0x51 mentioned above

    so after receiving this message the function on_read is called . this function send 135 bytes due to this code (I was metioned this code in my first message but I repeat this one here)

    ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
        auth_reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
        auth_reply.params.read.update = 1;

      auth_reply->params.read.p_data = get_calibraion_buff;
            auth_reply->params.read.len = 135;
            DEBUG_MSG("Size Of Spectrum = %d", auth_reply->params.read.len);

     sd_ble_gatts_rw_authorize_reply(conn_handle, auth_reply);

    The sdk version is 17.0..2

    Best tregards

    Andrii

Reply
  • Yes I am sure :-)  because this event handler was developed by our company and registered as observer :-)

    static void measurements_service_event_handler(ble_evt_t const *p_ble_evt, void *p_context)
    {
        ble_measurements_service_t *service_context = (ble_measurements_service_t *)p_context;
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_WRITE:
                on_write(service_context, p_ble_evt);
                break;
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                const ble_gatts_evt_rw_authorize_request_t*  req;
                
                req = &p_ble_evt->evt.gatts_evt.params.authorize_request;
                if (req->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
                {
                    on_read(p_ble_evt->evt.common_evt.conn_handle, service_context, req->request.read.handle);
                }
                break;
            }
            default:
                // No implementation needed.
                break;
        }
    }

    registration is

    NRF_SDH_BLE_OBSERVER(ble_service_name_obs, BLE_LBS_BLE_OBSERVER_PRIO,
                             measurements_service_event_handler, &m_ble_measurements_service);

    the BLE_GATTS_AUTHORIZE_TYPE_READ has value 0x51 mentioned above

    so after receiving this message the function on_read is called . this function send 135 bytes due to this code (I was metioned this code in my first message but I repeat this one here)

    ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
        auth_reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
        auth_reply.params.read.update = 1;

      auth_reply->params.read.p_data = get_calibraion_buff;
            auth_reply->params.read.len = 135;
            DEBUG_MSG("Size Of Spectrum = %d", auth_reply->params.read.len);

     sd_ble_gatts_rw_authorize_reply(conn_handle, auth_reply);

    The sdk version is 17.0..2

    Best tregards

    Andrii

Children
  • So your custom event handler is called 5 times, which causes the on_read function to be called 5 times?

    How many packets are actually sent? Does the on_read function cause the whole 135 bytes to be sent or does it send just one packet of 31 bytes each time it's called?

    Have you considered setting the MTU and LE data length to over 135 bytes, to let you send all the data in a single packet?

    -Einar

  • First question - YES.

    Second querstion - I have to put the same code third time please read my messages attentively

    ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
        auth_reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
        auth_reply.params.read.update = 1;

      auth_reply->params.read.p_data = get_calibraion_buff;
            auth_reply->params.read.len = 135;
            DEBUG_MSG("Size Of Spectrum = %d", auth_reply->params.read.len);

            sd_ble_gatts_rw_authorize_reply(conn_handle, auth_reply);

         where get_calibraion_buff is pointer to array with size 135 byte.

      third question - the size of MTU is assigned during connection esteblishment .

    The sizue of MTU accordingly  sdk _config.h

    #ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE
    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 160
    #endif

    But question how to increaase MTU during connection establishment it is another question and another  topic.

    Current question is why soft device generate 5 time BLE_GATTS_AUTHORIZE_TYPE_READ event 

    after calling sd_ble_gatts_rw_authorize_reply(conn_handle, auth_reply) with  parrameter filled by above mentioned way.

    Best regards

    Andrii

  • Please, I am reading your messages attentively, but it's not obvious to me how your program will behave based on this code, which is why I'm asking you these questions. So I would appreciate if you could answer my question and not just post the same code again. Thanks.

    I believe the MTU is very relevant to your question, as it seems likely to me that your data is split into 5 packets because of the MTU.

    From your original post it seems the MTU is set to 31, have you changed the sdk_config.sh since your first post or is the setting not taking effect? Also it is not enough to just set the MTU, you'll also have to set the data length variable to send larger packets.

    -Einar

  • Hello Einarh

    Excuse me for later answer.

    There are several software principles. One of them, if it describe roughly, sounds like - one part of software (In our case high level) should not know details of another part of software (in our case low level of BLE stack).. Other words - the application should not know about details of transport of its messages.

    If apply this principle to our case, so application should call function with 2 parameters one of them pointer to the buffer of data, another number of data. After that application should receive the result of transmition  in synchronous or asynchronous way. That is all . Everything other should be business  of  BLE stack(Size of MTU, Fragmentation, memory allocation etc..).

    You consider some particular case, but it is necessary to provide some common approach.

    Of coarse this case depends from size of MTU. AND IT IS PROBLEM. For example what happen if I need to transmit not 135 bytes but 1350 bytes ? Or size of MTU will be changed during connection establishment negotiation to the 27 or other because it depends from which version of BLE  protocol hardware of opposite side  support or another circumstances?

    THE MAIN QUESTION OF THIS TOPIC IS - 

    Whether such behaviour is result of wrong BLE stack adjustment or wrong parameter filling or it is bug of BLE stack.

    That is why I have sent you sources. 

    Best regards

    Andrii Shevchuk

  • Hi again

    These are nice principles to have when doing high level programming, but I'm afraid much of what you are doing here is fairly low level. If you don't want to deal with low level BLE stack behavior, then you should consider whether a pre-existing BLE service can work for your application instead of writing your own.

    I'm still having trouble understanding how your code is supposed to work, if you could please explain the expected basic program flow of your application that would make it much easier for me to help you.

    I would also appreciate if you could send me a sniffer trace showing the communication between your two devices, using the nRF sniffer tool, as that would help a lot with debugging.

    Best regards,

    Einar

Related