This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BLE_GATTS_EVT_HVN_TX_COMPLETE event does not works on NUS for multi-role device

Hi,

In a multi-role central-peripheral code for a nRF52840-DK based device, I have to send a buffer acting as a peripheral. I use the ble_nus_data_send function sent as a trigger in the BLE_GAP_EVT_CONNECTED (into the ble_evt_handler function). So, I send the first data packet once the connection as peripheral has been established.

The rest of the buffer was expected to be sent using the BLE_GATTS_EVT_HVN_TX_COMPLETE event into the ble_evt_handler function. However, the event does not never occurs.

In fact, when I execute ble_nus_data_send the first time, it returns a NRF_ERROR_INVALID_STATE because it detects a condition ike !p_client->is_notification_enabled.

I have tried to clone the NUS configuration (as a peripheral) from the ble_app_uart example, working using the nRF5_SDK_17.1.0_ddde560. And including the sdk_config.h file configuration.

What should I setup to enable the BLE_GATTS_EVT_HVN_TX_COMPLETE event? Should I use another event?

Thank you very much in advance.

Best Regards,

Joel

  • Excuse me Einar, but I think èrhaps there is a misunderstanding. This device is a multi-role device. According to the aggregator multi-role and multi-link example it was possible to work simultaneously as a central and as a peripjheral.

    When it works as a peripheral, it is only connected to one central and the configuration and the tests have all been done using one only central ever. I have never tried to connect it to two centrals.

    However, this device is also a central for other peripherals.

    Regards,

    Joel

  • Hi joel,

    jinvers said:

    Excuse me Einar, but I think èrhaps there is a misunderstanding. This device is a multi-role device. According to the aggregator multi-role and multi-link example it was possible to work simultaneously as a central and as a peripjheral.

    When it works as a peripheral, it is only connected to one central and the configuration and the tests have all been done using one only central ever. I have never tried to connect it to two centrals.

    Aha, yes there could be a misunderstanding. I was reading this:

    jinvers said:
    I have a problem. Acting as a peripheral I can see it the Aggregator device on the mobile app nRF Connect. However, it does not establish connection with a second nRF52840-DK board that has the ble_app_uart_c code running on it as a central.

    and interpreted it that you now tried to use both a phone and a second DK with ble_app_uart_c) at the same time, which would e two centrals, and that will not work with your application (which allows several links in the central role, but only one link in the peripheral role).  Perhaps we can back-track a bit, and you can explain in more detail how you test, describing all devices in use at the same time and which roles they have etc?

    Assuming this is all from the misunderstanding, I guess the original issue remains, which seems to be that you (in the central role / as GATT client have not enabled notifications on the NUS characteristic, and therefor the NUS peripheral (GATT server) is not able to notify on it. This you just need to do as is doen in the NUS example (taking account that you have multiple connections).

  • Hi Einar,

    I try to update the question.

    First, I try to clarify again the scenario: The multi-link-multi-role device (using the modified aggregator example I attached) when connects as a PERIPHERAL (so as GATT Server) to a mobile phone app OR (not simultaneously) to a second nRF52840-DK acting as central. To be more clear, consider only a mobile phone app.

    I have to transmit a long buffer (around 125KBytes) from this device acting as a PERIPHERAL (so GATT Server) to the mobile phone app (acting as a Central). But in 2 or 3 seconds, so I need to do it using NOTIFICATIONS at a high rate (phy of 1M, MTU of 247, Data Length of 244, Interval between 50ms and 100ms).

    I have continued investigating about the aggregator example. I would say that it uses the ble_agg_cfg_service_string_send funtion to do this (into this function it's called the sd_ble_gatts_hvx function). So, I try again using the ble_agg_cfg_service_string_send function. Is this OK?

    So, using the ble_agg_cfg_service_string_send function I may confirm that the BLE_GATTS_EVT_HVN_TX_COMPLETE is activated into the ble_evt_handler. However, the transmitting rate is slow. So, I think that the notifications are really not enabled and that I'm not using the right tools for testing. To send notifications, I have understood that they should be enabled in the mobile app side. Is this right?

    If all my former assumptions are correct, I have really two questions now:

    1.- Before developing a new mobile app, I need to use some other tool (acting as a central) to simulate all this behaviour. What would you suggest to use?

    2.- Could I use the nRFConnect mobile phone app as a terminal to test this? How?

    Regards,

    Joel

  • Hi Joel,

    Thanks for the clarifications. I also want to mention in the beginning that the example you have based your example on is an unofficial example made by one of my colleagues several years ago which I had never seen before, just so you understand I have no intermate knowledge about it. So I am looking at this as your project.

    jinvers said:
    I would say that it uses the ble_agg_cfg_service_string_send funtion to do this (into this function it's called the sd_ble_gatts_hvx function). So, I try again using the ble_agg_cfg_service_string_send function. Is this OK?

    Yes, the ble_agg_cfg_service_string_send() is basically a wrapper around sd_ble_gatts_hvx() and is the only function in this project that is used to send notifications.

    jinvers said:
    So, using the ble_agg_cfg_service_string_send function I may confirm that the BLE_GATTS_EVT_HVN_TX_COMPLETE is activated into the ble_evt_handler. However, the transmitting rate is slow. So, I think that the notifications are really not enabled and that I'm not using the right tools for testing.

    If you get BLE_GATTS_EVT_HVN_TX_COMPLETE then that means that you have successfully sent a notifications, and so it must also be enabled. 

    jinvers said:
    So, I think that the notifications are really not enabled and that I'm not using the right tools for testing.

    As mentioned, if you get BLE_GATTS_EVT_HVN_TX_COMPLETE, then data is exchanged and notifications are enabled. If not, you would not get the event.

    jinvers said:
    To send notifications, I have understood that they should be enabled in the mobile app side. Is this right?

    Yes, the GATT client (which is the mobile app if you use that to test) must enable notifications on the relevant characteristic, and then the GATT server (which is on the nRF) in this case can send notifications.

    jinvers said:
    However, the transmitting rate is slow.

    Throughput are controlled by several factors. Assuming you try to send notifications as fast as possible, you primarily want to look at the connection interval and event length, as well as the packet length. Also, remember that for a multi link and multi role peripheral the stack needs to allocate time for each link in each role, so you will never get a very high throughput compared to what you get with a single link. If you want to test for yourself, you can set for instance both the event length and connection interval to a equal value which is (say) 100 ms and only support a single peripheral link (do adjust NRF_SDH_BLE_TOTAL_LINK_COUNT, NRF_SDH_BLE_CENTRAL_LINK_COUNT and NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) accordingly etc. Then you should see that you are able to get a decent throughout. As you add more connections (you don't need to actually establish them, just configure support for it, so that the SoftDevice will take it into account), you will see a reduction in throughput as there is less time for each connection.

    jinvers said:
    1.- Before developing a new mobile app, I need to use some other tool (acting as a central) to simulate all this behaviour. What would you suggest to use?

    If you need a central for development purposes, I suggest either nRF Connect for desktop or nRF Connect for mobile (which Understand you have already used). 

    jinvers said:
    2.- Could I use the nRFConnect mobile phone app as a terminal to test this? How?

    Yes. In nRF Connect for mobile (and desktop), you can enable notifications on a characteristic which support it by clicking on the "play symbol" next to it.

    Einar

  • Hi Einar,

    I send the reply from this message.

    Throughput are controlled by several factors. Assuming you try to send notifications as fast as possible, you primarily want to look at the connection interval and event length, as well as the packet length. Also, remember that for a multi link and multi role peripheral the stack needs to allocate time for each link in each role, so you will never get a very high throughput compared to what you get with a single link. If you want to test for yourself, you can set for instance both the event length and connection interval to a equal value which is (say) 100 ms and only support a single peripheral link (do adjust NRF_SDH_BLE_TOTAL_LINK_COUNT, NRF_SDH_BLE_CENTRAL_LINK_COUNT and NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) accordingly etc. Then you should see that you are able to get a decent throughout. As you add more connections (you don't need to actually establish them, just configure support for it, so that the SoftDevice will take it int

    I have made all the setup tests of MTU value, data length and connection interval using the ble_app_att_mtu_throughput example. MUT of 247, data length of 244 bytes and a connection intervbal of 50ms or 100ms get the best results. However, there is a big difference using that example compared to my new application.

    I understand that to get the necessary throughtput I will have to close temporarily the services not used. For example, disable the nus_c service while I need to connect the big volume of information to the phone app. Is it possible to change this' Could you suggest any example, please?

    Moreover, is there a way to dinamically change and adjust the number of peripheral links in execution mode?

    Regards,

    Joel

Related