| STM32WBA_BLE_UM
STM32WBA Bluetooth® LE Stack User Manual

Revision history

Rev 1.0 (27 January 2023): First release.

Rev 1.1 (March 2023): Update maximum number of supported Links and a new condition to call the BleStack_Process.

Rev 1.2 (2 June 2023): Update Bluetooth® LE library folder structure picture (add ble_legacy.h file); Fix some spell errors; Define bitmap of “options” argument of “BleStack_init_t”; Replace BLE with Bluetooth® LE.

Rev 1.3 (6 October 2023): Update the section 2.1.2 library variants: Add “figure 2: Bluetooth® LE stack variants”; Update the paragraph detailing the 4 variants to be clearer; Update the certified features.

Rev 1.4 (10 November 2023): Update timer ID parameter of BLEPLAT_Timer functions.

Rev 1.5 (20 December 2023): Update table of supported features variants. Update libraries compilation information.

Rev 1.6 (11 January 2024): Minor update of the table of supported features variants. Add unaligned memory access note.

Rev 1.7 (22 January 2024): Update table of supported features variants.

Rev 1.8 (10 April 2024): Update BLE Stack variants. Add BLE Stack wrapper section. Figures updated.

Rev 1.9 (13 May 2024): Update BLE Stack and Link Layer Footprint; Update BLE Stack user interface section.

Rev 1.10 (17 September 2024): Update BLE Stack and Link Layer Footprint; Update table of supported features variants; Update References section; Update Stack porting section.

Rev 1.11 (20 November 2024): Update table of supported features variants; Update options descriptions of “BleStack_init_t”; RAM footprint added; Add BLEPLAT_AesCcmCrypt description.

Rev 1.12 (25 February 2025): Update notes in BLE platform functions and Real-Time environment sections; Replace Bluetooth® LE by BLE; Update acronyms.

Rev 1.13 (3 April 2025): Update NVM functions section; Update BLE stack initialization sections.

Rev 1.14 (6 May 2025): Update BLE Stack and Link Layer Footprint; Update BLE stack initialization section.

Rev 1.15 (26 June 2025): Add Host FIFO events information; Update BLE Stack initialization and BLE Stack process sections.

Rev 1.16 (28 August 2025): Update BLE stack initialization section; Update BLE Stack and Link Layer Footprint; Update library variants; Update BLE platform Timer functions.

Rev 1.17 (29 September 2025): Update library variants; Update Application compilation options section.

# List of tables

Table 1: Acronym definitions 1

Table 2: Supported features of each BLE stack variant 1

Table 3: BleStack_Init function 1

Table 4: BleStack_Init function's parameters 1

Table 5: BleStack_Process function 1

Table 6: BleStack_Request function 1

Table 7: BLECB_Indication function 1

Table 8: BLEPLAT_Init function 1

Table 9: BLEPLAT functions' returns 1

Table 10: BLEPLAT NVM functions 1

Table 11: BLEPLAT Timer functions 1

Table 12: BLEPLAT AES functions 1

Table 13: BLEPLAT PKA functions 1

Table 14: BLEPLAT RNG function 1

# List of figures

Figure 1: BLE Stack folder structure. 1

Figure 2: BLE stack variants. 1

# 1 About this document

## 1.1 Purpose

This document describes to an application developer how to integrate the STM32WBAxx Bluetooth® LE stack library.

## 1.2 Scope

This document covers only the Bluetooth® LE stack library integration, and it does not include the Link Layer integration aspects.

## 1.3 Acronym definitions

Acronym | Definition
BLE | Bluetooth® Low Energy
HCI | Host Controller Interface
ACI | Application Command Interface
LL | Link Layer
N/A | Not Applicable

Table 1: Acronym definitions

## 1.4 References

- STM32WBA_BLE_Wireless_Interface.html

- RM0493 - Reference Manual - Multiprotocol wireless Bluetooth® Low-Energy and IEEE802.15.4, STM32WBA5xxx Arm®-based 32-bit MCUs

- PM0271 - Programming manual - Guidelines for Bluetooth® Low Energy stack programming on STM32WB/STM32WBA MCUs

# 2 BLE stack overview

## 2.1 Release contents

### 2.1.1 Folder structure

The BLE stack delivery contains 3 folders as follows:

Figure 1: BLE Stack folder structure

- “doc” folder contains the current document and “STM32WBA_BLE_Wireless_Interface.html” which describes the BLE Application Commands Interface (ACI) and the Host Commands Interface (HCI).

- “include” folder contains the header files of the BLE stack library interface. These files contain some definitions of constants and types and the declarations of ACI and HCI functions. It also contains the declarations of some external modules’ functions used by the BLE stack (for more details see section 4.2)

- “lib” folder contains the BLE stack libraries described in the following section.

### 2.1.2 Library variants

The BLE stack library is delivered in 5 variants as follows:

· 4 variants containing the BLE host stack:

o Full stack (stm32wba_ble_stack_full.a)

o Basic Plus stack (stm32wba_ble_stack_basic_plus.a)

o Basic Features stack (stm32wba_ble_stack_basic.a)

o Peripheral Only stack (stm32wba_ble_stack_po.a)

· 1 variant without the BLE host stack (it contains the LE Controller only):

o Link Layer Only stack (stm32wba_ble_stack_llo.a)

Figure 2: BLE stack variants

Here are the 5 BLE stack variants details:

- Full stack (stm32wba_ble_stack_full.a) includes the LE Controller and the Host Stack, both with all the supported features.
It contains all the legacy stack supported features plus the advertising extensions, GATT caching, Enhanced ATT, ACI HCI flow control, isochronous support for audio, L2CAP connection oriented channels.

Note: This BLE stack variant can be configured to run in controller only mode (host stack is bypassed).
See the parameter “options” of the initialization structure BleStack_init_t parameters in section 3.1 to enable/disable the controller only mode.
Please refer to PM0271 to know which command is available if controller only mode is enabled or not.

- Basic Plus stack (stm32wba_ble_stack_basic_plus.a) includes the LE Controller and the Host Stack, both with the basic features along with additional features as Extended Advertising/Scanning, LE Power Control and Connection Subrating, Enhanced ATT, L2CAP connection oriented channels and GATT caching features.

- Basic Features stack (stm32wba_ble_stack_basic.a) includes the LE Controller and the Host Stack, both with the basic features.
It contains only BLE legacy features without extended advertising, neither GATT caching, nor ACI HCI flow control, nor isochronous support, nor L2CAP connection oriented channels. The Host Stack is included, and it supports all the basic GATT, GAP and L2CAP features.

- Peripheral Only stack (stm32wba_ble_stack_po.a) includes the LE Controller and the Host Stack, both with the basic features but only for peripheral role.
The Host Stack is included, and it supports all the basic GATT, GAP and L2CAP features.

- Link Layer Only stack (stm32wba_ble_stack_llo.a) includes only the LE Controller with all the supported features and is compatible with any Link Layer variant.
This variant doesn’t contain the Host Stack.

For more information, please refer to “STM32WBA_BLE_Wireless_Interface.html” to know which ACI and HCI command/event is supported by each stack configuration.

The table below details the supported features for each BLE stack variant:

VARIANT | Full Host Stack + LE Controller (stm32wba_ble_stack_full) | Basic Plus Host Stack + LE Controller (stm32wba_ble_stack_basic_plus) | Basic Features Host Stack + LE Controller (stm32wba_ble_stack_basic) | Peripheral Only Host Stack + LE Controller (stm32wba_ble_stack_po) | Link Layer Only LE Controller Only (stm32wba_ble_stack_llo)
Link Layer library dependency (4) | LinkLayer_BLE_Full_lib | LinkLayer_BLE_Basic_Plus_lib | LinkLayer_BLE_Basic_lib | LinkLayer_BLE_Peripheral_Only_lib | Compatible with all Link Layer libraries
Stack Library Flash Footprint (1) | 83 KB | 68 KB | 55 KB | 43 KB | Up to 24 KB
Link Layer Library Flash Footprint (1) | 234 KB | 130 KB | 92 KB | 72 KB | Refer to the FLASH footprint of the Link Layer variant used
Stack Library RAM Footprint (1)(3) | 2 KB | 1 KB | 1 KB | 1 KB | 1 KB
Link Layer Library RAM Footprint (1) | 26 KB | 18 KB (for 8 connections) 27 KB (for 20 connections) | 14 KB (for 8 connections) 22 KB (for 20 connections) | 13 KB | Refer to the RAM footprint of the Link Layer variant used
Direct Test Mode | Certified | Certified | Certified | Certified | Certified
Advertising | Certified | Certified | Certified | Certified | Certified
Scanning | Certified | Certified | Certified | Not Supported | Certified
Connection Peripheral (5) | Certified | Certified | Certified | Certified | Certified
Connection Central (5) | Certified | Certified | Certified | Not Supported | Certified
Security & Privacy (6) | Certified | Certified | Certified | Certified | Certified
LE 2M PHY / LE Coded PHY | Certified | Certified | Certified | Certified | Certified
LE Advertising Extensions | Certified | Certified | Not Supported | Not Supported | Certified
LE Periodic Advertising (7) | Certified | Not Supported | Not Supported | Not Supported | Certified
Sleep Clock Accuracy Update | Certified | Not Supported | Not Supported | Not Supported | Certified
Angle of Arrival/Angle of Departure | Certified | Not Supported | Not Supported | Not Supported | Certified
Periodic Advertising Sync Transfer | Certified | Not Supported | Not Supported | Not Supported | Certified
LE Isochronous Channels | Certified | Not Supported | Not Supported | Not Supported | Certified
LE Power Control | Certified | Certified | Not Supported | Not Supported | Certified
Connection Subrating | Certified | Certified | Not Supported | Not Supported | Certified
Channel Classification enhancement | Certified | Not Supported | Not Supported | Not Supported | Certified
Advertising Coding Selection | Certified | Certified | Not Supported | Not Supported | Certified
Encrypted Advertising Data | Enabled | Not Supported | Not Supported | Not Supported | Enabled
Configuration HCI only | Certified | Not Supported | Not Supported | Not Supported | N/A
GATT Client | Certified | Certified | Certified | Not Supported | N/A
LE L2CAP Connection Oriented channel | Certified | Certified | Not Supported | Not Supported | N/A
Enhanced Attribute Protocol | Certified | Certified | Not Supported | Not Supported | N/A
GATT caching | Certified | Certified | Not Supported | Certified | N/A
Number of supported links | Up to 8 | Up to 20 (2) | Up to 20 (2) | Up to 8 | Up to 20 (2)

Table 2: Supported features of each BLE stack variant

(1): These values were computed with STM32CubeWBA Firmware Package v1.8.0 using Keil® environment.

(2): It might be limited to 8 or 20 links depending on the Link Layer library used (libraries with 20_links_lib suffix for 20 links)

(3): In addition to the BLE Stack library RAM, the BLE Stack requires RAM memory from the application (see section 3.1 )

(4): Each STM32WBA series has its own Link Layer libraries (ex: WBA5_LinkLayer_BLE_Full_lib).

(5): Supports LE Data Packet Length Extension and LE Channel Selection Algorithm #2.

(6): LE Encryption / LE Secure Connections / LE Ping / Link Layer Privacy / LE Privacy v1.1 / Link Layer Extended Filter Policies.

(7): Supports Periodic Advertising ADI.

## 2.2 Real-Time environment

The BLE stack library is independent from the real-time software environment as well as any real-time resource.

The functions of this library used during run-time are:

- The BLE stack commands (HCI, ACI...),

- The BLE stack process,

- The BLE stack callback functions called by the link layer or the platform software (PKA, Timer...).

Note that these BLE stack functions are not reentrant. It is therefore recommended to prevent any reentrancy by construction. The wrapper described in the “BLE stack wrapper” section can help with this for the BLE stack commands. A straightforward approach would be to call all these functions from the same context of execution, i.e., from the same task when using a real-time operating system or from the main loop in a bare metal environment.

## 2.3 Library dependencies

The BLE stack library depends on (i.e. it must be linked with the following libraries):

- STM32WBAxx Link Layer libraries (refer to Table 2 BLE stack variants for Link Layer library configuration dependency).

- Standard C library:

o Only basic memory functions are used (memcpy, memset, memmove, memcmp)

## 2.4 Library compilation options

The BLE stack library is compiled with the following options in Keil® environment:

- General options:

o Byte order: Little-endian

o FPU: VFPv5 single precision

- C/C++ Compilation options

o Compilation options

--library_interface=aeabi_clib : Used to generate AEABI-compliant object code

--mno-unaligned-access : Used to enforce aligned memory access

o Plain 'char' is unsigned.

As mentioned above, the BLE stack library is AEABI compliant; The advantage of adhering to AEABI is that the BLE stack library can be linked with any other AEABI-compliant module, even modules produced by tools provided by other vendors than Keil®.

For the enum type, the Keil® C/C++ compiler uses the smallest type required to hold enum constants (-fshort-enums), preferring signed rather than unsigned.

## 2.5 Application compilation options

These compilation options are compulsory:

o Plain 'char' is unsigned

o Short enum:

· For IAR® compiler, this option is set by default

· Keil µvision® environment with ARM® CC compiler, the following option shall be added: -fshort-enums

In CubeIDE environment with GCC compiler, there is no need to add specific compiler options or linker options.

In addition to compiler options, the BLE stack requires preprocessor symbols to be defined depending on the variant used (BLE_STACK_PERIPHERAL_ONLY, BLE_STACK_BASIC_FEATURES, BLE_STACK_BASIC_PLUS. No preprocessor is required for the Full and Link Layer Only variants). These symbols are used by the "ble_bufsize.h" to calculate the size of the BLE stack RAM buffers.

# 3 BLE stack user interface

To use the main functions of the BLE stack library, the user application code needs to include “blestack.h”.

In addition, to be able to directly call BLE commands (see section 3.3.2), the application needs to also include “blecore.h”.

## 3.1 BLE stack initialization

Functions | Parameters | Return Value
BleStack_Init | BleStack_init_t* init_params_p | tBleStatus

Table 3: BleStack_Init function

BleStack_Init: The BLE Stack initialization routine. This function is used to define the memory and configure the BLE Stack.
Those parameters are not applicable for “Link Layer Only” variants, except for “options” and “debug” parameters.
All BleStack_init_t parameters are described below:

BleStack_init_t parameters | Definition | Value
uint16_t numAttrRecord | Maximum number of attribute records related to all the required characteristics (excluding the services) that can be stored in the GATT database, for the specific BLE user application. | Value = <number of user attributes> + 9 Min value = 9 Max value: depending on the GATT database defined by the user application.
uint16_t numAttrServ | Defines the maximum number of services that can be stored in the GATT database. Note that the GAP and GATT services are automatically added at initialization so this parameter must be the number of user services increased by two. | Value = <number of user services> + 2. Min value = 2 Max value: depending on the GATT database defined by the user application.

uint16_t attrValueArrSize

Size of the storage area for the attribute values

By default, two services are present and must be included, with dedicated characteristics:

• Generic access service: service UUID 0x1800, with its three mandatory characteristics:

o Device name UUID 0x2A00.

o Appearance UUID 0x2A01.

o Peripheral preferred connection parameters. UUID 0x2A04.

• Generic attribute service. UUID 0x1801, with one optional characteristic:

o Service changed UUID 0x2A05.

Each characteristic contributes to the attrValueArrSize value as follows:

• Characteristic value length plus:

o 5 bytes if characteristic UUID is 16 bits

o 19 bytes if characteristic UUID is 128 bits

o 2 bytes if characteristic has a server configuration descriptor

o 2 bytes * NUM_OF_LINKs if the characteristic has a client configuration descriptor

o 2 bytes if the characteristic has extended properties

Depends on the number of attributes used by the application.

uint8_t numOfLinks | Maximum number of simultaneous connections that the device supports. | Min value: 1 Max value: 20 (or 8 depending on the LL library used)
uint8_t prWriteListSize | Maximum number of supported “prepare ATT write request”. | Value defined by the macro: DIVC (max_char_size, default_att_mtu - 5) * 2 max_char_size: Maximum characteristic’s value size BLE_DEFAULT_ATT_MTU = 23

uint8_t mblockCount

Number of allocated memory blocks for the BLE stack.

Value defined by the macro:

BLE_MBLOCKS_CALC (PREP_WRITE_LIST_SIZE, MAX_ATT_MTU, NUM_LINKS) + MBLOCK_COUNT_MARGIN)

With:
- PREP_WRITE_LIST_SIZE defined by the parameter prWriteListSize.
- MAX_ATT_MTU defined by the attMtu parameter

- NUM_LINKS defined by the numOfLinks parameter
- MBLOCK_COUNT_MARGIN the memory margin to take.

uint8_t max_add_eatt_bearers | Maximum number of bearers that can be created for Enhanced ATT in addition to the number of links. | Min value: 0 Max value: 64
uint16_t attMtu | Maximum ATT MTU size supported. | Min value: 23 Max value: 512
uint16_t max_coc_mps | Maximum value of the connection-oriented channel Maximum Payload Size. | Min value: 23 Max value: 248
uint8_t max_coc_nbr | Maximum number of connection-oriented channels. | Min value: 0 Max value: 64
uint8_t max_coc_initiator_nbr | Maximum number of connection-oriented channels in initiator mode. | Min value: 0 Max value: max_coc_nbr
uint8_t* bleStartRamAddress | Start address of the RAM buffer allocated for BLE stack library. It must be a 32bit aligned RAM area. |

uint32_t total_buffer_size

Size of the RAM buffer allocated for BLE stack library.

Value defined by the macro:
BLE_TOTAL_BUFFER_SIZE (NUM_LINKS, MBLOCK_COUNT, NUM_ADD_BEARERS)

With

- NUM_LINKS: the maximum number of links defined by the parameter numOfLinks.
- MBLOCK_COUNT: the number of allocated memory blocks, defined by the parameter mblockCount.

- NUM_ADD_BEARERS: The maximum number of bearers that can be created for Enhanced ATT defined by the parameter max_add_eatt_bearers.

uint8_t* bleStartRamAddress_GATT | Start address of the RAM buffer allocated for GATT database. It must be a 32bit aligned RAM area. |
uint32_t total_buffer_size_GATT | Size of the RAM buffer allocated for GATT database. | Value defined by the macro: BLE_TOTAL_BUFFER_SIZE_GATT (NUM_ATTR_RECORD, NUM_ATTR_SERV, ATTR_VALUE_ARR_SIZE) With - NUM_ATTR_RECORD: defined by the parameter numAttrRecord. - NUM_ATTR_SERV: defined by the parameter numAttrServ. - ATTR_VALUE_ARR_SIZE: defined by the parameter attrValueArrSize.
uint8_t* gatt_long_write_buffer | Address of the RAM buffer allocated for GATT long write procedures. | - If ACI_GATT_WRITE_LONG_CHAR_VALUE / ACI_GATT_WRITE_CHAR_RELIABLE commands are used, this parameter must point to a 256-byte static buffer. - If these commands are never used, this parameter can be set to NULL.

uint8_t* extra_data_buffer

Address of the RAM buffer allocated for the extension of Host commands. This buffer is referred to as the "extra data" buffer in the BLE Wireless Interface document.

- If ACI_GATT_WRITE_WITHOUT_RESP_EXT / ACI_GATT_WRITE_WITH_RESP_EXT commands are used, this parameter must point to static buffer.

- If these commands that need this extension are never used, this parameter can be set to NULL.

uint32_t extra_data_buffer_size | Size of the RAM buffer allocated for the extension of Host commands. | - If the “extra_data_buffer” is unused, the size can be set to 0.
uint16_t* host_event_fifo_buffer | Address of the Host events FIFO buffer. |
uint16_t host_event_fifo_buffer_size | Size of the Host events FIFO buffer (in 16-bit words). | Min value advised: 512 Host Event FIFO can be disabled by setting size to 0.
uint64_t* nvm_cache_buffer | Start address of the RAM buffer allocated for BLE NVM cache. |
uint16_t nvm_cache_size | Size of actual data in BLE NVM cache (in 64-bit words). | Min value: 0 Max value: nvm_cache_max_size - 1
uint16_t nvm_cache_max_size | Maximum size of BLE NVM cache (in 64-bit words). | Min value: 1 Max value: 1024

uint16_t options

Options flags. Bitmap of the “BLE_OPTIONS_...” definitions:

bit number | bit value = 1 | bit value = 0
0 | LL only | LL + host
1 | Remove the Service Changed characteristic | Add the Service Changed characteristic
2 | Device name Read-Only | Device name R/W
3 | Extended adv supported | Extended adv not supported
5 | Reduced GATT database in NVM | Full GATT database in NVM
6 | GATT caching is used | GATT caching is not used
7 | LE Power Class 1 | Other LE Power Classes
8 | Appearance Writable | Appearance Read-Only
9 | Enhanced ATT supported | Enhanced ATT not supported
others | Reserved

BLE_OPTIONS_LL_ONLY(1) = 0x0001U,

BLE_OPTIONS_NO_SVC_CHANGE_DESC = 0x0002U,

BLE_OPTIONS_DEV_NAME_READ_ONLY = 0x0004U,

BLE_OPTIONS_EXTENDED_ADV = 0x0008U,

BLE_OPTIONS_REDUCED_DB_IN_NVM = 0x0020U,

BLE_OPTIONS_GATT_CACHING = 0x0040U,

BLE_OPTIONS_POWER_CLASS_1 = 0x0080U,

BLE_OPTIONS_APPEARANCE_WRITABLE = 0x0100U

BLE_OPTIONS_ENHANCED_ATT = 0x0200U

uint32_t debug | Debug flags | BLE_DEBUG_RAND_ADDR_INIT = 0x00000010UL

Table 4: BleStack_Init function's parameters

(1): This option is only available in the FULL variant and allows to switch to HCI only mode or ACI mode.

The BLE Host Stack RAM memory must be allocated by the application. This RAM memory is composed of:

- the BLE stack and ACL buffers RAM (defined by the bleStartRamAddress and total_buffer_size parameters)

- the GATT database RAM (defined by the bleStartRamAddress_GATT and total_buffer_size_GATT parameters)

The size of this memory depends on several parameters, such as the maximum number of links, the maximum ATT MTU size, the maximum number of services, etc.

These RAM sizes can be computed using the BLE_TOTAL_BUFFER_SIZE and BLE_TOTAL_BUFFER_SIZE_GATT macros from ble_bufsize.h.

Here is an example of the RAM impact depending on the maximum number of connections, services and attributes:

| RAM usages (Bytes)
Variant | Full & Basic Plus | Basic | Peripheral only
BLE Host Stack and ACL buffer RAM (*) (example config: 8 connections, ATT MTU set to 300, prep. write list size set to 30) | 9 996 | 9 164 | 8 684
RAM impact per connection (with ATT MTU set to 300) | 708 | 656 | 628
GATT database (example config: 8 services, 68 attributes, 1344 bytes allocated for attributes values) | 4 448 | 4 448 | 4 448
RAM impact per Service | 48 | 48 | 48
RAM impact per Attribute | 40 | 40 | 40
Total BLE Host Stack RAM (example config: 8 connections, ATT MTU set to 300, 8 services, 68 attributes, 1344 bytes allocated for attributes values) | 14 444 | 13 612 | 13 132

(*: This memory includes the memory required for the 8 connections)

Example:

BleStack_init_t pInitParams;

pInitParams.numAttrRecord = CFG_BLE_NUM_GATT_ATTRIBUTES;

pInitParams.numAttrServ = CFG_BLE_NUM_GATT_SERVICES;

pInitParams.attrValueArrSize = CFG_BLE_ATT_VALUE_ARRAY_SIZE;

pInitParams.prWriteListSize = CFG_BLE_ATTR_PREPARE_WRITE_VALUE_SIZE;

pInitParams.attMtu = CFG_BLE_MAX_ATT_MTU;

pInitParams.max_coc_nbr = CFG_BLE_MAX_COC_NUMBER;

pInitParams.max_coc_mps = CFG_BLE_MAX_COC_MPS;

pInitParams.max_coc_initiator_nbr = CFG_BLE_MAX_COC_INITIATOR_NBR;

pInitParams.numOfLinks = CFG_BLE_NUM_LINK;

pInitParams.mblockCount = CFG_BLE_MBLOCK_COUNT;

pInitParams.bleStartRamAddress = (uint8_t*)buffer;

pInitParams.total_buffer_size = BLE_DYN_ALLOC_SIZE;

pInitParams.bleStartRamAddress_GATT = (uint8_t*)gatt_buffer;

pInitParams.total_buffer_size_GATT = BLE_GATT_BUF_SIZE;

pInitParams.debug = BLE_DEBUG_RAND_ADDR_INIT;

pInitParams.options = 0x0000;

pInitParams.gatt_long_write_buffer = gatt_write_long_buffer;

pInitParams.extra_data_buffer = extra_data_buffer;

pInitParams.extra_data_buffer_size = EXTRA_DATA_BUF_SIZE;

pInitParams.host_event_fifo_buffer = host_evt_fifo_buffer;

pInitParams.host_event_fifo_buffer_size = HOST_EVT_BUF_SIZE;

pInitParams.nvm_cache_buffer = (uint64_t*)buffer_nvm;

pInitParams.nvm_cache_size = CFG_BLE_NVM_SIZE;

pInitParams.nvm_cache_max_size = CFG_BLE_NVM_MAX_SIZE;

pInitParams.max_add_eatt_bearers = CFG_BLE_MAX_EATT_BEARERS;

return_status = BleStack_Init(&pInitParams);

## 3.2 BLE stack process

The BleStack_Process function runs all Host stack layers’ dedicated processes.

Functions | Parameters | Return Value
BleStack_Process | None | BLE_SLEEPMODE_RUNNING (0): -> BLE Stack Process must be executed. BLE_SLEEPMODE_CPU_HALT (1): -> BLE Stack Process does not have to be executed.

Table 5: BleStack_Process function

The BleStack_Process function shall be called in the following conditions:

- The Link Layer has been scheduled.

- To handle BLE Host Stack events.

- An ACI/HCI command, ACL data or ISO data has been sent to the BLE stack (either by calling BleStack_Request or by direct call to a specific command).

- By the platform software at the timer expiry or the end of PKA activity.

- When the BleStack_Process function returns BLE_SLEEPMODE_RUNNING, it shall be re-called. If it returns BLE_SLEEPMODE_CPU_HALT, there is no need to call this function again and the MCU could go to sleep mode.

Example:

return_status = BleStack_Process();

if (return_status == BLE_SLEEPMODE_RUNNING)

// BleStack_Process shall be re-called again

else

// The MCU can go to sleep mode

## 3.3 BLE stack ACI/HCI interface

We have two ways to send commands and receive events in ST’s BLE Stack: Transparent Mode or Direct Mode.

### 3.3.1 Transparent Mode

To use BLE stack in Transparent Mode, a buffer that contains the ACI/HCI command or ACL data packet shall be passed as parameter to the function BleStack_Request.

The ACI/HCI command is executed. The response event (command complete/ command status) is returned in the same buffer, and the size (in bytes) of the response event is given by the function’s return value.

Functions | Parameters | Return Value
BleStack_Request | uint8_t* buffer [IN/OUT]: Buffer of bytes in the BLE standard format HCI/ACI command packet or ACL data packet. The response packet is returned in the same buffer and the size (in bytes) of the response is given by the function’s return value. | The size (uint16_t) of the response packet returned in the buffer parameter.

Table 6: BleStack_Request function

Example:

// It is recommended to initiate the buffer at maximum length that Bluetooth® LE Stack supports.

uint8_t reset_cmd[255] = {0x01, 0x03, 0x0C, 0x00};

/* BLE Stack executes Reset command, the Command Complete Event is returned in reset_cmd array,

the total length of event is returned in event_length. */

uint16_t event_length = BleStack_Request(reset_cmd);

// The response packet is in Bluetooth® LE standard format.

uint8_t cmd_status = reset_cmd[6];

The ACI/HCI asynchronous events must be processed in the BLECB_Indication callback.

The value returned by the BLECB_Indication callback shall indicate whether the event has been processed by the application or not. In case the unprocessed event is stored in the Host or the LL event FIFO, it will later be sent to the application again. Otherwise, it will be discarded.

This function is called by the BLE Stack with the following parameters:

Functions | Parameters | Return Value

BLECB_Indication

- const uint8_t* data: The data buffer

- uint16_t length: The length of the data buffer

- const uint8_t* ext_data: The extended data buffer. This buffer is used only for ISO data and ACL data events

- uint16_t ext_length: The length of the extended data buffer

uint8_t:

- 0 for success

- Other values mean that the event hasn’t been handled by the application and can be stored in the Host or LL events FIFO.

Table 7: BLECB_Indication function

Example:

uint8_t BLECB_Indication(const uint8_t* data, uint16_t length,

const uint8_t* ext_data, uint16_t ext_length)

{

if (data[0] == HCI_LE_META_EVT_CODE)

{

// Check the subevent_code and the parameter length

if ((data[2] == HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE) && (data[1] == 0x13))

{

hci_le_connection_complete_event_rp0 *p_conn_complete;

p_conn_complete = (hci_le_connection_complete_event_rp0 *) (data + 3);

printf("Connection DONE - Connection handle: 0x%04X\n", p_conn_complete->Connection_Handle);

printf("Connection established with @:%02x:%02x:%02x:%02x:%02x:%02x\n",

p_conn_complete->Peer_Address[5],

p_conn_complete->Peer_Address[4],

p_conn_complete->Peer_Address[3],

p_conn_complete->Peer_Address[2],

p_conn_complete->Peer_Address[1],

p_conn_complete->Peer_Address[0]

);

printf("Connection parameters:\n- Connection Interval: %.2f ms\n- Connection latency: %d\n- Supervision Timeout: %d ms\n",

p_conn_complete->Conn_Interval * 1.25,

p_conn_complete->Conn_Latency,

p_conn_complete->Supervision_Timeout * 10

);

}

}

return 0;

}

### 3.3.2 Direct Mode

The Direct Mode provides a dedicated API for each ACI/HCI command and event.

Instead of using BleStack_Request / BLECB_Indication like in transparent mode, the ACI/HCI commands/events can be used through dedicated functions. Those functions are listed and detailed in the document STM32WBA_BLE_Wireless_Interface.html.

To use the direct mode, the BLE wrapper shall be compiled, that means “ble_wrap.c” needs to be included (see section 3.3.2.1).

#### 3.3.2.1 BLE stack wrapper

The BLE stack includes a wrapper to execute user-defined pre and post processing for each BLE command.

The wrapper is implemented in the include/auto/ble_wrap.c file and defines each pre-processing and post-processing macro.

Each wrapper macro can be defined at the application level to execute dedicated code. By default, all specific macros are defined to the generic macros: “BLE_WRAP_PREPROC” and “BLE_WRAP_POSTPROC”.

The “BLE_WRAP_PREPROC” and “BLE_WRAP_POSTPROC” are empty macros; it is up to the user to redefine those macros to execute pre and post processing respectively for every command.

Wrapper implementation:

/* Generic BLE command pre-processing macro */

#ifndef BLE_WRAP_PREPROC

#define BLE_WRAP_PREPROC( )

#endif

/* Generic BLE command post-processing macro */

#ifndef BLE_WRAP_POSTPROC

#define BLE_WRAP_POSTPROC( )

#endif

/* HCI_DISCONNECT pre-processing macro */

#ifndef BLE_WRAP_HCI_DISCONNECT_PREPROC

#define BLE_WRAP_HCI_DISCONNECT_PREPROC BLE_WRAP_PREPROC

#endif

/* HCI_DISCONNECT post-processing macro */

#ifndef BLE_WRAP_HCI_DISCONNECT_POSTPROC

#define BLE_WRAP_HCI_DISCONNECT_POSTPROC BLE_WRAP_POSTPROC

#endif

…

/* HCI_DISCONNECT wrapper function */

tBleStatus hci_disconnect( uint16_t Connection_Handle,

uint8_t Reason )

{

BLE_WRAP_HCI_DISCONNECT_PREPROC( );

tBleStatus status = HCI_DISCONNECT( Connection_Handle,

Reason );

BLE_WRAP_HCI_DISCONNECT_POSTPROC( );

return status;

}

Application example:

/* User can define the specific macros to call their own functions */

/* HCI_DISCONNECT pre-processing macro */

#define BLE_WRAP_HCI_DISCONNECT_PREPROC user_disconnect_preproc()

/* HCI_DISCONNECT post-processing macro */

#define BLE_WRAP_HCI_DISCONNECT_POSTPROC user_disconnect_postproc()

[OR]

/* User can define the generic macros to call their own functions */

#define BLE_WRAP_PREPROC user_preproc()

#define BLE_WRAP_POSTPROC user_postproc()

#### 3.3.2.2 Commands and data sending

Each ACI/HCI command has its own interface, e.g. the HCI Reset command can be called through the “hci_reset” interface.

The HCI commands functions can be found in include/auto/ble_hci_le.h file.

The ACI commands for GAP functions can be found in include/auto/ble_gap_le.h file.

The ACI commands for GATT functions can be found in include/auto/ble_gatt_le.h file.

The ACI commands for L2CAP functions can be found in include/auto/ble_l2cap_le.h file.

The ACI commands for Generic functions can be found in include/auto/ble_gen_aci.h file.

The ACI commands for HAL functions can be found in include/auto/ble_hal_aci.h file.

Also, there is a way to use the ACI/HCI commands without using the BLE Wrapper. Those interfaces have the same name as the one listed before, but in uppercase: e.g. HCI Reset command is “HCI_RESET” instead of “hci_reset”.

Those functions can be found in include/auto/ble_raw_api.h file.

Example:

// Send HCI Reset command

tBleStatus reset_status = hci_reset();

// Send HCI Reset command without using the BLE Wrapper

tBleStatus reset_status = HCI_RESET();

// Send ACI GATT delete include service command

uint16_t Serv_Handle = 0x2456;

uint16_t Include_Handle = 0x8795;

tBleStatus gatt_status = aci_gatt_del_include_service(Serv_Handle, Include_Handle);

#### 3.3.2.3 Asynchronous events and data reception

To handle ACI/HCI events in its application, the user can choose between two different methods:

1- “FIFO event handling”

Handle the ACI/HCI events through the BLE Wrapper callback functions (listed in include/auto/ble_events.h file).
In the “BLECB_Indication” function, it is required to push the event data into a FIFO. Then, it is possible to call the “BLE_EventProcess” function each time an event is popped from the FIFO.
The “BLE_EventProcess” function calls the dedicated event callback. To handle the event, its dedicated callback needs to be redefined (e.g. “hci_disconnection_complete_event” callback)

2- “Raw event handling”

Handle the ACI/HCI event directly when the BLE Stack raises it without using the BLE Wrapper. It requires to redefine the dedicated event callbacks (e.g. “HCI_DISCONNECTION_COMPLETE_EVENT” callback).
If an event is handled in its dedicated callback, the event cannot be handled in the BLECB_Indication callback anymore.
Note: No ACI/HCI command should be called from the Raw event callback.

Based on its own application scenario, the user should identify the required BLE events to be detected and handled and define the application ‘s specific actions as a response to such events.

When implementing a BLE application, the most common and widely used BLE events are the ones related to the discovery, connection, terminate procedures, services and characteristics discovery procedures, attribute modified events on a GATT server and attribute notification/ indication events on a GATT client.3.3.3.

There is one callback per event. All callback functions can be found in include/auto/ble_events.h (for method 1) and include /auto/ble_raw_api.h (for method 2).

Example:

tBleStatus hci_disconnection_complete_event(uint8_t Status,

uint16_t Connection_Handle,

uint8_t Reason)

{

/* USER CODE BEGIN */

// What to do when the device is disconnected.

/* USER CODE END */

}

Known limitation: In “LL only” mode or when using Direct Mode for the event callback, the RAM containing the reported data doesn’t support unaligned access. In these cases, it is advised to use the ble_memcpy/ble_memset/ble_memcmp functions (declared in "mem_intf.h" from link layer libraries) instead of memcpy/memset/memcmp functions when accessing those data.

# 4 BLE stack porting

The BLE stack uses some generic HW features but lets the application define them by using HW drivers or emulating some of them by SW code.

All porting interfaces required by the BLE stack are defined in the bleplat.h

The following features are used and need to be implemented on the application side:

- NVM: Non-Volatile Memory used by the security database of the BLE stack. (required only for variants including the Host Stack)

- Timer: used by several components of the BLE stack. (required only for variants including the Host Stack)

- AES: Advanced Encryption Standard used by the security manager layer of the BLE stack.

- PKA: Public Key Accelerator used by the controller in the BLE stack.

- RNG: Random Number Generation used by the controller in the BLE stack.

## 4.1 BLE platform initialization

Functions | Parameters | Return Value
BLEPLAT_Init | None | None

Table 8: BLEPLAT_Init function

This function is called by the BLE stack when it is initialized or reset (via hci_reset). The user shall call here the functions to reset the Timer, AES, PKA and RNG needed for the BLE stack.

The user must implement the functions mentioned below that are called by the BLE stack at runtime.

## 4.2 BLE platform functions

All the BLEPLAT functions are called from the BLE stack process or commands. Those functions shall return one of the following status values:

Status | Value | Description
BLEPLAT_OK | 0 | The function did the job and returns an OK status
BLEPLAT_FULL | -1 | The function exists because the HW resource is full
BLEPLAT_BUSY | -2 | The function is busy and is not available for the requested operation
BLEPLAT_EOF | -3 | The function exits and notifies the HW resource (memory for example) reached the end.
BLEPLAT_ERROR | -5 | The function exits due to some issues (memory corruption or buffer overflow for example)

Table 9: BLEPLAT functions' returns

Note: BLE platform functions do not have severe timing constraints. In fact, the BLE host stack only deals with timeouts of several seconds.

### 4.2.1 NVM function

The NVM function indicates the portion of NVM cache buffer that needs to be written in NVM.

Functions | Parameters | Return Value
BLEPLAT_NvmStore: Store data in the NVM. Indicates the portion of NVM cache buffer that needs to be written in NVM. | - uint64_t* ptr: Pointer to the data buffer to be stored (it points inside the NVM cache buffer) - uint32_t size: The size of data to be stored (in 64-bit words) | None

Table 10: BLEPLAT NVM functions

### 4.2.2 Timer functions

The timer functions are used by the BLE stack to handle all procedures which are time dependent.

The timer should have an accuracy of 1 ms and it is recommended to be able to count up to 24 hours.

Function | Parameters | Return Value
BLEPLAT_TimerStart: Start the Timer | uint16_t id: The timer ID to be started. uint32_t timeout: The timeout needed to stop the timer (in ms) | int: One of the return values described in the section 4.2
BLEPLAT_TimerStop: Stop the Timer | uint16_t id: The timer ID to be stopped | None
BLEPLATCB_TimerExpiry: The timer callback function called when the timeout of a given timer has elapsed | uint16_t id: The timer ID of the timer that has expired. | None

Table 11: BLEPLAT Timer functions

The number of timers required by the BLE stack depends on the variants used.

Here is the formula to compute the maximum number of timers needed per variants:

- For the Full and Basic Plus, Basic variants: Maximum Number of timers = (6 x numOfLinks) + 5

- For the Peripheral Only variant: Maximum Number of timers = (4 x numOfLinks) + 4

Note: Implementation of the BLEPLAT_Timer API is not necessary for the LL Only variant.

### 4.2.3 AES functions

The AES functions are used by the BLE stack to encrypt a 128-bit single block or to compute CMAC which is needed by BLE security manager.

Function | Parameters | Return Value
BLEPLAT_AesEcbEncrypt: Encrypt a single 128-bit block with a 128-bit key | const uint8_t* key: table of 16 bytes that contains the key to use (Little Endian format) const uint8_t* input: table of 16 bytes that contains the block to encrypt uint8_t* output: table of 16 bytes that is filled by the function with the encrypted block | None

BLEPLAT_AesCcmCrypt:

CCM computation

uint8_t mode: CCM mode (0=encryption, 1=decryption)

const uint8_t* key: table of 16 bytes that contains the AES encryption key (Little Endian format)

uint8_t iv_length: initialization vector length

const uint8_t* iv: table that contains the initialization vector data

uint8_t add_length: Additional Authenticated Data length

const uint8_t* add_data: table that contains the Additional Authenticated Data

uint32_t input_length: input data length

const uint8_t* input: input data (to be encrypted or decrypted)

uint8_t tag_length: CCM tag length

uint8_t* tag: table that contains the CCM tag

uint8_t* output: result data (encrypted or decrypted)

int: One of the return values described in the section 4.2

BLEPLAT_AesCmacSetKey: Set the 128-bit key to be used for CMAC computation | const uint8_t* key: table of 16 bytes that contains the key to use (Little Endian format) | None

BLEPLAT_AesCmacCompute:

CMAC computation: the function can be called several times with output_tag set to 0 to append data to the computation. It must be called once at the end with output_tag not set at 0 to complete the CMAC computation.

const uint8_t* input: table of “input_length” bytes that contains the data to append for the CMAC computation

uint32_t input_length: number of bytes in “input”.

uint8_t* output_tag: must be set to 0 for append. Otherwise: table of 16 bytes that is filled by the function with the computed CMAC tag.

None

Table 12: BLEPLAT AES functions

### 4.2.4 PKA functions

The PKA functions are used by the BLE stack to compute the P-256 public key and the DH key used for BLE secure connections.

Function | Parameters | Return Value
BLEPLAT_PkaStartP256Key: Start P-256 public key generation | const uint32_t* local_private_key: table of 8 x 32-bit words that contains the P-256 private key (Little Endian format) | int: One of the return values described in the section 4.2
BLEPLAT_PkaReadP256Key: Get result of P-256 public key generation | uint32_t* local_public_key: table of 32 x 32-bit words that is filled by the function with the generated P-256 public key (Little Endian format) | int: One of the return values described in the section 4.2
BLEPLAT_PkaStartDhKey: Start DH key computation | const uint32_t* local_private_key: table of 8 x 32-bit words that contains the local P-256 private key (Little Endian format) const uint32_t* remote_public_key: table of 32 x 32-bit words that contains the remote P-256 public key (Little Endian format) | int: One of the return values described in the section 4.2
BLEPLAT_PkaReadDhKey: Get result of DH key computation | uint32_t* dh_key: table of 8 x 32-bit words that is filled by the function with the generated DH key (Little Endian format) | int: One of the return values described in the section 4.2
BLEPLATCB_PkaComplete: Callback function implemented by the BLE stack that must be called by the user to inform the BLE stack about completion of P-256 public key generation or DH key computation | None | int: One of the return values described in the section 4.2

Table 13: BLEPLAT PKA functions

### 4.2.5 RNG functions

This function is called by the BLE stack to retrieve “n” x 32*bit words of random values.

Function | Parameters | Return Value
BLEPLAT_RngGet: Get random values. | uint8_t n: number of 32-bit words to read. uint32_t* val: pointer to a 32-bit table of size ‘n’ that are filled with random values by the function. | None

Table 14: BLEPLAT RNG function

ARM CC compiler and Keil µvision are registered trademarks owned by ARM

IAR C/C++ compiler is a registered trademark owned by IAR Systems

http://dita.st.com/dx/ditaexchange/Repository/Topics/disclaimer_PUBLIC.xml

Please Read Carefully
Information in this document is provided solely in connection with ST products. STMicroelectronics NV and its subsidiaries ("ST") reserve the right to make changes, corrections, modifications or improvements, to this document, and the products and services described herein at any time, without notice.
All ST products are sold pursuant to ST’s terms and conditions of sale.
Purchasers are solely responsible for the choice, selection and use of the ST products and services described herein, and ST assumes no liability whatsoever relating to the choice, selection or use of the ST products and services described herein.

No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted under this document. If any part of this document refers to any third party products or services it shall not be deemed a license grant by ST for the use of such third party products or services, or any intellectual property contained therein or considered as a warranty covering the use in any manner whatsoever of such third party products or services or any intellectual property contained therein.

UNLESS OTHERWISE SET FORTH IN ST’S TERMS AND CONDITIONS OF SALE ST DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY WITH RESPECT TO THE USE AND/OR SALE OF ST PRODUCTS INCLUDING WITHOUT LIMITATION IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE (AND THEIR EQUIVALENTS UNDER THE LAWS OF ANY JURISDICTION), OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.

ST PRODUCTS ARE NOT DESIGNED OR AUTHORIZED FOR USE IN: (A) SAFETY CRITICAL APPLICATIONS SUCH AS LIFE SUPPORTING, ACTIVE IMPLANTED DEVICES OR SYSTEMS WITH PRODUCT FUNCTIONAL SAFETY REQUIREMENTS; (B) AERONAUTIC APPLICATIONS; (C) AUTOMOTIVE APPLICATIONS OR ENVIRONMENTS, AND/OR (D) AEROSPACE APPLICATIONS OR ENVIRONMENTS. WHERE ST PRODUCTS ARE NOT DESIGNED FOR SUCH USE, THE PURCHASER SHALL USE PRODUCTS AT PURCHASER’S SOLE RISK, EVEN IF ST HAS BEEN INFORMED IN WRITING OF SUCH USAGE, UNLESS A PRODUCT IS EXPRESSLY DESIGNATED BY ST AS BEING INTENDED FOR "AUTOMOTIVE, AUTOMOTIVE SAFETY OR MEDICAL" INDUSTRY DOMAINS ACCORDING TO ST PRODUCT DESIGN SPECIFICATIONS. PRODUCTS FORMALLY ESCC, QML OR JAN QUALIFIED ARE DEEMED SUITABLE FOR USE IN AEROSPACE BY THE CORRESPONDING GOVERNMENTAL AGENCY.

Resale of ST products with provisions different from the statements and/or technical features set forth in this document shall immediately void any warranty granted by ST for the ST product or service described herein and shall not create or extend in any manner whatsoever, any liability of ST.
ST and the ST logo are trademarks or registered trademarks of ST in various countries.
Information in this document supersedes and replaces all information previously supplied.
The ST logo is a registered trademark of STMicroelectronics. All other names are the property of their respective owners.
© 2025 STMicroelectronics - All rights reserved
STMicroelectronics group of companies
Australia - Belgium - Brazil - Canada - China - Czech Republic - Finland - France - Germany - Hong Kong - India - Israel - Italy - Japan - Malaysia - Malta - Morocco - Philippines - Singapore - Spain - Sweden - Switzerland - United Kingdom - United States of America
www.st.com