GAPRole Task¶
The GAPRole task is a separate task which offloads handling most of the GAP layer functionality from the application. This task is enabled and configured by the application during initialization. Based on this configuration, many Bluetooth low energy protocol stack events are handled directly by the GAPRole task and never passed to the application. Callbacks exist that the application can register with the GAPRole task so that the application task can be notified of certain events and proceed accordingly.
Based on the configuration of the device, the GAP layer always operates in one of four roles:
- Broadcaster - The device is an advertiser that is non connectable.
- Observer - The device scans for advertisements but cannot initiate connections.
- Peripheral - The device is an advertiser that is connectable and operates as slave in a single link-layer connection.
- Central - The device scans for advertisements and initiates connections and operates as a master in a single or multiple link-layer connections. The Bluetooth low energy central protocol stack supports up to three simultaneous connections.
The Bluetooth Core Specification Version 4.2 allows for certain combinations of multiple-roles, which are supported by the Bluetooth low energy protocol stack. For configuration of the Bluetooth low energy stack features, see Creating a Custom Bluetooth low energy Application
For supported GAPRole API, see BLE Stack API Reference.
Peripheral Role¶
The peripheral GAPRole task is defined in peripheral.c and peripheral.h. See the BLE Stack API Reference for the full API Peripheral Role API including commands, configurable parameters, events, and callbacks. The steps to use this module are as follows:
- Initialize the GAPRole parameters. This
initialization should occur in the application initialization
function. (for example
simple_peripheral_init
shown in Listing 58.).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // Setup the GAP Peripheral Role Profile
{
uint8_t initialAdvertEnable = TRUE;
uint16_t advertOffTime = 0;
uint8_t enableUpdateRequest = DEFAULT_ENABLE_UPDATE_REQUEST;
uint16_t desiredMinInterval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16_t desiredMaxInterval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
uint16_t desiredSlaveLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
uint16_t desiredConnTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
// Set the GAP Role Parameters
GAPRole_setParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
&initialAdvertEnable);
GAPRole_setParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
&advertOffTime); GAPRole_setParameter(GAPROLE_SCAN_RSP_DATA,
sizeof(scanRspData), scanRspData);
GAPRole_setParameter(GAPROLE_ADVERT_DATA, sizeof(advertData),
advertData); GAPRole_setParameter(GAPROLE_PARAM_UPDATE_ENABLE,
sizeof(uint8_t), &enableUpdateRequest);
GAPRole_setParameter(GAPROLE_MIN_CONN_INTERVAL,
sizeof(uint16_t), &desiredMinInterval);
GAPRole_setParameter(GAPROLE_MAX_CONN_INTERVAL,
sizeof(uint16_t), &desiredMaxInterval);
GAPRole_setParameter(GAPROLE_SLAVE_LATENCY, sizeof(uint16_t),
&desiredSlaveLatency);
GAPRole_setParameter(GAPROLE_TIMEOUT_MULTIPLIER,
sizeof(uint16_t), &desiredConnTimeout);
}
|
- Initialize the GAPRole task and pass application callback functions to GAPRole. This should also occur in the application initialization function.
1 2 | // Start the Device
VOID GAPRole_StartDevice(&SimpleBLEPeripheral_gapRoleCBs);
|
- Send GAPRole commands from the application. Figure 43. is an example of the application using GAPRole_TerminateConnection().
1 | GAPRole_TerminateConnection();
|
Note
The return value only indicates whether the attempt to terminate the connection initiated successfully. The actual termination of connection event is returned asynchronously and is passed to the application through a callback.
- The GAPRole task processes most of the GAP-related events passed to it from the Bluetooth low energy protocol stack. The GAPRole task also forwards some events to the application. When a link is terminated, the GAPRole automatically restarts advertising. The following code snippet can be found in peripheral.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | case GAP_LINK_TERMINATED_EVENT:
{
//.......
//.......
//.......
// If device was advertising when connection dropped
if (gapRole_AdvNonConnEnabled)
{
// Continue advertising.
gapRole_state = GAPROLE_ADVERTISING_NONCONN;
}
// Else go to WAITING state.
else
{
if(pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM)
{
gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
}
else
{
gapRole_state = GAPROLE_WAITING;
}
// Start advertising, if enabled.
gapRole_setEvent(START_ADVERTISING_EVT);
}
}
break;
|
Central Role¶
The central GAPRole task is defined in central.c and central.h. See the BLE Stack API Reference for the full Central Role API including commands, configurable parameters, events, and callbacks. See the simple_central example project for an example of implementing the central GAPRole. The steps to use this module are as follows.
- Initialize the GAPRole parameters.
This initialization should occur in the application
initialization function (for example in
SimpleBLECentral_init
). GAP parameters can also be set in this initialization function.
// Setup Central Profile
{
uint8_t scanRes = DEFAULT_MAX_SCAN_RES;
GAPCentralRole_SetParameter(GAPCENTRALROLE_MAX_SCAN_RES,
sizeof(uint8_t), &scanRes);
}
- Start the GAPRole task. This involves passing function pointers to application callback function to the central GAPRole. This should also occur in the application initialization function.
VOID GAPCentralRole_StartDevice(&SimpleBLECentral_roleCB);
- Send GAPRole commands from the application. Figure 44. is an example of the application using GAPCentralRole_StartDiscovery().
The return status from the protocol stack indicates only whether or not the attempt to perform device discovery was initiated. The actual device discovered is returned asynchronously as a GAP_DEVICE_INFO_EVENT forwarded through the central GAPRole callbacks as described below.
- The GAPRole task performs some processing on the GAP events it receives from the protocol stack. The task also forwards some events to the application. Figure 44. also shows how the GAP_DEVICE_INFO_EVENT is processed from the protocol stack to the application.
Note that during scanning, as defined by the Bluetooth Core Specification Version 4.2, individual advertisements / scan responses are returned as GAP_DEVICE_INFO_EVENT. By default, duplicate reports are filtered such that only one event is returned to the application per unique address and data pair. This can be configured via the TGAP_FILTER_ADV_REPORTS GAP parameter. After the scan has completed, a summary of discovered reports will be returned to the application as a GAP_DEVICE_DISCOVERY_EVENT.
The maximum amount of scan responses that can be discovered during one scan can be set with the GAPCENTRALROLE_MAX_SCAN_RES parameter. In an environment saturated with advertisements / scan responses, this can have a drastic impact on heap usage to the point of potentially breaking the stack. Therefore, it is essential to profile your application for the worst-case scenario where the maximum amount of scan responses are discovered during a scan.
In the worst-case scenario where the maximum number of advertisements / scan responses ( n ) is found during a scan, all with the maximum data size, in which the application is consistently processing such that it does not process any of the stack’s messages, the heap could grow by: ( 8 + 87 * n bytes ). For example, if GAPCENTRALROLE_MAX_SCAN_RES is set to 10, there must be at least 878 bytes available for allocation from the heap. This includes a completely filled GAP_DEVICE_DISCOVERY_EVENT. If this allocation fails, a GAP_DEVICE_DISCOVERY_EVENT with error status will attempt to be allocated instead which is only 8 bytes. Therefore, in order for the system to keep running in the scenario described above, the heap must have space to allocate at least ( 8 + 79 * n bytes ). See the Debugging chapter for steps to profile the heap.