The BLE-CC254x-1.4.0 stack release broke the ability for peripheral implementations to completely control when advertising is and is not enabled. Our CC2540 based product requires direct control of when advertising happens in order to carefully minimize battery power drain. I recently discovered that our prototypes were advertising when they shouldn't be doing so. This had worked previously. After much effort, it became clear that the change in behavior was caused by the BLE 1.4.0 stack update. By sharing this discovery and work-around I hope to save others the effort to debug and fix this issue themselves. (Note that the impact here is subtle. Nothing in our prototypes quit working. They simply advertised far too often. After deliberating choosing to close the connection with the central device because there was no data to be exchanged, they would immediately re-advertise and re-connect to the central device.)
Unlike the 1.3.x stack, disabling advertising with the code sniper below does not leave advertising disabled. The 1.4.0 stack re-enables advertising within peripheral.c when the connection is dropped.
uint8 disable = 0;
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(disable), (void*)&disable);
If your application requires complete control over enabling and disabling advertising, you will need to modify peripheral.c.
Note that the Porting Guide for 1.4.0 posted on the TI Wiki (ti.com/ble-wiki) includes the remark in yellow below. This is NOT mentioned in the release notes. And the suggested change only partially addresses the issue.
- Advertising will now begin again after a connection is dropped by default. To remove this, comment out line 1021 of peripheral.c (shown below):
VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
Additional changes are necessary to regain application control over advertising.
- Comment out line 1018: "gapRole_AdvEnabled = TRUE;"
- Comment out line 1021 as mentioned above: "VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );"
- Comment out line 1131: "gapRole_AdvEnabled = TRUE;"
- Comment out line 1132: "VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT);"
Changes #1 & #2 above prevent advertising from silently being re-enabled upon a timeout disconnection.
Changes #3 & #4 above prevent advertising from silently being re-enabled upon a GAP_LINK_TERMINATED_EVENT.
TI Guru's -- I suggest that TI change the implementation of peripheral.c such than a second advertising enable boolean be used for peripheral.c internal disabling and enabling of advertising and that the gapRole_AdvEnabled boolean be changed ONLY via application code calls to GAPRole_SetParameter ( GAPROLE_ADVERT_ENABLED, …)
This will avoid the silent override of application desired control over advertising and provide a solution that works for all.
Respectfully,
Doug Bartlett
VP of Engineering
SmartMove Inc.
Edited 30Jan2014 by D. Bartlett: Corrections shown with pink highlight.