sandeepmistry / arduino-BLEPeripheral

An Arduino library for creating custom BLE peripherals with Nordic Semiconductor's nRF8001 or nR51822.
MIT License
463 stars 179 forks source link

Limitation on BLEPeripheral.addAttribute with 128-bit UUIDs #46

Open ThomasHeb opened 8 years ago

ThomasHeb commented 8 years ago

Hello Sandeep,

first of all, thanks a lot for that great lib. Made my first steeps on BLE very easy. My application is a connection from iPad to BLE Nano connected to dive computers having irda or similar strange interfaces. For setup, errorhandling and information exchange I am going to use several services and characteristics. Crossing the limit of 16 added services / characteristics showed, that all services / characteristics above 16 are not supported / processed anymore I walked through the source but couldn’t find a restriction. Can you please support me?

I tested on BLE Nano and Blend Micro (Blend Mirco has not enough RAM/ROM to go ahead with processing the dive data, so BLE Nano is in focus). I tested with static implementation as well as dynamic (new). Appending my source. The BLEPeripheral/BLECharacteristic is modified with a EventListener to be included inside a class (maybe you can include this code into your lib (search for: // Added by Thomas Heberlein)

See DriverBLE.h/cpp for handling the BLE interface. Archiv.zip

Regards and thanks a lot Thomas

sandeepmistry commented 8 years ago

@ThomasHeb thanks for reporting and providing sample code!

I need to try it out on my board still, much I imagine the call to sd_ble_uuid_vs_add is failing at some point, see documentation: https://devzone.nordicsemi.com/documentation/nrf51/4.1.0/html/group__ble__api.html#gab3101ab721b427d1548b5f77bf5118cf

NRF_ERROR_NO_MEM If the size exceeds the number of free slots for VS UUIDs.

This library tries to add a new VS UUID id for each attribute, even though a slot might be able to be re-used. One thing to try is switching to all 16-bit id's to test this theory.

Btw, for future issue reported please supply as example sketch that can be used with the library as is. This simplifies things for me.

sandeepmistry commented 8 years ago

@ThomasHeb ping ....

ThomasHeb commented 8 years ago

Hi Sandeep,

I am back from holiday and on a business trip for the next two weeks, so sorry for my delay. I reworked my code to reduce the number of used attributes, so actually I got all communication running between the BLE and the iPad. Never the less i can populate the system with a high number of dive computer UUIDs. I will check 16 bit IDs over the weekend and post my results here.

Regards Thomas

ThomasHeb commented 8 years ago

Hi Sandeep,

I changed to 16bit UUIDs. With that modification I am able to increase the number of working characteristics. So this issue seems to be around sd_ble_uuid_vs_add .

Regards Thomas

sandeepmistry commented 8 years ago

@ThomasHeb thanks for looking into this, I've updated the title of the issue to include 128-bit.

rogerclarkmelbourne commented 8 years ago

Thomas Are you sure you are simply not exceeding the maximum advertising packet size.

Each time you add a new data block to the advertising, it not only adds the data but it has a block header which contains the block type and I think the block length.

So if you have a Name block and a 16 bit services ID block, you have 2 block headers as well as the data

If the name is not essential to you, its possible to not send it.

Using 128 bit UUIDs takes up loads of space, and I think there is only room for 1 128 bit service UUID If you want to advertising multiple services you'd need to use 16 or 32 bit services. and even then, you soon run out of space if you have a lot of different services

You may be better off rolling all your comms into one custom service

sandeepmistry commented 8 years ago

@rogerclarkmelbourne this is not related to advertising, this library only support advertising 1 service UUID.

The root cause is the multiple calls to sd_ble_uuid_vs_add that add a custom 128-bit UUID to the Nordic stack. There's a limit to how many UUID's can be added, and the library currently doesn't check if a previously added 128-bit UUID can be re-used. Adding the smarts for this can remove the issue in some scenarios, however it will still exist if you try to add N unique custom 128-bit UUIDs.