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

device manager with NUS from ble_peripheral\ble_app_uart\pca10028\s130


Hi,
I’m working on a project where I need to control a device via BLE_Uart. The scenario I’m trying to achieve is:
- I have a network of several centrals und several peripherals. I’m trying to find I way to manage the devices connections using the device manager and whiltelists.
- Peripheral start directed_slow advertising  without timeout
- A Central, that goes to sleep after Max 2 mins, wakes up and should connect and bond with one specific peripheral. After some data exchange Central goes back to sleep for power save (PSV) reasons. The Centrals will be dedicated Remote Controls (RC), hence the PSV, or Apps running on Android or iOS.
I’ am trying to implement this scenario using the NUS  in conjunction with the device manager.
I took the example in [ \..\..\examples\ble_peripheral\ble_app_uart\pca10028\s130\arm5_no_packs ] from SDK and would like to extend it with device manager functionalities as explained here.
At this point already, my peripheral won’t even advertise after I added device manager implementations. Pretty sure I’m missing an important configuration but it all seems ok to me. I need help in this.
Here my changes:

static void sys_evt_dispatch(uint32_t sys_evt)
{
    pstorage_sys_event_handler(sys_evt); // Forward Softdevice events to the pstorage module
    ble_advertising_on_sys_evt(sys_evt);
}

static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
    ble_conn_params_on_ble_evt(p_ble_evt);
    ble_nus_on_ble_evt(&m_nus, p_ble_evt);
    dm_ble_evt_handler(p_ble_evt);// Forward BLE events to the Device Manager
    on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);
    bsp_btn_ble_on_ble_evt(p_ble_evt);
}
static void device_manager_init(bool erase_bonds)
{
    uint32_t               err_code;
    dm_init_param_t        init_param = {.clear_persistent_data = erase_bonds};
    dm_application_param_t register_param;
    // Initialize persistent storage module.
    err_code = pstorage_init();
    APP_ERROR_CHECK(err_code);
    err_code = dm_init(&init_param);
    APP_ERROR_CHECK(err_code);
    memset(&register_param.sec_param, 0, sizeof(ble_gap_sec_params_t));
    register_param.sec_param.bond         = SEC_PARAM_BOND;
    register_param.sec_param.mitm         = SEC_PARAM_MITM;
    register_param.sec_param.lesc         = SEC_PARAM_LESC;
    register_param.sec_param.keypress     = SEC_PARAM_KEYPRESS;
    register_param.sec_param.io_caps      = SEC_PARAM_IO_CAPABILITIES;
    register_param.sec_param.oob          = SEC_PARAM_OOB;
    register_param.sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
    register_param.sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
    register_param.evt_handler            = device_manager_evt_handler;
    register_param.service_type           = DM_PROTOCOL_CNTXT_GATT_SRVR_ID;
    err_code = dm_register(&m_app_handle, &register_param);
    APP_ERROR_CHECK(err_code);
}
static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle,
                                           dm_event_t const  * p_event,
                                           ret_code_t        event_result)
{
    APP_ERROR_CHECK(event_result);
#ifdef BLE_DFU_APP_SUPPORT
    if (p_event->event_id == DM_EVT_LINK_SECURED)
    {
        app_context_load(p_handle);
    }
#endif // BLE_DFU_APP_SUPPORT
    return NRF_SUCCESS;
}
static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    ble_advdata_t scanrsp;
    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
  
    memset(&scanrsp, 0, sizeof(scanrsp));
    scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    scanrsp.uuids_complete.p_uuids  = m_adv_uuids;
    ble_adv_modes_config_t options = {0};
    options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
}
 
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;
    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;
        default:
            break;
    }
}
Please let me know if, more info about the implementation or scenario is missing
Regards,
Daniel
Parents
  • Hello,

    Ok, so your device is not starting to advertise, is that correct?

    Probably one of your APP_ERROR_CHECK(err_code); receives an err_code != NRF_SUCCESS (=0). What SDK version do you use? Can you try to define DEBUG in your preprocessor defines, and turn off optimization (-O0), and try to set a breakpoint in the error handler in app_error.c? Exactly where this is depends a bit on what SDK version you use. Alternatively, you can try to set some breakpoints at the APP_ERROR_CHECKS, but you probably need to disable optimization to see what the err_code is. If you find out this, what function returned the err_code != NRF_SUCCESS, and what was the err_code?

     

    If I am going to reproduce the issue here, I would need a project that I can run. Unfortunately it isn't that easy to see from only a few snippets. 

     

    Also, I don't know how far in the development you have come, but the Device Manager is quite old. If it is not too late, I suggest you move to the Peer Manager, which is a more stable module, doing the same thing. It was introduced in one of the later SDKs for the nRF51 series (SDK11 if I remember correctly), but if you use a very old version of the SDK, it isn't included, and it might be a bigger job to port to a newer SDK. However, if you use SDK12.3.0, which is the latest SDK that supports nRF51, I recommend that you try to use the Peer Manager.

     

    Best regards,

    Edvin

  • Hi Edvin,

    I think I'm running version 11.0.0-2.alpha. Our development is pretty far since we will go in production in two weeks. So I'll neeed this help ASAP. I tried with the peer manager but there I ran into the 32K code size limit. And if I need to purchase a full KEIL license it will be too late. So going for the DM and hoping for it to work with stability. 

    Here to the issue: 

    - added the DEBUG flag and changed the optimization Level to 0 (all in "Options for target"-> "C/C++"). But I still can hit the breakpoint or better said the breakpoint becomes an exclamation sign and the debugger breaks in disassembly. How do I solve this?

    I can send you my entire project but we'll need to move the case to a secure area sicn these will be sensitive data.Please advise accordignly.

    Regards,

    Daniel

  • I really recommend that you port to at least SDK11.0.0 (NOT alpha), as the Alpha SDKs are pre-releases, and not production standard. It shouldn't be much work, as it only contains bug fixes. I suggest that you do this first, and see if - by chance - you have encountered a bug that was fixed in the production release.

    You can find SDK11.0.0 here.

    If the breakpoint becomes an exclamation mark in Keil, then it means that this part of the code is not included in the compilation. If you define DEBUG in your preprocessor defines, like in the attached screenshot, and set a breakpoint on line 54 in app_error.c, it will stop there if APP_ERROR_CHECK(err_code) receives an err_code != NRF_SUCCESS. When it stops, right click error_info on line 48, and click add to watch 1. Then you should see some info on why the program has stopped in the watch1 window in Keil.

     

    But please (!) update to SDK11.0.0, not alpha version.

     

    Best regards,

    Edvin

  • HI Edvin,

    thank you so much for your hints. I made the porting to SDK 11.0.0 (your download link) and was able to set breakpoints and find out the issue. It was a call  with sd_ble_gap_address_get() that I was making before initialitizing the stack. So the SD wasn't ready.

    So now, maybe right  here without opening a new case for it, can we go on to the real configuration that we're tying to achieve as stated above?:

    - I have a network of several centrals und several peripherals. I’m trying to find I way to manage the devices connections using the device manager and whiltelists.
    - Peripheral start directed_slow advertising  without timeout
    - A Central, that goes to sleep after Max 2 mins, wakes up and should connect and bond with one specific peripheral. After some data exchange Central goes back to sleep for power save (PSV) reasons. The Centrals will be dedicated Remote Controls (RC), hence the PSV, or Apps running on Android or iOS.

    Scenario for Central: 

    Should put a connection request only to one specific peripheral and bond. If this peripheral is not advertising Central should go to sleep

    Scenario for Periph:

    Peripheral starts directed_slow advertising without timeout, and if this specific central isn't requesting a connection 

    Peripheral should go thru the whitelist for other central that try to connect.

    The point is that there is one dedicated Central that as higher prio and needs to always connect fast to only one periphareal.

    Best regards,

    Daniel 

Reply
  • HI Edvin,

    thank you so much for your hints. I made the porting to SDK 11.0.0 (your download link) and was able to set breakpoints and find out the issue. It was a call  with sd_ble_gap_address_get() that I was making before initialitizing the stack. So the SD wasn't ready.

    So now, maybe right  here without opening a new case for it, can we go on to the real configuration that we're tying to achieve as stated above?:

    - I have a network of several centrals und several peripherals. I’m trying to find I way to manage the devices connections using the device manager and whiltelists.
    - Peripheral start directed_slow advertising  without timeout
    - A Central, that goes to sleep after Max 2 mins, wakes up and should connect and bond with one specific peripheral. After some data exchange Central goes back to sleep for power save (PSV) reasons. The Centrals will be dedicated Remote Controls (RC), hence the PSV, or Apps running on Android or iOS.

    Scenario for Central: 

    Should put a connection request only to one specific peripheral and bond. If this peripheral is not advertising Central should go to sleep

    Scenario for Periph:

    Peripheral starts directed_slow advertising without timeout, and if this specific central isn't requesting a connection 

    Peripheral should go thru the whitelist for other central that try to connect.

    The point is that there is one dedicated Central that as higher prio and needs to always connect fast to only one periphareal.

    Best regards,

    Daniel 

Children
No Data
Related