|
Radio Control Layer (RCL)
|
In Bluetooth® Low Energy (BLE), scanning and initiating are key processes for establishing connections between devices.
Scanning is the process by which a central device discovers nearby peripheral devices and can be classified either as passive scanning or active. Passive scanning involves the central device listening on specific advertising channels for advertising packets sent by peripheral devices which contain information about the peripherals, such as their identity, services offered, and signal strength. Active scanning on the other hand occurs when the central device sends scan request PDUs to solicit additional information from specific advertising peripherals after passively receiving their advertising packets.
The initiating process occurs after the scanning phase and involves a central device establishing a connection with a specific peripheral device it has discovered. Initiating differs from scanning in that once the central device has identified a peripheral of interest during the scanning phase, it proceeds to establish a connection by sending connection request PDUs. Unlike scanning, where the central device listens for advertising packets and is not required to respond to them, initiating requires active communication between the central and peripheral devices. The central device sends a connection request PDU to the identified peripheral, indicating its intention to establish a connection and specifying the connection parameters. This triggers a series of negotiation processes, including the exchange of connection parameters and acknowledgment PDUs between both devices, which ultimately leads to the establishment of a BLE connection between the central and peripheral devices.
Just like for the advertiser command handler, before describing how the scanner/initiator command works, it is worth listing the different PDUs involved in the command handler's life cycle.
| PDU Type | PDU Name | Physical Channel | LE 1M | LE 2M | LE Coded | Currently Supported |
|---|---|---|---|---|---|---|
| 0b0000 | ADV_IND | Primary | * | * | ||
| 0b0001 | ADV_DIRECT_IND | Primary | * | * | ||
| 0b0010 | ADV_NONCONN_IND | Primary | * | * | ||
| 0b0011 | SCAN_REQ | Primary | * | * | ||
| 0b0011 | AUX_SCAN_REQ | Secondary | * | * | * | * |
| 0b0100 | SCAN_RSP | Primary | * | * | ||
| 0b0101 | CONNECT_IND | Primary | * | * | ||
| 0b0101 | AUX_CONNECT_REQ | Secondary | * | * | * | * |
| 0b0110 | ADV_SCAN_IND | Primary | * | * | ||
| 0b0111 | ADV_EXT_IND | Primary | * | * | * | |
| 0b0111 | AUX_ADV_IND | Secondary | * | * | * | * |
| 0b0111 | AUX_SCAN_RSP | Secondary | * | * | * | * |
| 0b0111 | AUX_SYNC_IND | Periodic | * | * | * | * |
| 0b0111 | AUX_CHAIN_IND | Secondary and Periodic | * | * | * | * |
| 0b0111 | AUX_SYNC_SUBEVENT_IND | Periodic | * | * | * | |
| 0b0111 | AUX_SYNC_SUBEVENT_RSP | Periodic | * | * | * | |
| 0b1000 | AUX_CONNECT_RSP | Secondary | * | * | * | * |
Please note that legacy advertising PDUs are limited to primary advertising channels and have a specific payloads, while extended advertising PDUs share the same PDU payload format known as the Common Extended Advertising Payload Format.
The scanner/initiator command handler supports both legacy and extended advertising by extracting the PDU type, and if needed the AdvMode associated with the PDU.
Even though scanning and initiating are two different processes, their similarities are sufficient to allow for a single command handler that can be configured either for scanning or for initiating. This is because after all, the main difference between both commands (scanner or initiator) is that the expected outcome of an initiator is to establish a connection with the desired peripheral device. Therefore, aspects such as the configuration of the acceptance or rejection of legacy or extended advertising packets are common to both commands.
As any other command handler, the following steps must take place to use the command.
Once these steps have been completed, RCL_Command_submit is called to start the command. Upon submitting the command, the caller can either use RCL_Command_pend or a callback to wait for the command's conclusion and proceed with any additional tasks such as post-processing or the submitting of new commands.
The scanner command can be configured to behave either as an active or as a passive scanner for both legacy and extended advertising packets. Based on this, it will only listen to advertising PDUs, or it will send scan request PDUs (i.e. SCAN_REQ or AUX_SCAN_REQ) to receive possible scan responses.
For legacy advertising, this means that once an advertising PDU has been received, and a potential scan request has be sent and replied to (if configured to do so), the command handler will restart scanning unless the operation has timed out. For extended advertising, the behavior is somewhat different as it depends on the information in the received PDUs. If the received PDU has an AuxPtr pointing to an auxiliary PDU, and that auxiliary PDU is expected to come before the timeout set by the command (i.e.maxAuxPtrWaitTime), the scanner will move to a new advertising channel and set up a new listening window based on the information in the AuxPtr. The operation will only end once an advertising packet is received without an AuxPtr. It's worth mentioning that the scanner command handler can also be used as entry point for periodic advertising. The synchronization information about the periodic advertising event is sent as part of an AUX_ADV_IND PDU which can then be used by the application to schedule a Periodic Scanner command (RCL_CMD_BLE5_PER_SCANNER_t).
The following code snippet shows how a passive scanner can be configured to receive both legacy and extended advertising packets.
PDUs received on a primary channel can correspond to either legacy advertising or extended advertising. The following tables describe the scanner's behavior and the actions it takes when receiving either a legacy or an extended advertising PDU on a primary channel.
TODO: Generate table for legacy packets.
| PDU Type | AdvMode | AdvA Type | Known AdvA | RpaMode.Peer | TargetA Type | Known TargetA | RpaMode.Own | Action # |
|---|---|---|---|---|---|---|---|---|
| ADV_EXT_IND | 00 | X | Yes | X | X | Yes | X | 1 |
| ADV_EXT_IND | 00 | Public | No | X | X | X | X | 2 |
| ADV_EXT_IND | 00 | X | X | X | Public | No | X | 2 |
| ADV_EXT_IND | 00 | RPA | No | No | X | X | X | 2 |
| ADV_EXT_IND | 00 | RPA | No | Yes | X | X | X | 3 |
| ADV_EXT_IND | 00 | X | X | X | RPA | No | No | 2 |
| ADV_EXT_IND | 00 | X | X | X | RPA | No | Yes | 3 |
| ADV_EXT_IND | 01/10 | N/A | N/A | X | N/A | N/A | X | 4 |
| Action # | LRF Rx Event | PBE End Cause | RCL Command Status | ignoredAddr | Description |
|---|---|---|---|---|---|
| 1 | rxOk | ENDOK | Undetermined at this point | 0 | Receive ADV_EXT_IND, check for AuxPtr, and follow it if needed. Otherwise end operation with RCL_CommandStatus_Finished. |
| 2 | None | RXERR | RCL_CommandStatus_RxErr | 0 | Ignore ADV_EXT_IND and end command. |
| 3 | rxOk | RXERR | RCL_CommandStatus_RxErr | 1 | Receive ADV_EXT_IND and end command. |
| 4 | rxOk | ENDOK | Undetermined at this point | 0 | Receive ADV_EXT_IND, check for AuxPtr and follow it. |
PDUs received on a secondary channel can only correspond to extended advertising. The following table describes the behavior and actions the scanner takes when receiving such types of PDUs.
| PDU Type | AdvMode | SyncInfo in PDU | AdvA Type | Known AdvA | RpaMode.Peer | TargetA Type | Known TargetA | RpaMode.Own | PeriodicSyncEstablishment | Action # |
|---|---|---|---|---|---|---|---|---|---|---|
| AUX_ADV_IND | 00 | X | X | Yes | X | X | Yes | X | X | 1 |
| AUX_ADV_IND | 00/01/10 | No | Public | No | X | X | X | X | X | 2 |
| AUX_ADV_IND | 00/01/10 | No | X | X | X | Public | No | X | X | 2 |
| AUX_ADV_IND | 00/01/10 | No | RPA | No | No | X | X | X | X | 2 |
| AUX_ADV_IND | 00/01/10 | No | RPA | No | Yes | X | X | X | X | 3 |
| AUX_ADV_IND | 00/01/10 | No | X | X | X | RPA | No | No | X | 2 |
| AUX_ADV_IND | 00/01/10 | No | X | X | X | RPA | No | Yes | X | 3 |
| AUX_ADV_IND | 01 | No | X | Yes | X | X | Yes | X | X | 4 |
| AUX_ADV_IND | 10 | No | X | Yes | X | X | Yes | X | X | 5 |
| AUX_ADV_IND | 00 | Yes | X | Yes | X | X | Yes | X | X | 1 |
| AUX_ADV_IND | 00 | Yes | Public | No | X | X | X | X | No | 2 |
| AUX_ADV_IND | 00 | Yes | X | X | X | Public | No | X | No | 2 |
| AUX_ADV_IND | 00 | Yes | RPA | No | No | X | X | X | No | 2 |
| AUX_ADV_IND | 00 | Yes | RPA | No | Yes | X | X | X | No | 3 |
| AUX_ADV_IND | 00 | Yes | X | X | X | RPA | No | No | No | 2 |
| AUX_ADV_IND | 00 | Yes | X | X | X | RPA | No | Yes | No | 2 |
| AUX_ADV_IND | 00 | Yes | Public | No | X | X | X | X | Yes | 6 |
| AUX_ADV_IND | 00 | Yes | X | X | X | Public | No | X | Yes | 6 |
| AUX_ADV_IND | 00 | Yes | RPA | No | No | X | X | X | Yes | 6 |
| AUX_ADV_IND | 00 | Yes | RPA | No | Yes | X | X | X | Yes | 6 |
| AUX_ADV_IND | 01/10 | Yes | X | X | X | X | X | X | X | 2 |
| AUX_CHAIN_IND | 00 | N/A | N/A | N/A | X | N/A | N/A | X | X | 1 |
| AUX_CHAIN_IND | 01/10 | N/A | N/A | N/A | X | N/A | N/A | X | X | 2 |
| AUX_SCAN_RSP | 00 | N/A | X | Yes | X | N/A | N/A | X | X | 7 |
| AUX_SCAN_RSP | 00 | N/A | X | nO | X | N/A | N/A | X | X | 2 |
| AUX_SCAN_RSP | 01/10 | N/A | N/A | N/A | X | N/A | N/A | X | X | 2 |
| Action # | LRF Rx Event | PBE End Cause | RCL Command Status | ignoredAddr | SyncInfoOnly | Description |
|---|---|---|---|---|---|---|
| 1 | rxOk | ENDOK | Undetermined at this point | 0 | 0 | Receive AUX_ADV_IND, check for AuxPtr, and follow it if needed. Otherwise end operation with RCL_CommandStatus_Finished. |
| 2 | None | RXERR | RCL_CommandStatus_RxErr | 0 | 0 | Ignore AUX_ADV_IND and end command. |
| 3 | rxOk | RXERR | RCL_CommandStatus_RxErr | 1 | 0 | Receive AUX_ADV_IND and end command. |
| 4 | rxOk | ENDOK | RCL_CommandStatus_Finished | 0 | 0 | Receive AUX_ADV_IND and end command, since it's a connectable PDU. |
| 5 | rxOk | ENDOK | Undetermined at this point | 0 | 0 | Receive AUX_ADV_IND, send AUX_SCAN_REQ and wait for response. |
| 6 | rxOk | RXERR | RCL_CommandStatus_RxErr | 0 | 1 | Receive AUX_ADV_IND and end command. |
| 7 | rxOk | ENDOK | Undetermined at this point | 0 | 0 | Receive AUX_SCAN_RSP, check for AuxPtr. Follow it if needed, or end operation with RCL_CommandStatus_Finished. |
Unlike scanning, initiating is not a passive operation. The expectation is that if the conditions are right, the initiator will attempt to form a connection with the advertiser by sending a connection request PDU and potentially receiving a connect response (if it's Extended Advertising).
For legacy advertising, this means that once an connectable advertising PDU has been received, the initiator will send a CONNECT_IND that contains information about the connection parameters. Once this occurs, the operation will conclude. For extended advertising, establishing a connection process also involves the advertiser device responding to the connect request PDU (i.e. AUX_CONNECT_REQ) sent by the initiator with a connect response. It's important to take into account that the initiator command handler will only respond to connectable PDU types (i.e. ADV_IND, ADV_DIRECT_IND, extended advertising PDUs with AdvMode 0b01).
The following code snippet shows how an initiator can be configured to establish a connection with an advertiser using extended advertising.
See: RCL-815
See: RCL-815
See: RCL-815
PDUs received on a secondary channel can only correspond to extended advertising. The following table describes the behavior and actions the initiator takes when receiving such types of PDUs.
See: RCL-815