NRF 51 BLE library for custom services

nrf51 ble stack

nrf51 ble stack

After building my first project using an nRF51 device from the template given in the SDK I was really disappointed by the result, I mean, it works but the code is really bad and hard to maintain.

The given examples are not really generic and if you have to create your custom ble service and characteristics you have  to make many modification in a code that is not clean for all.

So my second project was to create a ble library to make creation of custom services & characteristics as easy as possible and to create a main file with less code.

That is the purpose of my ble_dsk library you can found on bitbucket following this link about a library to quickly create ble services.

This library creates custom bluetooth low energy services and its attached characteristics. It can be instantiated to create multiple services. Services can have misc read/write/notify characteristics of any object size.

To use it you just need to create a structure for describing services & characteristics then call for the init. Your interaction will then be made over callback functions. You can also manually push updates.

You can also add standard ble services like Battery, Device Information, UART and DFU services are not yet implemented but part of the next evolutions.

The library is in version 1,0 and will evolve based on my future needs. Don’t hesitate to request for evolution and to propose some pull requests.

The way to use it is to declare the service & characteristics you need like in the example :

const ble_dsk_peripherical_t myPeriph = {
    /* Peripherical name */                         "disk91Ble",
    /* add_mac_address after name */                false,
    /* Manufacturer name */                         "disk91.com",
    /* Appearance type */                           BLE_APPEARANCE_UNKNOWN,
    /* Basic Service to enable */                   BLE_DSK_SERVICE_BAS | BLE_DSK_SERVICE_DIS,
    /* UUID are 128b format */                      false,
    /* 128b uuid to be used */                      {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    /* Configuration bitfield */                    BLE_DSK_CONFIG_SERVICE_CHANGE_CHAR,

    /* Advertising mode */                          (BLE_DSK_ADV_MODE_SLOW | BLE_DSK_ADV_MODE_FAST),
    /* Advertising fast interval ms */              200,
    /* Advertising fast timeout in s */             20,     // 20 seconds
    /* Advertising slow interval ms */              600,
    /* Advertising slow timeout in s */             0,      // never ends
    /* Advertizing callback */                      onAdvertizingChanged,
    /* Advertizing callback stop */                 onAdvertizingChanged,

    /* Security options */                          BLE_DSK_SEC_DEFAULT_OPTIONS,            // Bonding + MITM
    /* Security io capability */                    BLE_DSK_SEC_DEFAULT_IOCAPA,             // None
    /* Security oob data */                         BLE_DSK_SEC_DEFAULT_OOBDATA,            // 0
    /* Security min key size */                     BLE_DSK_SEC_DEFAULT_MINKEYSZ,           // 7
    /* Security max key size */                     BLE_DSK_SEC_DEFAULT_MAXKEYSZ,           // 16

    /* GAP min cnx interval */                      BLE_DSK_GAP_DEFAULT_MINCNX,             // 100ms
    /* GAP max cnx interval */                      BLE_DSK_GAP_DEFAULT_MAXCNX,             // 200ms
    /* GAP slave latency */                         BLE_DSK_GAP_DEFAULT_SLAVLAT,            // 0
    /* GAP cnx Supervision timeout */               BLE_DSK_GAP_DEFAULT_CNXSUPTM,           // 4s

    /* CNX time for update on connect*/             BLE_DSK_CNX_DEFAULT_CNX_TIME,           // 5s
    /* CNX update time */                           BLE_DSK_CNX_DEFAULT_CNX_UPDATE,         // 30s
    /* CNX attempts */                              BLE_DSK_CNX_DEFAULT_CNX_TRY,            // 3
    /* CNX disconnect on fail */                    BLE_DSK_CNX_DEFAULT_DISC_ON_FAIL,   // false

    /* Battery level function */                    getBatteryLevel,

    /* Number of custom services */                 1,  
    /* Link to custom services desc */              myServices
};

Periph contains all the common parameters for the BLE stack. It also allow to start standard services like BAS (battery status) and DIS (device information).

It has a link to the service structure to describe your custom service and characteristics like in the following example. The bitbucket repository have a larger example with 2 services and 3 characteristics.

const ble_dsk_service_desc_t myServices[1] = {
{
    /* Service UUID */                          0x1900,
    /* Service Description */                   "testSrv",
    /* onConnect callback */                    onConnectTestSrv,
    /* onDisconnect callback */                 onDisconnectTestSrv,
    /* Number of characteristics */ 1,
    /* Characteristics */                     { 
    {
         /* Description */                              "testChar1",
         /* Characteristic UUID */                      0x2B01,
         /* Characteristic access right */              (BLE_DSK_ACC_READ | BLE_DSK_ACC_NOTIFY),
         /* Char Data len   */                          2,
         /* Char Data initial value */                  {0x00,0x01},
         /* Char onWrite callback   */                  NULL,
         /* Char onRead callback */                     onReadTestChar1             // set not NULL will request ReadWrite Auth
    }
    }
}
};

All these structure are constant to be stored in flash and preserve RAM. Size of the different elements can be tuned in one of the header files to preserve flash & code size.

Once all of this created, you just need to call the init function and create the characteristics associated callbacks to manage the input & output.

int main(void) {
    // Initialize timer module.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, 4, false);

    // Init the ble structure
    ble_dsk_peripherical_init(&myPeriph);

    for (;;) {
    sd_app_evt_wait();
  }
}

Main don’t need more than what you see above. Call back can be set to be called on every read or write actions ; asynchronous updates & notify is also supported

bool onReadTestChar1(uint8_t * data_buf) {
    uint16_t * _v = (uint16_t *) data_buf;
    *_v = (*_v+1);
    return true;
}
void onWriteTestChar2(uint8_t * v) {}

This library is GPL based, so do not hesitate to try & play with it. If you are looking for another license, you can contact me and we can find the best agreement to integrate it in your project.

The purpose of this BLE library for nRF51 and nRF52 is to get start in 10 minutes with custom ble services for the IoT.

3 thoughts on “NRF 51 BLE library for custom services

  1. How can we add UUID-180A Service in our project for nRF 52832 board using SDK v16.0 in SEGGER Embedded Studio. Can u please provide me a guide to do so ?

  2. Wow, it is a wonderful library! I downloaded it and I’m trying to set up custom BLE services on a nRF52832 CPU. I also sette up all the SDK, unfortunately now nordic SDK 17.0.2 doesn’t support pstorage and device_manager (it’s so annoying) so i’m trying to migrate to Peer Manager but working with nordic support is quite a mess. Is it possible to migrate to the new SDK functions?

    • I’m not doing a lot of NRF currenlty so I won’t work on this quiclky and I’m more focussing on ItSDK where I plan to support NFR as a target with an equivalent configuration approach.So stay tuned.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.