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

C# API for nRF51 Dongle

Hi, I would like to use a nRF51 Dongle to connect to BLE devices and retrieve some data.

I already tried my scenario through nRF Connect for Desktop and it works, so I assume I can develop a custom C# application to do the same thing.

I looked for some API/library and so far I just found 3 possibilities:

- PC BLE Driver: https://github.com/NordicSemiconductor/pc-ble-driver
- PC BLE Driver JS: https://github.com/NordicSemiconductor/pc-ble-driver-js
-
 PC BLE Driver Py: https://github.com/NordicSemiconductor/pc-ble-driver-py

If I'm right, the last two should be higher level APIs that would perfectly fit my needs, but unfortunately the C# language is a requirement and then I cannot use those drivers.

The first question I want to ask is: is the PC BLE Driver the right choice for developing such a C# application or is there anything better?

The second (and last) question is: where can I find some documentation about how to import that driver in C# and how to use the APIs in order to connect to BLE devices and read/write some Characteristics?

Thanks a lot for your help!

  • Hi,

    The libraries that you have already found and linked to are the recommended options for controlling an nRF51 Dongle from PC software. We do not have a C# API, so if C# is a requirement you would have to wrap the c library of pc-ble-driver library with C# bindings on your own. Just as we have wrapped it in javascript and python bindings and added higher level abstractions on top, for the -js and -py versions.

    Please note that we did implement a C# library several years ago, named "Master Emulator", but it is no longer in active development and we can offer only limited support if going forward with that solution. We highly recommend going for pc-ble-driver instead.

    Regards,
    Terje

  • Hi, thanks for your reply.

    As you suggested I continued using the PC BLE Driver, but the lack of documentation is driving me crazy. Until now I used the examples (in particular the Heart Rate Collector), but there is something that is not covered neither by that, for example the bonding.

    Currently I'm able to use the driver to connect to a BLE device, discover services, characteristics and writing and reading attributes. I then started to develop the bonding feature, after searching a lot on the web I got the right parameters to pass to sd_ble_gap_authenticate() in order to start the bonding process, like I found on this sequence chart. After calling this function I receive a BLE_GAP_EVT_SEC_PARAMS_REQUEST to which I should reply witha a sd_ble_gap_sec_params_reply().

    When I call it I get the following exception:

    Unhandled exception at 0x00007FF9D580B79E (ucrtbase.dll)

    I am probably calling the function with the wrong parameters, but I cannot figure out which are the right ones.

    The following are some pieces of my code:

    memset(&this->securityParameters, 0, sizeof(this->securityParameters));
    this->securityParameters.bond = true;
    this->securityParameters.mitm = false;
    this->securityParameters.io_caps = BLE_GAP_IO_CAPS_NONE;
    this->securityParameters.oob = false;
    this->securityParameters.min_key_size = 7;
    this->securityParameters.max_key_size = 16;
    this->securityParameters.kdist_own.enc = 1;
    this->securityParameters.kdist_own.id = 1;
    this->securityParameters.kdist_peer.enc = 1;
    this->securityParameters.kdist_peer.id = 1;
    
    uint8_t errorCode = sd_ble_gap_authenticate(this->adapter, this->connection_handle, &this->securityParameters);
    
    //...
    
    // This call return NRF_SUCCESS, then I receive the BLE_GAP_EVT_SEC_PARAMS_REQUEST event
    
    //...
    
    memset(&this->keyset, 0, sizeof(this->keyset));
    uint8_t errorCode = sd_ble_gap_sec_params_reply(this->adapter, this->connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, NULL, NULL);

    Since it's not working I also tried:

    uint8_t errorCode = sd_ble_gap_sec_params_reply(this->adapter, this->connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, &this->securityParameters, NULL);
    uint8_t errorCode = sd_ble_gap_sec_params_reply(this->adapter, this->connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, &this->securityParameters, &this->keyset);
    uint8_t errorCode = sd_ble_gap_sec_params_reply(this->adapter, this->connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, nullptr, nullptr);

    What else should I try?

    In case you need further details, my NRF51 Dongle is flashed with the SoftDevice S130 v2.0.1, so I'm using the DLL SD API v2.

    EDIT: I found this question and after moving the function to the main thread it's not crashing anymore, but I'm still stuck because:

    1. if I pass NULL as security parameters I get a NRF_ERROR_INVALID_ADDR

    2. if I pass the real security parameters I get a NRF_ERROR_INVALID_PARAM

  • Hi,

    I can confirm that s130 v2.0.1 is the SoftDevice to be used with pc-ble-driver for the nRF51. The documentation that you linked to is for an older version SoftDevice, and although Just Works Pairing seems to be the same there are some differences. You find the s130 v2.0.1 documentation here.

    For sd_ble_gap_sec_params_reply(), in the central role, p_sec_params should be NULL, as the parameters are previously given through sd_ble_gap_authenticate(). Based on your code excerpts I think that the following may be correct:

    uint8_t errorCode = sd_ble_gap_sec_params_reply(this->adapter, this->connection_handle, BLE_GAP_SEC_STATUS_SUCCESS, NULL, &this->keyset);

    You can also have a look at how this is done in the Peer Manager library in nRF5 SDK v12.3, for reference. (Search for sd_ble_gap_authenticate and sd_ble_gap_sec_params_reply in components\ble\peer_manager\security_dispatcher.c.)

    Regards,
    Terje

Related