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

Multi-peripheral, bonding and whitelisting

Hi,

I need a way to have a concurrent connection (multi-peripheral), with whitelisting and bonding. Is there any example of this?

I found an example for multi-peripherals, but this is not for concurrent connections. I also found the HID-Mouse example which uses whitelisting and bonding, but it's only supporting single links (because it uses the advertising module).

I some sort of managed to include those two together, but then sometimes the softdevice asserts. So I was wondering if there are any other examples of doing this?

Parents
  •  That is not true. You can support multiple connections when the advertising module is used. Just look at the multiperipheral example.

    The advertising API notes: "Note: The Advertising Module supports only applications with a single peripheral link."

    The multiperipheral example doesn't use the advertising module if I understand correctly. It uses the Advertising and Scan Response Data Encoder

    Or am I confusing things?

    What did that look like? What happened when the "softdevice asserted"? Can you show me a screenshot, or any other observation you did to conclude with that?

    For instance, when I disconnect, I get:

    00> <info> app: Connection with link 0x0 established.
    00> <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 27 bytes.
    00> <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    00> <debug> nrf_ble_gatt: max_rx_octets: 27
    00> <debug> nrf_ble_gatt: max_tx_octets: 27
    00> <debug> nrf_ble_gatt: max_rx_time: 328
    00> <debug> nrf_ble_gatt: max_tx_time: 2120
    00> <debug> app: PHY update request.
    00> <error> app: Fatal error

    But it doesn't happen always, but the fact that it happens makes it unreliable. 

    So probably something is wrong in my code. 

    I can send you my code, how can I do that?

  • Gueston said:

    The multiperipheral example doesn't use the advertising module if I understand correctly. It uses the Advertising and Scan Response Data Encoder

    Or am I confusing things?

     You are absolutely correct. I didn't realize this before. 

     

    Gueston said:

    So probably something is wrong in my code. 

    I can send you my code, how can I do that?

     The log is a good thing. It is probably something you can fix. 

    Whenever you see "Fatal error" in the log, it means that one of your APP_ERROR_CHECK(err_code); has received an err_code != 0.

    To find out which one that triggered it, add "DEBUG" to your preprocessor definitions. Let me know what IDE you are using if you are not sure how to do this. 

    When you added this, the log should point to an APP_ERROR_CHECK(err_code) in your project, and a value for err_code. Which one does it point to, and what function returned that err_code, and what value did err_code have?

    BR,
    Edvin

  • I cleaned the project using make clean first (which deletes the _build folder). So that wasn't the issue.

    You are using pca10040\s132\armgcc, right?

    BR,

    Edvin

  • Try to download and use 

    GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/7 2018-q2-update/bin/
    GNU_VERSION := 7.3.1
    GNU_PREFIX := arm-none-eabi
    

    which is the version mentioned in SDK16\components\toolchain\gcc\Makefile.windows.

    Although I don't think that is the issue. 

    Please, go to nordicsemi.com, download a new SDK16.0.0.zip, and unzip it in a new location, then copy your folder ble_app_.. into the folder:

    SDK16.0.0\examples\ble_peripheral\experimental, then navigate to:

    SDK16.0.0\examples\ble_peripheral\experimental\ble_app_...\pca10040\s132\armgcc, delete the build folder, run the command "make", and erase the nrf52832, using the command "nrfjprog --eraseall".

    Then flash the softdevice and the application and reset the device.

    You will see:

    Please make sure to use the exact same version that you sent to me in the message, and a completely unmodified SDK. If you at some point modified the project that you uploaded, perhaps I don't have the latest update? If so, please send me an updated project.

    If we don't see the same log, it means that you have a different application than the one you sent me, and then there is no point in me poking around in your firmware to find bugs that you may already have solved. 

    Also: These files can't be found when I tried to compile your project. Do you get the same message? If not, we either have a different makefile, or a different configured SDK.

     

    makefile:314: Cannot find include folder: ../../../config
    makefile:314: Cannot find include folder: ../../../../../../../components/drivers_nrf/usbd
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/experimental_log
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/experimental_log/src
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/experimental_memobj
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/experimental_mpu
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/experimental_stack_guard
    makefile:314: Cannot find include folder: ../../../../../../../components/libraries/usbd/config
    makefile:314: Cannot find include folder: ../../../../../../../components/nfc/t2t_lib/hal_t2t
    makefile:314: Cannot find include folder: ../../../../../../../components/nfc/t4t_lib/hal_t4t

    FYI, this is the warnings I geth when I build the application:

    In file included from ../../../custom_services/ble_leds/ble_leds.c:25:0:
    ../../../custom_services/ble_leds/ble_leds.h:61:1: warning: multi-line comment [-Wcomment]
     //#define MOCK_DEVICE_EC_01_UUID_BASE        {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
     ^
    ../../../custom_services/ble_leds/ble_leds.h:100:1: warning: "/*" within comment [-Wcomment]
     /* A typedef to a pointer to a function that takes two parameters and returns void */
    
    ../../../custom_services/ble_leds/ble_leds.h:104:1: warning: "/*" within comment [-Wcomment]
     /** LEDS Service initialization structure. This structure contains all options and data needed for
    
    ../../../custom_services/ble_control/ble_control.c: In function 'ble_control_init':
    ../../../custom_services/ble_control/ble_control.c:127:38: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
         add_char_params.p_init_value     = &calibration_inital_value; //Set the initial value for the characteristic
                                          ^
    In file included from ../../../main.c:65:0:
    ../../../custom_services/ble_leds/ble_leds.h:61:1: warning: multi-line comment [-Wcomment]
     //#define MOCK_DEVICE_EC_01_UUID_BASE        {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
     ^
    ../../../custom_services/ble_leds/ble_leds.h:100:1: warning: "/*" within comment [-Wcomment]
     /* A typedef to a pointer to a function that takes two parameters and returns void */
    
    ../../../custom_services/ble_leds/ble_leds.h:104:1: warning: "/*" within comment [-Wcomment]
     /** LEDS Service initialization structure. This structure contains all options and data needed for
    
    ../../../main.c: In function 'pm_evt_handler':
    ../../../main.c:273:5: warning: enumeration value 'PM_EVT_SLAVE_SECURITY_REQ' not handled in switch [-Wswitch]
         switch (p_evt->evt_id) {
         ^~~~~~
    ../../../main.c:273:5: warning: enumeration value 'PM_EVT_FLASH_GARBAGE_COLLECTED' not handled in switch [-Wswitch]
    ../../../main.c:273:5: warning: enumeration value 'PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED' not handled in switch [-Wswitch]
    ../../../main.c: In function 'control_user_handler':
    ../../../main.c:627:11: warning: "/*" within comment [-Wcomment]
           {   /*Only update the blinking frequnecy if the value received is a value value (1-10Hz)
    
    ../../../main.c:603:30: warning: unused variable 'current_led_state' [-Wunused-variable]
         static ble_led_command_t current_led_state = LED_OFF;
                                  ^~~~~~~~~~~~~~~~~
    ../../../main.c:601:14: warning: unused variable 'err_code' [-Wunused-variable]
         uint32_t err_code;
                  ^~~~~~~~
    ../../../main.c: In function 'bsp_event_handler':
    ../../../main.c:1054:20: warning: unused variable 'size' [-Wunused-variable]
         static uint8_t size = 0;
                        ^~~~
    ../../../main.c: In function 'main':
    ../../../main.c:1106:16: warning: variable 'err_code' set but not used [-Wunused-but-set-variable]
         ret_code_t err_code;
                    ^~~~~~~~
    At top level:
    ../../../main.c:1054:20: warning: 'size' defined but not used [-Wunused-variable]
         static uint8_t size = 0;
                        ^~~~
    ../../../main.c:603:30: warning: 'current_led_state' defined but not used [-Wunused-variable]
         static ble_led_command_t current_led_state = LED_OFF;
                                  ^~~~~~~~~~~~~~~~~
    ../../../main.c:1010:13: warning: 'buttons_init' defined but not used [-Wunused-function]
     static void buttons_init(void) {
                 ^~~~~~~~~~~~
    ../../../main.c:195:13: warning: 'leds_init' defined but not used [-Wunused-function]
     static void leds_init(void) { bsp_board_init(BSP_INIT_LEDS); }
                 ^~~~~~~~~
    ../../../main.c:134:27: warning: 'm_adv_data' defined but not used [-Wunused-variable]
     static ble_gap_adv_data_t m_adv_data = {
                               ^~~~~~~~~~
    ../../../main.c:128:16: warning: 'm_adv_handle' defined but not used [-Wunused-variable]
     static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;           /**< Advertising handle used to identify an advertising set. */

    Some of them aren't that important, such as the unused variables and functions. But some of them you should look into, such as:

    "warning: assignment from incompatible pointer type".

    I am not sure if you have looked more into the initial issue. Did you check whether the advertisements were started elsewhere (in the advertising module)? Try to disable the restart advertising on disconnect in the advertising module (enabled by default) and add a delay between custom_stop_advertising() and the call that returned the error.

  • Please make sure to use the exact same version that you sent to me in the message, and a completely unmodified SDK. If you at some point modified the project that you uploaded, perhaps I don't have the latest update? If so, please send me an updated project.

    That's what I did. And yesterday I solved those warning issues and made a new project file, see my message below:

    I uploaded the new project in the same link as before.

    Did you download this new project file? You can use the same link as I send to you yesterday. To double check I just downloaded that file myself and compiled it, and there are no warnings anymore.

    Because what you described above seems like the "older" project from yesterday.

    I am not sure if you have looked more into the initial issue. Did you check whether the advertisements were started elsewhere (in the advertising module)? Try to disable the restart advertising on disconnect in the advertising module (enabled by default) and add a delay between custom_stop_advertising() and the call that returned the error.

    I set init.config.ble_adv_on_disconnect_disabled = true; in advertising config, and now it seems to work now at first couple of tests!

    But for my knowledge and understanding, at what order is advertising started on disconnect when this value is enabled. What handlers are called?

    As far as I understand on a disconnect first 

    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
        ret_code_t err_code;
    
        switch (p_ble_evt->header.evt_id) {
    
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected");
                on_disconnected(&p_ble_evt->evt.gap_evt);
                break;
    is called which directs to on_disconnect function. This function looks like:

    static void on_disconnected(ble_gap_evt_t const *const p_gap_evt) {
        {
            ret_code_t err_code;
            uint32_t periph_link_cnt = ble_conn_state_peripheral_conn_count();  // Number of peripheral links.
    
            NRF_LOG_INFO("Connection 0x%x has been disconnected. Reason: 0x%X",
                         p_gap_evt->conn_handle,
                         p_gap_evt->params.disconnected.reason);
    
            if (periph_link_cnt == 0) {
                bsp_board_led_off(CONNECTED_LED);
                err_code = app_button_disable();
                APP_ERROR_CHECK(err_code);
            }
    
            if (periph_link_cnt == (NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - 1)) {
                // Advertising is not running when all connections are taken, and must therefore be started.
                advertising_start(false);
            }
        }
    }

    As a side note/question: Why is this function checking for periph_link_cnt -1? (

    if (periph_link_cnt == (NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - 1)). The comment says that advertising is not running when all connections are taken, but now it checks for 3 connections, not 4?
    But if i'm right, with advertising enabled by default, after this function it starts advertising again, which is the cause of the error. Stopping the advertising in the function below makes no difference anymore as it is already stopped:
            case BLE_ADV_EVT_PEER_ADDR_REQUEST: {
                pm_peer_data_bonding_t peer_bonding_data;
                custom_adv_stop();
                // Only Give peer address if we have a handle to the bonded peer.
                if (m_peer_id != PM_PEER_ID_INVALID) {
                    err_code = pm_peer_data_bonding_load(m_peer_id, &peer_bonding_data);
                    if (err_code != NRF_ERROR_NOT_FOUND) {
                        APP_ERROR_CHECK(err_code);
    
                        // Manipulate identities to exclude peers with no Central Address Resolution.
                        identities_set(PM_PEER_ID_LIST_SKIP_ALL);
    
                        ble_gap_addr_t *p_peer_addr = &(peer_bonding_data.peer_ble_id.id_addr_info);
                        err_code = ble_advertising_peer_addr_reply(&m_advertising, p_peer_addr);
                        APP_ERROR_CHECK(err_code);
                        
                    }
                }
                advertising_start(false);
    
            }
    But what exactly is this case doing? When is it invoked, in disconnect or connect?
    It's still weird that I don't get an error but an app crash by the way. If you have time you still can check my project and see yourself that it's not giving an error but just crashes with no report error.
  • try to edit advertising_init() in main.c, and set:

    init.config.ble_adv_on_disconnect_disabled = true;

    At least that solved in my case:

     

    Edvin said:
    Try to disable the restart advertising on disconnect in the advertising module (enabled by default)

     BR,

    Edvin

Reply Children
No Data
Related