GAP — Usage Scenarios#
WiSeConnect Bluetooth Low Energy (BLE) example projects under examples/snippets/ble/<example_folder>/ show GAP flows. Each scenario below states when to use it and gives a compact implementation example: #include lines as in the SDK, a one-line // caption (same style as other SiWx917 usage-scenario guides), then the API sequence. Non-essential branches are folded to // .... Full sources live under wiseconnect/examples/snippets/ble/ relative to the WiSeConnect SDK content root; the same tree is published in the Silicon Labs wiseconnect GitHub repository (WiseConnect SDK).
Related: BLE usage scenarios hub, GAP overview, BLE initialization and configuration, Debugging and error handling.
Register GAP Callbacks#
When to Use#
After wireless/BLE stack initialization, register GAP event handlers before starting advertising, scanning, or connection procedures.
Pass
NULLonly for slots your application does not use (for example advertising report on a peripheral-only device).
Implementation Example#
rsi_ble_gap_register_callbacks() takes ten parameters (WiSeConnect rsi_ble_apis.h). Unused parameters are NULL. A non-NULL argument must be a function pointer type-compatible with that position’s rsi_ble_on_*_t typedef (parameter and return types only; the function identifier is not specified by the API). Snippet identifiers follow SDK examples and are illustrative. End-of-line comments pair role or feature with NULL when peripheral-only, unused, or optional.
#include "rsi_ble_apis.h"
rsi_ble_gap_register_callbacks(
rsi_ble_on_adv_report_event, // adv report — NULL if peripheral_only or unused
rsi_ble_on_connect_event, // connect — NULL if unused
rsi_ble_on_disconnect_event, // disconnect — NULL if unused
rsi_ble_on_le_ping_payload_timeout, // LE ping timeout — NULL if unused
rsi_ble_on_phy_update_complete, // PHY update — NULL if unused
rsi_ble_on_data_length_update, // data length update — NULL if unused
rsi_ble_on_enhance_connect, // enhanced connection status — NULL if unused
rsi_ble_on_directed_adv_report_event, // directed adv report — NULL if peripheral_only or unused
rsi_ble_on_conn_update_complete, // connection update complete — NULL if unused
rsi_ble_on_remote_conn_params_request); // remote conn params request — NULL if unusedDual-role or compile-time role samples (for example ble_power_save) pick one set of pointers per BLE_ROLE. SDK example projects use longer internal names (for example rsi_ble_simple_central_on_adv_report_event in ble_central) but the same slot order.
Note: Parameter order matches the WiSeConnect API. See Register Callbacks and Callbacks Declarations. Pairing flows often add
rsi_ble_smp_register_callbacks()in the same initialization sequence.
Typical Use Case 1: Peripheral — Advertise and Accept a Connection#
When to Use#
The device must be discoverable and connectable using legacy advertising.
After a central connects, the application handles connection status and may start SMP (same example project).
Implementation Example#
Step 1: Start Connectable Advertising#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// Legacy ADV + name: ble_secureconnection/app.c (rsi_bt_set_local_name earlier in same init path)
uint8_t adv[31] = {2, 1, 6};
adv[3] = strlen(RSI_BLE_DEVICE_NAME) + 1;
adv[4] = 9; // Complete Local Name (0x09)
strcpy((char *)&adv[5], RSI_BLE_DEVICE_NAME);
rsi_ble_set_advertise_data(adv, strlen(RSI_BLE_DEVICE_NAME) + 5);
status = rsi_ble_start_advertising();
if (status != RSI_SUCCESS) {
return;
}Note:
rsi_ble_start_advertising()has no parameters that carry advertising type or interval. That example project’sble_config.hdefinesRSI_BLE_ADV_TYPE, the WiSeConnect GAP sources includeble_config.hand copy those values into the internal advertise requestadv_typebefore it issuesRSI_BLE_REQ_ADV. To set advertise fields explicitly at call time, usersi_ble_start_advertising_with_values().
Step 2: Connection Acceptance and Handling (Peripheral)#
With rsi_ble_on_connect_event registered under Register GAP callbacks, the main task runs on RSI_BLE_CONN_EVENT and can request pairing.
#include "rsi_ble_apis.h"
// GAP callback — connection complete (ble_secureconnection/app.c)
static void rsi_ble_on_connect_event(rsi_ble_event_conn_status_t *resp_conn)
{
memcpy(remote_dev_address, resp_conn->dev_addr, 6);
rsi_6byte_dev_address_to_ascii(str_remote_address, resp_conn->dev_addr);
rsi_ble_app_set_event(RSI_BLE_CONN_EVENT);
}
// Main-task handler — case RSI_BLE_CONN_EVENT (ble_secureconnection/app.c)
rsi_ble_app_clear_event(RSI_BLE_CONN_EVENT);
if (!pairing_info_available) {
status = rsi_ble_smp_pair_request(remote_dev_address, RSI_BLE_SMP_IO_CAPABILITY, MITM_REQ);
}Note: Disconnect raises
RSI_BLE_DISCONN_EVENTin the same file. Full flow: projectreadme.md.
SDK Example Project#
Goal | Example folder |
|---|---|
Pairing + encryption |
|
Extended advertising |
|
Power save |
|
See also: Peripheral role, GATT server.
Typical Use Case 2: Central — Scan and Connect#
When to Use#
Discover peripherals by scanning, then initiate a connection to a selected device.
After the link is up, handle connection status in the application task (same example project).
Implementation Example#
Step 1: Start Scanning#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// ble_central/app.c — default scan parameters
status = rsi_ble_start_scanning();
if (status != RSI_SUCCESS) {
return;
}Step 2: Advertising Report — Stop Scan, Connect#
rsi_ble_simple_central_on_adv_report_event() is registered in Register GAP callbacks. It fills remote_addr_type and remote_dev_bd_addr when the advertised name or address matches the example’s compile-time defines, then raises RSI_APP_EVENT_ADV_REPORT.
// Main task — case RSI_APP_EVENT_ADV_REPORT (ble_central/app.c)
status = rsi_ble_stop_scanning();
if (status != RSI_SUCCESS) {
return;
}
status = rsi_ble_connect(remote_addr_type, (int8_t *)remote_dev_bd_addr);
if (status != RSI_SUCCESS) {
return;
}Step 3: Connection Established (Central)#
rsi_ble_gap_register_callbacks() registers rsi_ble_simple_central_on_conn_status_event() (or the enhanced variant). The task handles RSI_APP_EVENT_CONNECTED.
#include "rsi_ble_apis.h"
// Connection complete callback — ble_central/app.c
void rsi_ble_simple_central_on_conn_status_event(rsi_ble_event_conn_status_t *resp_conn)
{
memcpy(&rsi_app_connected_device, resp_conn, sizeof(rsi_ble_event_conn_status_t));
if (ble_peripheral_conn_sem) {
osSemaphoreRelease(ble_peripheral_conn_sem);
}
rsi_ble_app_set_event(RSI_APP_EVENT_CONNECTED);
}
// Main task — case RSI_APP_EVENT_CONNECTED
rsi_ble_app_clear_event(RSI_APP_EVENT_CONNECTED);
rsi_6byte_dev_address_to_ascii(str_remote_address, rsi_app_connected_device.dev_addr);Recommendation: On
RSI_APP_EVENT_DISCONNECTED, the example clearsdevice_found, restartsrsi_ble_start_scanning(), and can rediscover.
SDK Example Project#
Goal | Example folder |
|---|---|
Central |
|
Extended scan |
|
Accept list |
|
Multi-link |
|
See also: Central role, GATT client.
Typical Use Case 3: Broadcaster — Beacon-Style Payload#
When to Use#
Fixed iBeacon-style (or similar) payload plus optional scan response.
Implementation Example#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// iBeacon payload filled earlier in adv[]; scan response = local name (ble_ibeacon/app.c)
rsi_ble_set_advertise_data(adv, 30);
scan_data[3] = strlen(RSI_BLE_LOCAL_NAME) + 1;
scan_data[4] = 9;
strcpy((char *)&scan_data[5], RSI_BLE_LOCAL_NAME);
rsi_ble_set_scan_response_data(scan_data, 31);
status = rsi_ble_start_advertising();
if (status != RSI_SUCCESS) {
// ...
return;
}Note: Assign and check
statusfrom each API in production builds.
Note: Broadcaster-style samples use the same
rsi_ble_set_advertise_data()/rsi_ble_start_advertising()pattern as connectable peripheral demos; connectable vs non-connectable is determined byRSI_BLE_ADV_TYPEin that example project’sble_config.h(for exampleUNDIR_NON_CONNfor iBeacon-style advertising), not by extra arguments onrsi_ble_start_advertising(). See the note under Typical Use Case 1 for how those macros reach the stack.
SDK Example Project#
Goal | Example folder |
|---|---|
iBeacon |
|
See also: Broadcaster role.
Typical Use Case 4: Observer — Extended Scan#
When to Use#
Legacy scan: Use Case 2. Extended scan: configure AE parameters, then enable.
Periodic advertising sync (receive a periodic train) uses extended scan plus additional APIs; see Typical Use Case 6.
Implementation Example#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// Extended scan — ble_ae_central/app.c (1M + Coded PHY, interval/window from macros)
rsi_ble_ae_set_scan_params_t ae_set_scan_params = { 0 };
ae_set_scan_params.own_addr_type = LE_PUBLIC_ADDRESS;
ae_set_scan_params.scanning_filter_policy = RSI_BLE_SCAN_FILTER_TYPE;
ae_set_scan_params.scanning_phys = (PHY_1M | PHY_LE_CODED);
ae_set_scan_params.ScanParams[AE_SCAN_SET1].ScanInterval = LE_SCAN_INTERVAL;
ae_set_scan_params.ScanParams[AE_SCAN_SET1].ScanWindow = LE_SCAN_WINDOW;
// ... optional AE_SCAN_SET2 when SET2_ENABLE
status = rsi_ble_ae_set_scan_params(&ae_set_scan_params);
rsi_ble_ae_set_scan_enable_t ae_set_scan_enable = { 0 };
ae_set_scan_enable.enable = RSI_BLE_START_SCAN;
ae_set_scan_enable.filter_duplicates = BLE_SCAN_ENABLE_FILTER_DUP;
ae_set_scan_enable.duration = BLE_SCAN_DUR;
ae_set_scan_enable.period = BLE_SCAN_PERIOD;
status = rsi_ble_ae_set_scan_enable(&ae_set_scan_enable);
if (status != RSI_SUCCESS) {
// ...
return;
}SDK Example Project#
Goal | Example folder |
|---|---|
AE central |
|
See also: Observer role, Extended advertising.
Typical Use Case 5: Extended Advertising — Peripheral Enable#
When to Use#
After
rsi_ble_set_ae_params()/rsi_ble_set_ae_data(), turn the AE set on.
Implementation Example#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// Start extended advertising — ble_ae_peripheral/app.c
rsi_ble_ae_adv_enable_t ble_ae_adv = { 0 };
ble_ae_adv.enable = RSI_BLE_START_ADV;
ble_ae_adv.no_of_sets = 1;
ble_ae_adv.adv_handle = BLE_ADV_HNDL1;
ble_ae_adv.duration = 0;
ble_ae_adv.max_ae_events = BLE_MAX_AE_EVNTS;
status = rsi_ble_start_ae_advertising(&ble_ae_adv);
if (status != RSI_SUCCESS) {
// ...
return;
}SDK Example Project#
Goal | Example folder |
|---|---|
AE peripheral |
|
Coex sample |
|
See also: Extended advertising.
Typical Use Case 6: Periodic Advertising and Periodic Advertising Sync#
When to Use#
Periodic advertising sends connectionless application data on a fixed schedule (one-to-many). Receivers use periodic sync to align with that schedule and receive at those times instead of scanning continuously—useful for telemetry or beacons and when a GATT connection to every device is not required.
Peripheral (advertiser): After extended advertising parameters and data are set for an advertising set, configure periodic advertising parameters and data, start extended advertising, then enable periodic advertising on that set (example:
ble_ae_peripheral/app.cwithPERIODIC_ADV_ENset to1).Observer (receiver): With extended scanning enabled (see Typical Use Case 4), register extended advertising callbacks for periodic events, optionally manage the periodic advertiser list, then create periodic sync to a specified advertiser address and SID. Handle sync established, periodic reports, and sync lost in the application task (
ble_ae_central/app.c).
Implementation Example#
Peripheral — Periodic Advertising Enable#
Abbreviated from ble_ae_peripheral/app.c (paths under #if PERIODIC_ADV_EN). Set PERIODIC_ADV_EN to 1 in the example to compile this path. Order: rsi_ble_set_ae_params() → rsi_ble_app_set_periodic_ae_params() → rsi_ble_set_ae_data() with BLE_AE_PERIODIC_ADV_DATA_TYPE → rsi_ble_start_ae_advertising() → rsi_ble_app_set_periodic_ae_enable().
#include "rsi_ble_apis.h"
#include "ble_config.h"
// After rsi_ble_set_ae_params() for the set — ble_ae_peripheral/app.c
#if PERIODIC_ADV_EN
rsi_ble_ae_periodic_adv_params_t ae_periodic_param = { 0 };
ae_periodic_param.max_interval = 0x190;
ae_periodic_param.min_interval = 0x90;
ae_periodic_param.properties = 0x40;
ae_periodic_param.adv_handle = BLE_ADV_HNDL1;
status = rsi_ble_app_set_periodic_ae_params(&ae_periodic_param);
if (status != RSI_SUCCESS) {
return;
}
#endif
// Periodic advertising data, then extended data as in the example; then:
status = rsi_ble_start_ae_advertising(&ble_ae_adv);
// ...
#if PERIODIC_ADV_EN
status = rsi_ble_app_set_periodic_ae_enable(1, 0);
#endifObserver — Register Callbacks and Create Periodic Sync#
From ble_ae_central/app.c: call ble_extended_adv_callbacks_register() (or equivalent) so periodic sync established / periodic report / sync lost events are delivered; then after AE scan is enabled:
#include "rsi_ble_apis.h"
#include "ble_config.h"
// Optional: add advertiser to periodic list when BLE_AE_PERIODIC_LIST_USED
// rsi_ble_ae_dev_to_periodic_list(&ae_add_dev);
// Create periodic sync — ble_ae_central/app.c
rsi_ble_ae_set_periodic_adv_create_sync_t ae_per_sync_create = { 0 };
rsi_ascii_dev_address_to_6bytes_rev((uint8_t *)ae_per_sync_create.adv_addr, (int8_t *)REM_ADDR);
ae_per_sync_create.adv_addr_type = LE_PUBLIC_ADDRESS;
ae_per_sync_create.adv_sid = BLE_AE_ADV_SID;
ae_per_sync_create.options = BLE_AE_OPTIONS;
ae_per_sync_create.skip = BLE_AE_ADV_SKIP;
ae_per_sync_create.sync_timeout = BLE_AE_SYNC_TIMOUT;
status = rsi_ble_ae_set_periodic_sync(BLE_AE_PER_SYNC_CREATE, &ae_per_sync_create);
if (status != RSI_SUCCESS) {
return;
}Main-task branches handle RSI_APP_EVENT_AE_PER_SYNC_ESTBL, periodic report events, and RSI_APP_EVENT_AE_PER_ADV_SYNC_LOST as in the full example. Optional BLE_AE_PER_SYNC_CANCEL and BLE_AE_PER_SYNC_TERMINATE paths use the same rsi_ble_ae_set_periodic_sync() API with different command values.
SDK Example Project#
Goal | Example folder |
|---|---|
Periodic advertising (peripheral) |
|
Periodic sync + reports (observer) |
|
See also: Extended advertising, Observer role, Broadcaster role.
Typical Use Case 7: LE Privacy#
When to Use#
Add bonded peers to the resolving list, then enable address resolution.
Implementation Example#
#include "rsi_ble_apis.h"
// Add to resolving list — ble_privacy/app.c (helper add_device_to_resolvlist)
status = rsi_ble_resolvlist(RSI_BLE_ADD_TO_RESOLVE_LIST,
resolve_key_p->Identity_addr_type,
temp_le_sec_keys.Identity_addr,
resolve_key_p->peer_irk,
resolve_key_p->local_irk);
if (status != RSI_SUCCESS) {
return status;
}
// Enable resolution + RPA timeout — same file (after list size query)
status = rsi_ble_set_addr_resolution_enable(RSI_BLE_DEV_ADDR_RESOLUTION_ENABLE,
RSI_BLE_SET_RESOLVABLE_PRIV_ADDR_TOUT);
if (status != RSI_SUCCESS) {
// ...
return;
}Caution: Do not call
rsi_ble_set_addr_resolution_enable()while scanning, advertising, or connection setup is active. See LE Privacy.
SDK Example Project#
Goal | Example folder |
|---|---|
Privacy |
|
See also: LE Privacy, Pairing and bonding.
Typical Use Case 8: Data Length Extension (DLE)#
When to Use#
After connect/MTU handling, read max LL length and set data length.
Implementation Example#
#include "rsi_ble_apis.h"
// DLE request — ble_datalength/app.c (RSI_BLE_MTU_EVENT path); TX_LEN / TX_TIME from project headers
status = rsi_ble_read_max_data_len(&blereadmaxdatalen);
if (status != RSI_SUCCESS) {
return;
}
status = rsi_ble_set_data_len(rsi_app_connected_device.dev_addr, TX_LEN, TX_TIME);
// Retries until success (goto loop in source)SDK Example Project#
Goal | Example folder |
|---|---|
DLE |
|
PHY |
|
See also: Data length extension.
Typical Use Case 9: Connection Parameter Update#
When to Use#
After a connection is established, the host requests updated LL connection interval, peripheral latency, and supervision timeout for that peer (throughput / latency / energy tradeoff on the link). Macro values typically come from
ble_config.h(for exampleCONN_INTERVAL_MIN,CONN_INTERVAL_MAX,CONN_LATENCY,SUPERVISION_TIMEOUTinble_throughput_app).
Implementation Example#
#include "rsi_ble_apis.h"
#include "ble_config.h"
// ble_throughput_app/app.c — connection parameters (names vary by example project ble_config.h)
status = rsi_ble_conn_params_update(remote_dev_address,
CONN_INTERVAL_MIN,
CONN_INTERVAL_MAX,
CONN_LATENCY,
SUPERVISION_TIMEOUT);
if (status != RSI_SUCCESS) {
// ...
}Note: This is GAP / LL connection timing on an active link, not Network Processor (NWP) sleep or MCU power management. NWP power save (PSP, Wi‑Fi performance profile, idle sleep in the app task) is described on the BLE usage scenarios hub using
ble_power_save.
SDK Example Project#
Goal | Example folder |
|---|---|
Conn param update + throughput demo |
|
See also: Data length extension, Peripheral role.
Summary#
Scenario | Primary example |
|---|---|
GAP callback registration |
|
Peripheral advertise |
|
Central scan/connect |
|
iBeacon |
|
Extended scan |
|
Extended adv enable |
|
Periodic advertising / periodic sync |
|
Privacy |
|
DLE |
|
Connection parameter update |
|
APIs Used in This Section#
Topic | APIs / symbols | Reference |
|---|---|---|
GAP — registration |
| |
GAP — legacy advertising, scan, connect |
| |
GAP — extended scanning |
| |
GAP — extended advertising (sets, data, enable) |
| |
GAP — periodic advertising and periodic sync |
| |
SMP — pairing (examples) |
| |
LE Privacy |
| |
Data length extension |
| |
LL connection parameters |
| |
GAP event types (callbacks) |
|
Integration: BLE API reference; Developing with WiSeConnect SDK.