Advertising: Odd API design

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I am very puzzled by the API for controlling GAP Peripheral advertising. There appears to be two API functions:

   

CyBle_GappEnterDiscoveryMode: This requires a user-provided CYBLE_GAPP_DISC_MODE_INFO_T structure and allows full control of the settings ignoring the component configuration.

   

CyBle_GappStartAdvertisement: This seems to take the settings from the component configuration with the only option being to chose between Fast and Slow interval settings from the configuration ('custom' is also documented, but it is not clear what this does).

   

The second of these API functions is generated code which can be examined in source form, from which we can see that it simply calls the first (which is precompiled and not visible) passing it an undocumented CYBLE_GAPP_DISC_MODE_INFO_T instance which has presumably been created from the configuration settings (after some patching of interval settings).

   

This seems to be a very "all or nothing" approach: either let the component configuration control the one-and-only advertising settings or forget the configuration and do it all programatically. What if you just want to programatically control the Discovery Mode, for example? If you use Limited Discovery Mode, you will typically want to revert to Non-Discoverable advertising afterward so the paired central can re-connect.

   

I have found myself copying the source of CyBle_GappStartAdvertisement into my own code and modifying it with parameters to change other advertisment settings such as discovery mode. But this is not good programming practice since it assumes undocumented features not part of the API. Is there a better way?

0 Likes
7 Replies
Anonymous
Not applicable

Hi John,

   

The simplest approach with the APIs that are available is to directly modify the contents of the global cyBle_discoveryModeInfo and cyBle_discoveryParam structures that are used internally as needed (i.e. changing the discovery mode), and then use:

   

CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_CUSTOM)

   

...and:

   

CyBle_GappStopAdvertisement()

   

...to start and stop, since these take care of a few additional state-tracking niceties for you. The structure of these global variables can be found in the auto-generated BLE_StackGap.h header file or in the BLE component datasheet.

   

Just be sure to check the API result any time you start advertising, to ensure that you haven't modified the mode/param data outside of acceptable bounds.

0 Likes
Anonymous
Not applicable

Thanks,

   

I am trying to get my mind around what it means for a peripheral to be advertising with Discovery Mode: Non Discoverable; Advertising Type: Connectable undirected advertising. I assumed this would mean I could reconnect to a paired device using a known peripheral Bluetooth Address. But this does not seem to work: indeed there is no obvious way in CySmart (PC Version) to connect from the Devices List and the Non Discoverable device (logically) does not appear in the Discovered Devices list.

   

So I am puzzled about what the practical difference is between advertising in Non Discoverable mode and not advertising at all?

   

EDIT: Sorry, silly question! Just noticed in the Configure UI that you cannot set it Non Discoverable and Connectable. I guess when I tried that programatically I ignored the error message you warned me about before. Still trying to figure out how I can make my peripheral securely bind to a single central when it has no UI capability. I hoped I could have a short window after switch on when it could bind, but then would not re-bind without a subsequent power cycle.

0 Likes
Anonymous
Not applicable

It is quite possible to setup the PRoC module to bond to a device "securely", and then remain bonded permanently to that device. The biggest issue is in determining when to be open to bonding, and what criteria you use for bonding.

   

On bootup on the chip, you can check if there is already bond(s) in the BLESS that it has bonded to previously; It would be a simple matter to tweak your code behavior based on the presence of a bond then.

   

For my own application, I use a button sequence to trigger bonding mode, and then allow anyone to bond with it. The user just has to set both sides to bond at the same time to have it work properly 🙂

0 Likes
Anonymous
Not applicable

Thanks, yes I believe I tried that before. I do not think there is any way to get an authenticated connection that way, so how can I subsequently control the access limiting it to only bonded clients? I tried whitelisting to achieve that and it worked fine until Android updated to use privacy and now the client keeps changing Bluetooth address so the client gets blocked even though it is whitelisted. I understand I would need to update my hardware to Bluetooth 4.2 to be able to resolve the address at the peripheral end.

0 Likes
Anonymous
Not applicable

I've done some more experiments and found that the problem is you cannot simply change the discovery mode, you also have to patch the pre-marshaled advertising data so the flags are right! I'm not sure if this will always be the third byte or if I have to parse the whole 31 bytes to find it. Particularly irritating since the firmware must already be doing this parsing operation internally to detect the error and so could easily 'go the extra mile' and patch it for me!

   

This seems like a design flaw to me: it is not really possible to use limited discovery mode in a conformant way without subsequently falling back to general discovery mode, which you cannot do through the documented API. I think what is really needed is the possibility to configure multiple advertising sets in the configuration UI and then select between them using an index in the API (basically the same as the current timing settings, but working for all the advertising settings).

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I've had no trouble switching between discovery modes, but I'm not changing from General Discovery to Limited Discovery, but rather from whitelist to any.

   

I imagine I would mimic the same process I'm using however, and just apply it to more bits/settings in the discovery info structure.

   

I've attached an example of the code I use to configure the discovery information, and hopefully it helps you out.

   

For resolving the private address I found this document from cypress with the address resolution process, but unfortunately it is only for version 4.2 😞 http://www.cypress.com/file/224826/download

0 Likes
Anonymous
Not applicable

Thanks.

   

This was also illuminating:

   

https://github.com/cypresssemiconductorco/PSoC-4-BLE/tree/master/100_Projects_in_100_Days/Day017_Pri...

   

Seems it is possible to use privacy with 4.1 devices, but there is no support in the configurator. Still not sure I've got my head around restricting access to bonded devices when the pairing is not authenticated (or to authenticate it without any UI).

0 Likes