diff --git a/security/encrypted_advertisement/README.md b/advertising/encrypted_advertisement/README.md
similarity index 100%
rename from security/encrypted_advertisement/README.md
rename to advertising/encrypted_advertisement/README.md
diff --git a/security/encrypted_advertisement/SimplicityStudio/readme.md b/advertising/encrypted_advertisement/SimplicityStudio/readme.md
similarity index 100%
rename from security/encrypted_advertisement/SimplicityStudio/readme.md
rename to advertising/encrypted_advertisement/SimplicityStudio/readme.md
diff --git a/security/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_advertiser.slcp b/advertising/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_advertiser.slcp
similarity index 100%
rename from security/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_advertiser.slcp
rename to advertising/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_advertiser.slcp
diff --git a/security/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_scanner.slcp b/advertising/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_scanner.slcp
similarity index 100%
rename from security/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_scanner.slcp
rename to advertising/encrypted_advertisement/SimplicityStudio/soc_encrypted_advertisement_scanner.slcp
diff --git a/security/encrypted_advertisement/config/advertiser/gatt_configuration.btconf b/advertising/encrypted_advertisement/config/advertiser/gatt_configuration.btconf
similarity index 100%
rename from security/encrypted_advertisement/config/advertiser/gatt_configuration.btconf
rename to advertising/encrypted_advertisement/config/advertiser/gatt_configuration.btconf
diff --git a/security/encrypted_advertisement/config/scanner/gatt_configuration.btconf b/advertising/encrypted_advertisement/config/scanner/gatt_configuration.btconf
similarity index 100%
rename from security/encrypted_advertisement/config/scanner/gatt_configuration.btconf
rename to advertising/encrypted_advertisement/config/scanner/gatt_configuration.btconf
diff --git a/security/encrypted_advertisement/images/add_log_1.png b/advertising/encrypted_advertisement/images/add_log_1.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_log_1.png
rename to advertising/encrypted_advertisement/images/add_log_1.png
diff --git a/security/encrypted_advertisement/images/add_log_2.png b/advertising/encrypted_advertisement/images/add_log_2.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_log_2.png
rename to advertising/encrypted_advertisement/images/add_log_2.png
diff --git a/security/encrypted_advertisement/images/add_log_3.png b/advertising/encrypted_advertisement/images/add_log_3.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_log_3.png
rename to advertising/encrypted_advertisement/images/add_log_3.png
diff --git a/security/encrypted_advertisement/images/add_log_4.png b/advertising/encrypted_advertisement/images/add_log_4.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_log_4.png
rename to advertising/encrypted_advertisement/images/add_log_4.png
diff --git a/security/encrypted_advertisement/images/add_log_5.png b/advertising/encrypted_advertisement/images/add_log_5.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_log_5.png
rename to advertising/encrypted_advertisement/images/add_log_5.png
diff --git a/security/encrypted_advertisement/images/add_simple_button_1.png b/advertising/encrypted_advertisement/images/add_simple_button_1.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_simple_button_1.png
rename to advertising/encrypted_advertisement/images/add_simple_button_1.png
diff --git a/security/encrypted_advertisement/images/add_simple_button_2.png b/advertising/encrypted_advertisement/images/add_simple_button_2.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_simple_button_2.png
rename to advertising/encrypted_advertisement/images/add_simple_button_2.png
diff --git a/security/encrypted_advertisement/images/add_simple_button_3.png b/advertising/encrypted_advertisement/images/add_simple_button_3.png
similarity index 100%
rename from security/encrypted_advertisement/images/add_simple_button_3.png
rename to advertising/encrypted_advertisement/images/add_simple_button_3.png
diff --git a/security/encrypted_advertisement/images/btconf.png b/advertising/encrypted_advertisement/images/btconf.png
similarity index 100%
rename from security/encrypted_advertisement/images/btconf.png
rename to advertising/encrypted_advertisement/images/btconf.png
diff --git a/security/encrypted_advertisement/images/encrypted_advertisement.png b/advertising/encrypted_advertisement/images/encrypted_advertisement.png
similarity index 100%
rename from security/encrypted_advertisement/images/encrypted_advertisement.png
rename to advertising/encrypted_advertisement/images/encrypted_advertisement.png
diff --git a/security/encrypted_advertisement/images/extended_scanner.png b/advertising/encrypted_advertisement/images/extended_scanner.png
similarity index 100%
rename from security/encrypted_advertisement/images/extended_scanner.png
rename to advertising/encrypted_advertisement/images/extended_scanner.png
diff --git a/security/encrypted_advertisement/images/result.png b/advertising/encrypted_advertisement/images/result.png
similarity index 100%
rename from security/encrypted_advertisement/images/result.png
rename to advertising/encrypted_advertisement/images/result.png
diff --git a/security/encrypted_advertisement/inc/advertiser/app.h b/advertising/encrypted_advertisement/inc/advertiser/app.h
similarity index 100%
rename from security/encrypted_advertisement/inc/advertiser/app.h
rename to advertising/encrypted_advertisement/inc/advertiser/app.h
diff --git a/security/encrypted_advertisement/inc/scanner/app.h b/advertising/encrypted_advertisement/inc/scanner/app.h
similarity index 100%
rename from security/encrypted_advertisement/inc/scanner/app.h
rename to advertising/encrypted_advertisement/inc/scanner/app.h
diff --git a/security/encrypted_advertisement/src/advertiser/app.c b/advertising/encrypted_advertisement/src/advertiser/app.c
similarity index 100%
rename from security/encrypted_advertisement/src/advertiser/app.c
rename to advertising/encrypted_advertisement/src/advertiser/app.c
diff --git a/security/encrypted_advertisement/src/advertiser/app_bm.c b/advertising/encrypted_advertisement/src/advertiser/app_bm.c
similarity index 100%
rename from security/encrypted_advertisement/src/advertiser/app_bm.c
rename to advertising/encrypted_advertisement/src/advertiser/app_bm.c
diff --git a/security/encrypted_advertisement/src/advertiser/main.c b/advertising/encrypted_advertisement/src/advertiser/main.c
similarity index 100%
rename from security/encrypted_advertisement/src/advertiser/main.c
rename to advertising/encrypted_advertisement/src/advertiser/main.c
diff --git a/security/encrypted_advertisement/src/scanner/app.c b/advertising/encrypted_advertisement/src/scanner/app.c
similarity index 100%
rename from security/encrypted_advertisement/src/scanner/app.c
rename to advertising/encrypted_advertisement/src/scanner/app.c
diff --git a/security/encrypted_advertisement/src/scanner/app_bm.c b/advertising/encrypted_advertisement/src/scanner/app_bm.c
similarity index 100%
rename from security/encrypted_advertisement/src/scanner/app_bm.c
rename to advertising/encrypted_advertisement/src/scanner/app_bm.c
diff --git a/security/encrypted_advertisement/src/scanner/main.c b/advertising/encrypted_advertisement/src/scanner/main.c
similarity index 100%
rename from security/encrypted_advertisement/src/scanner/main.c
rename to advertising/encrypted_advertisement/src/scanner/main.c
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/README.md b/advertising/periodic_advertisement_with_responses/encrypted_pawr/README.md
new file mode 100644
index 0000000..480f332
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/README.md
@@ -0,0 +1,248 @@
+# Encrypted Periodic Advertising with Responses and PAST Example
+
+## Description
+
+This example demonstrates secure application-data exchange between one access point and multiple tags using Bluetooth LE Periodic Advertising with Responses (PAwR) Encrypted Advertising Data (EAD), and Periodic Advertising Synchronization Transfer (PAST).
+
+The example consists of two projects:
+
+- **Access point:** provisions tags, operates the PAwR advertiser, encrypts subevent data, and decrypts tag responses.
+- **Tag:** advertises for provisioning, receives PAwR synchronization through PAST, decrypts its assigned subevent, and sends an encrypted response.
+
+A temporary Bluetooth connection is used to provision each tag. After provisioning, the regular data exchange is connectionless and uses PAwR subevents and response slots.
+
+### Access point
+
+At boot, the access point initializes its EAD session, begins scanning for tags, and starts its PAwR train. It uses passive scanning on the 1M PHY and identifies tags by the custom **Secure Tag** service UUID included in their extended advertisements.
+
+In this demonstration, a tag ID selects both the subevent to which the tag subscribes and the response slot in which it transmits. This one-to-one mapping is an application choice and can be changed as needed.
+
+The following APIs perform the main access-point operations.
+
+1. Configure and start scanning for tags:
+
+```c
+sl_bt_scanner_set_parameters(sl_bt_scanner_scan_mode_passive,
+ 200,
+ 200);
+
+sl_bt_scanner_start(sl_bt_scanner_scan_phy_1m,
+ sl_bt_scanner_discover_observation);
+```
+
+2. Create an advertising set and start the PAwR advertiser:
+
+```c
+sl_bt_advertiser_create_set(&pawr_advertising_set_handle);
+
+sl_bt_pawr_advertiser_start(pawr_advertising_set_handle,
+ PERIODIC_ADV_INTERVAL,
+ PERIODIC_ADV_INTERVAL,
+ 0,
+ SUBEVENT_NUMBER,
+ SUBEVENT_INTERVAL,
+ RESPONSE_SLOT_DELAY,
+ RESPONSE_SLOT_SPACING,
+ RESPONSE_SLOT_NUMBER_PER_SUBVENT);
+```
+
+3. Connect to a discovered tag and provision it through GATT:
+
+```c
+sl_bt_connection_open(report->address,
+ report->address_type,
+ sl_bt_gap_phy_1m,
+ &connection_handle);
+
+sl_bt_gatt_discover_primary_services_by_uuid(...);
+sl_bt_gatt_discover_characteristics_by_uuid(...);
+sl_bt_gatt_write_characteristic_value(...);
+```
+
+4. Transfer the PAwR synchronization information to the tag using PAST:
+
+```c
+sl_bt_advertiser_past_transfer(connection_handle,
+ 0,
+ pawr_advertising_set_handle);
+```
+
+5. Encrypt and provide data for each requested PAwR subevent:
+
+```c
+sl_bt_ead_randomizer_update(&nonce);
+sl_bt_ead_encrypt(...);
+sl_bt_ead_pack_ad_data(...);
+
+sl_bt_pawr_advertiser_set_subevent_data(req.advertising_set,
+ subevent_index,
+ 0,
+ RESPONSE_SLOT_NUMBER_PER_SUBVENT,
+ advertisement_len,
+ advertisement_buffer);
+```
+
+When a response report is received, the access point uses the response slot to locate the associated tag record and tag-specific key. It unpacks and decrypts the response using `sl_bt_ead_unpack_ad_data()` and `sl_bt_ead_decrypt()`.
+
+The access point periodically checks its tag records. A tag without a successfully decrypted response for 30 seconds is marked stale, allowing its ID and response key slot to be reused.
+
+### Tag
+
+At boot, the tag configures itself to synchronize when PAST information is received. It then starts connectable extended advertising. The tag's GATT database advertises the custom [Secure Tag service](config/gatt_configuration.btconf#L51), which contains:
+
+- **Tag ID:** the identifier assigned by the access point.
+- **AP Sync Key Material:** the EAD session key and initialization vector used to decrypt access-point subevent data.
+- **Tag Response Key Material:** the tag-specific EAD session key and initialization vector used to encrypt responses.
+
+The following APIs perform the main tag operations.
+
+1. Configure automatic synchronization from received PAST information:
+
+```c
+sl_bt_past_receiver_set_default_sync_receive_parameters(
+ sl_bt_past_receiver_mode_synchronize,
+ PERIODIC_SYNC_SKIP,
+ PERIODIC_SYNC_TIMEOUT,
+ sl_bt_sync_report_all);
+```
+
+2. Start connectable extended advertising for discovery and provisioning:
+
+```c
+sl_bt_advertiser_create_set(&advertising_set_handle);
+sl_bt_extended_advertiser_generate_data(
+ advertising_set_handle,
+ sl_bt_advertiser_general_discoverable);
+
+sl_bt_extended_advertiser_start(
+ advertising_set_handle,
+ sl_bt_extended_advertiser_connectable,
+ 0);
+```
+
+3. After receiving the PAST transfer, subscribe to the subevent assigned by the tag ID:
+
+```c
+sl_bt_pawr_sync_set_sync_subevents(
+ pawr_handle,
+ sizeof(subevents_subscription_list),
+ subevents_subscription_list);
+```
+
+4. Decrypt the received subevent data and prepare an encrypted response:
+
+```c
+sl_bt_ead_unpack_ad_data(...);
+sl_bt_ead_decrypt(...);
+sl_bt_ead_randomizer_update(&tag_resp_nonce);
+sl_bt_ead_encrypt(...);
+sl_bt_ead_pack_ad_data(...);
+```
+
+5. Send the response in the slot assigned to the tag:
+
+```c
+sl_bt_pawr_sync_set_response_data(pawr_handle,
+ sync_report->event_counter,
+ sync_report->subevent,
+ sync_report->subevent,
+ tag_id,
+ secret_data_len,
+ response_buffer);
+```
+
+If the tag loses PAwR synchronization while it is disconnected, a periodic timer causes it to resume connectable advertising so that the access point can provision it again.
+
+### Provisioning and synchronization sequence
+
+1. The access point starts the PAwR train and scans for the Secure Tag service.
+2. The tag starts connectable extended advertising.
+3. The access point discovers the tag and opens a Bluetooth connection.
+4. The access point discovers the Secure Tag service and its three characteristics.
+5. The devices establish a bonded, encrypted LE Secure Connections link.
+6. The access point assigns a tag ID.
+7. The access point writes the shared AP synchronization key material.
+8. The access point creates and writes unique response key material for the tag.
+9. The access point transfers the PAwR synchronization information using PAST.
+10. The access point records the tag as active and closes the connection.
+11. The tag subscribes to the subevent corresponding to its assigned ID.
+12. The devices continue exchanging encrypted data without a Bluetooth connection.
+
+## Simplicity SDK version
+
+- Simplicity SDK v2025.12.1
+
+## Hardware required
+
+- Two or more Wireless Starter Kit mainboards
+- One Bluetooth-capable Series 2 radio board for the access point
+- One Bluetooth-capable Series 2 radio board for each tag
+
+At least two devices are required: one access point and one tag.
+
+## Setting up
+
+> **Note:** The provided projects already contain the required source files, software components, and configuration. The following steps are useful if you you are starting from the basic bluetooth empty
+
+### Access point
+
+1. Open Simplicity Studio v6 with Simplicity SDK v2025.12.1 or a compatible version.
+2. generate a bluetooth empty project.
+3. Verify that the following important software components are installed:
+ - Extended Advertising
+ - Scanner for extended advertisements
+ - Periodic Advertising using PAwR trains
+ - Transfer periodic synchronization information for a local advertising set
+ - GATT Client
+ - Security Manager
+ - Encrypted Advertising Data Core
+ - Log
+4. Verify that [app.c](src/access_point/app.c), [main.c](src/access_point/main.c), and [app.h](inc/access_point/app.h) are included in the generated project.
+5. Build and flash the project to the access-point device.
+6. Open the serial console for the device. (make sure that you enable VCOM in the board control component)
+
+### Tag
+
+1. Open Simplicity Studio v6 with Simplicity SDK v2025.12.1 or a compatible version.
+2. Verify that the following important software components are installed:
+ - Extended Advertising
+ - PAST Receiver
+ - Synchronization to Periodic Advertising with Responses trains
+ - GATT Server
+ - Security Manager
+ - Encrypted Advertising Data Core
+ - Log
+3. Insert [gatt_configuration.btconf](config/gatt_configuration.btconf) is the config/btconf directory
+5. Verify that [app.c](src/tag/app.c), [main.c](src/tag/main.c), and [app.h](inc/tag/app.h) are included in the generated project.
+6. Build and flash the project to the tag device.
+7. Open the serial console for the device.(make sure that you enable VCOM in the board control component)
+
+## Usage
+
+1. Reset the access point. It prints its Bluetooth address, starts scanning for tags, and starts the PAwR train.
+2. Reset a tag. It advertises the Secure Tag service.
+3. The access point connects to the tag, assigns an ID, provisions the EAD keys, and transfers PAwR synchronization.
+4. After the connection closes, the tag reports the received PAwR timing and synchronization state.
+5. Observe the tag decrypting access-point messages and the access point decrypting tag responses.
+6. Reset additional tags one at a time to provision multiple devices.
+
+## Results
+
+Below is the tag log, it shows:
+- A boot sequence that starts advertising
+- A connection with increased security
+- Reception of an ID (also keys that are not logged here)
+- Reception of the PAWR train and connection close
+- The subevent subscribed and the payload
+- The response and its payload
+
+
+
+Below is the access point log, it shows:
+- A boot sequence that starts scanning for tags
+- The stack requests to the application for the subevents data of the PAWR train
+- A connection event with increased security
+- GATT operation to write a tag ID, AP sync key and tag response key
+- The response from the tag to subevent 0 in response slot 0
+
+
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/readme.md b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/readme.md
new file mode 100644
index 0000000..0e1c633
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/readme.md
@@ -0,0 +1,8 @@
+# encrypted pawr Example
+
+The readme file of this project can be found [here](https://github.com/SiliconLabs/bluetooth_stack_features/blob/master/advertising/periodic_advertisement_with_responses/encrypted_pawr/README.md).
+
+.
+> Note: In this project all the necessary software components are installed, source files are copied, and configurations are set, hence you can disregard the Setting Up section of the online readme file. Nevertheless, if you want to add the demonstrated feature to your own project, it might be good to know what software components you must install, and what configurations you must set beforehand, hence reading through the Setting Up section might be useful.
+
+> Note: This project requires a bootloader. For Series 1 (EFR32xG1x) devices please flash a **Bluetooth In-place OTA DFU** bootloader or an **Internal Storage** bootloader to your device to get this application to work. For Series 2 (EFR32xG2x) devices please flash a **Bluetooth Apploader OTA DFU** bootloader to your device
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_access_point.slcp b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_access_point.slcp
new file mode 100644
index 0000000..f2ca6bc
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_access_point.slcp
@@ -0,0 +1,62 @@
+project_name: soc_encrypted_pawr_access_point
+package: Bluetooth
+label: Bluetooth - SoC Encrypted PAwR Access Point
+description: >
+ Provisions PAwR tags, transfers synchronization with PAST, and exchanges encrypted advertising data.
+category: Bluetooth Examples
+quality: development
+
+component:
+ - id: device_init
+ - id: clock_manager
+ - id: bluetooth_stack
+ - id: gatt_configuration
+ - id: bluetooth_feature_legacy_advertiser
+ - id: bluetooth_feature_extended_advertiser
+ - id: bluetooth_feature_legacy_scanner
+ - id: bluetooth_feature_extended_scanner
+ - id: bluetooth_feature_connection_role_central
+ - id: bluetooth_feature_connection_role_peripheral
+ - id: bluetooth_feature_gatt
+ - id: bluetooth_feature_gatt_server
+ - id: bluetooth_feature_sm
+ - id: bluetooth_feature_system
+ - id: bluetooth_feature_pawr_advertiser
+ - id: bluetooth_feature_advertiser_past
+ - id: ead_core
+ - id: app_assert
+ - id: app_log
+ - id: app_os_helper
+ - id: component_catalog
+ - id: gatt_service_device_information_override
+ - id: mpu
+ - id: rail_util_pti
+ - id: sl_main
+
+source:
+ - path: ../src/access_point/app.c
+ - path: ../src/access_point/main.c
+
+include:
+ - path: ../inc/access_point/
+ file_list:
+ - path: app.h
+
+readme:
+ - path: ../README.md
+
+configuration:
+ - name: SL_STACK_SIZE
+ value: "2752"
+ - condition:
+ - psa_crypto
+ name: SL_PSA_KEY_USER_SLOT_COUNT
+ value: "0"
+
+tag:
+ - hardware:rf:band:2400
+
+ui_hints:
+ highlight:
+ - path: ../README.md
+ focus: true
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_tag.slcp b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_tag.slcp
new file mode 100644
index 0000000..18a1a22
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/SimplicityStudio/soc_encrypted_pawr_tag.slcp
@@ -0,0 +1,68 @@
+project_name: soc_encrypted_pawr_tag
+package: Bluetooth
+label: Bluetooth - SoC Encrypted PAwR Tag
+description: >
+ Receives PAwR synchronization with PAST and exchanges encrypted advertising data with an access point.
+category: Bluetooth Examples
+quality: development
+
+component:
+ - id: device_init
+ - id: clock_manager
+ - id: bluetooth_stack
+ - id: gatt_configuration
+ - id: bluetooth_feature_legacy_advertiser
+ - id: bluetooth_feature_extended_advertiser
+ - id: bluetooth_feature_legacy_scanner
+ - id: bluetooth_feature_connection_role_central
+ - id: bluetooth_feature_connection_role_peripheral
+ - id: bluetooth_feature_gatt
+ - id: bluetooth_feature_gatt_server
+ - id: bluetooth_feature_sm
+ - id: bluetooth_feature_system
+ - id: bluetooth_feature_past_receiver
+ - id: bluetooth_feature_pawr_sync
+ - id: ead_core
+ - id: app_assert
+ - id: app_log
+ - id: app_os_helper
+ - id: component_catalog
+ - id: gatt_service_device_information_override
+ - id: mpu
+ - id: rail_util_pti
+ - id: sl_main
+
+source:
+ - path: ../src/tag/app.c
+ - path: ../src/tag/main.c
+
+include:
+ - path: ../inc/tag/
+ file_list:
+ - path: app.h
+
+readme:
+ - path: ../README.md
+
+config_file:
+ - override:
+ component: gatt_configuration
+ file_id: gatt_configuration_file_id
+ path: ../config/gatt_configuration.btconf
+ directory: btconf
+
+configuration:
+ - name: SL_STACK_SIZE
+ value: "2752"
+ - condition:
+ - psa_crypto
+ name: SL_PSA_KEY_USER_SLOT_COUNT
+ value: "0"
+
+tag:
+ - hardware:rf:band:2400
+
+ui_hints:
+ highlight:
+ - path: ../README.md
+ focus: true
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/config/gatt_configuration.btconf b/advertising/periodic_advertisement_with_responses/encrypted_pawr/config/gatt_configuration.btconf
new file mode 100644
index 0000000..a47910b
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/config/gatt_configuration.btconf
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ Abstract: The generic_access service contains generic information about the device. All available Characteristics are readonly.
+
+
+
+ tag
+
+
+
+
+
+
+
+
+ Abstract: The external appearance of this device. The values are composed of a category (10-bits) and sub-categories (6-bits).
+ 0000
+
+
+
+
+
+
+
+
+ Abstract: The Device Information Service exposes manufacturer and/or vendor information about a device. Summary: This service exposes manufacturer information about a device. The Device Information Service is instantiated as a Primary Service. Only one instance of the Device Information Service is exposed on a device.
+
+
+
+ Abstract: The value of this characteristic is a UTF-8 string representing the name of the manufacturer of the device.
+ Silicon Labs
+
+
+
+
+
+
+
+ Abstract: The SYSTEM ID characteristic consists of a structure with two fields. The first field are the LSOs and the second field contains the MSOs. This is a 64-bit structure which consists of a 40-bit manufacturer-defined identifier concatenated with a 24 bit unique Organizationally Unique Identifier (OUI). The OUI is issued by the IEEE Registration Authority (http://standards.ieee.org/regauth/index.html) and is required to be used in accordance with IEEE Standard 802-2001.6 while the least significant 40 bits are manufacturer defined. If System ID generated based on a Bluetooth Device Address, it is required to be done as follows. System ID and the Bluetooth Device Address have a very similar structure: a Bluetooth Device Address is 48 bits in length and consists of a 24 bit Company Assigned Identifier (manufacturer defined identifier) concatenated with a 24 bit Company Identifier (OUI). In order to encapsulate a Bluetooth Device Address as System ID, the Company Identifier is concatenated with 0xFFFE followed by the Company Assigned Identifier of the Bluetooth Address. For more guidelines related to EUI-64, refer to http://standards.ieee.org/develop/regauth/tut/eui64.pdf. Examples: If the system ID is based of a Bluetooth Device Address with a Company Identifier (OUI) is 0x123456 and the Company Assigned Identifier is 0x9ABCDE, then the System Identifier is required to be 0x123456FFFE9ABCDE.
+
+
+
+
+
+
+
+
+
+
+
+
+ FF
+
+
+
+
+
+
+
+
+ 00
+
+
+
+
+
+
+
+
+ 00
+
+
+
+
+
+
+
+
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/ap_log.png b/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/ap_log.png
new file mode 100644
index 0000000..140bf43
Binary files /dev/null and b/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/ap_log.png differ
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/tag_log.png b/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/tag_log.png
new file mode 100644
index 0000000..3abbf5d
Binary files /dev/null and b/advertising/periodic_advertisement_with_responses/encrypted_pawr/images/tag_log.png differ
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/access_point/app.h b/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/access_point/app.h
new file mode 100644
index 0000000..be6ee23
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/access_point/app.h
@@ -0,0 +1,79 @@
+/***************************************************************************//**
+ * @file
+ * @brief Application interface.
+ *******************************************************************************
+ * # License
+ * Copyright 2025 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+#include
+
+/**************************************************************************//**
+ * Proceed with execution. (Indicate that it is required to run the application
+ * process action.)
+ *****************************************************************************/
+void app_proceed(void);
+
+/**************************************************************************//**
+ * Check if it is required to process with execution.
+ * @return true if required, false otherwise.
+ *****************************************************************************/
+bool app_is_process_required(void);
+
+/**************************************************************************//**
+ * Acquire access to protected variables.
+ *
+ * Acquire the guard to operate on the internal state variables.
+ * Guard is implemented using mutexing (RTOS).
+ *
+ * @note Must not be used from ISR context.
+ *
+ * @return true if operation was successful.
+ *****************************************************************************/
+bool app_mutex_acquire(void);
+
+/**************************************************************************//**
+ * Finish access to protected variables.
+ *
+ * Release the guard to stop working on the internal state variables.
+ * Guard is implemented using mutexing (RTOS).
+ *
+ * @note Must not be used from ISR context.
+ *****************************************************************************/
+void app_mutex_release(void);
+
+/**************************************************************************//**
+ * Initialize the application.
+ *
+ * This function initializes the application components.
+ *
+ * @note Must not be used from ISR context.
+ *****************************************************************************/
+void app_init_bt(void);
+
+#endif // APP_H
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/tag/app.h b/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/tag/app.h
new file mode 100644
index 0000000..be6ee23
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/inc/tag/app.h
@@ -0,0 +1,79 @@
+/***************************************************************************//**
+ * @file
+ * @brief Application interface.
+ *******************************************************************************
+ * # License
+ * Copyright 2025 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+
+#ifndef APP_H
+#define APP_H
+
+#include
+
+/**************************************************************************//**
+ * Proceed with execution. (Indicate that it is required to run the application
+ * process action.)
+ *****************************************************************************/
+void app_proceed(void);
+
+/**************************************************************************//**
+ * Check if it is required to process with execution.
+ * @return true if required, false otherwise.
+ *****************************************************************************/
+bool app_is_process_required(void);
+
+/**************************************************************************//**
+ * Acquire access to protected variables.
+ *
+ * Acquire the guard to operate on the internal state variables.
+ * Guard is implemented using mutexing (RTOS).
+ *
+ * @note Must not be used from ISR context.
+ *
+ * @return true if operation was successful.
+ *****************************************************************************/
+bool app_mutex_acquire(void);
+
+/**************************************************************************//**
+ * Finish access to protected variables.
+ *
+ * Release the guard to stop working on the internal state variables.
+ * Guard is implemented using mutexing (RTOS).
+ *
+ * @note Must not be used from ISR context.
+ *****************************************************************************/
+void app_mutex_release(void);
+
+/**************************************************************************//**
+ * Initialize the application.
+ *
+ * This function initializes the application components.
+ *
+ * @note Must not be used from ISR context.
+ *****************************************************************************/
+void app_init_bt(void);
+
+#endif // APP_H
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/app.c b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/app.c
new file mode 100644
index 0000000..9833fdc
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/app.c
@@ -0,0 +1,1018 @@
+/***************************************************************************//**
+ * @file
+ * @brief Core application logic.
+ *******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#include
+#include
+
+#include "app_assert.h"
+#include "app.h"
+#include "app_log.h"
+#include "psa/crypto.h"
+#include "psa/crypto_values.h"
+#include "sl_bluetooth_connection_config.h"
+#include "sl_bt_api.h"
+#include "sl_bt_ead_core.h"
+#include "sl_main_init.h"
+#include "sl_sleeptimer.h"
+#include "nvm3.h"
+#include "nvm3_default.h"
+
+// -----------------------------------------------------------------------------
+// Configuration
+// -----------------------------------------------------------------------------
+#define KEY_MATERIAL_SIZE (SL_BT_EAD_SESSION_KEY_SIZE + SL_BT_EAD_IV_SIZE)
+#define AP_SYNC_KEY_MATERIAL_ID 0x0001
+// user defined NVM3 objects should be placed below 0x10000.
+#define AP_SYNC_KEY_IV_NVM3_KEY 0x00000
+
+#define PERIODIC_ADV_INTERVAL 2400
+#define SUBEVENT_NUMBER 3
+#define SUBEVENT_INTERVAL 255
+#define RESPONSE_SLOT_DELAY 40
+#define RESPONSE_SLOT_SPACING 80
+#define RESPONSE_SLOT_NUMBER_PER_SUBVENT SUBEVENT_NUMBER
+
+#define TAG_STALE_TIMEOUT_MS 30000u
+#define TAG_STALE_SCAN_PERIOD_MS 5000u
+#define TAG_SWEEP_SIGNAL 0x01
+#define TAG_ID_UNASSIGNED 0xFF
+#define MAX_TAGS SUBEVENT_NUMBER
+#define BLE_EA_ADV_DATA_LEN 0xBF
+
+// -----------------------------------------------------------------------------
+// Types
+// -----------------------------------------------------------------------------
+typedef enum tag_record_state_t {
+ TAG_RECORD_FREE = 0,
+ TAG_RECORD_PROVISIONING,
+ TAG_RECORD_ACTIVE,
+ TAG_RECORD_STALE
+} tag_record_state_t;
+
+typedef struct tag_record_t {
+ tag_record_state_t state;
+
+ uint8_t tag_id;
+ uint8_t response_subevent;
+ uint8_t response_slot;
+
+ uint64_t last_seen_tick;
+ bd_addr address;
+ uint8_t address_type;
+ uint8_t bonding;
+ struct sl_bt_ead_key_material_s response_key_material;
+ struct sl_bt_ead_nonce_s response_nonce;
+} tag_record_t;
+
+typedef enum gatt_sequence_state_t {
+ GATT_IDLE = 0,
+ GATT_DISCOVER_SERVICE,
+ GATT_DISCOVER_TAG_ID,
+ GATT_READ_TAG_ID,
+ GATT_WRITE_TAG_ID,
+
+ GATT_DISCOVER_AP_SYNC_KEY,
+ GATT_WRITE_AP_SYNC_KEY,
+
+ GATT_DISCOVER_TAG_RESP_KEY,
+ GATT_WRITE_TAG_RESP_KEY,
+
+ GATT_FAILED,
+ GATT_DONE
+} gatt_sequence_state_t;
+
+// -----------------------------------------------------------------------------
+// Static data
+// -----------------------------------------------------------------------------
+static sl_sleeptimer_timer_handle_t tag_sweep_timer;
+static uint64_t tag_stale_timeout_ticks;
+
+static uint8_t pawr_advertising_set_handle = 0xff;
+static uint8_t advertisement_buffer[BLE_EA_ADV_DATA_LEN];
+static char name[] = "Encrypted Advertiser";
+static char secret_data[10];
+static uint8_t secret_number = 0;
+
+static tag_record_t tags[MAX_TAGS] = { 0 };
+
+static const uint8_t SecureTagServiceUUID[] = {
+ 0x81, 0xC2, 0x00, 0x2D,
+ 0x31, 0xF4, 0xB0, 0xBF,
+ 0x2B, 0x42, 0x49, 0x68,
+ 0xC7, 0x25, 0x71, 0x41
+};
+
+static const uint8_t TagIDCharUUID[16] = {
+ 0x91, 0xD4, 0x1E, 0x54,
+ 0x4B, 0xE1, 0xAC, 0x9B,
+ 0x08, 0x46, 0xEC, 0x60,
+ 0x26, 0x53, 0x2A, 0xC6
+};
+
+static const uint8_t APSyncKeyMaterialUUID[16] = {
+ 0xCC, 0x44, 0x0B, 0x61,
+ 0xB3, 0x00, 0xD4, 0xB9,
+ 0x3B, 0x40, 0x33, 0x6E,
+ 0x31, 0xF0, 0x51, 0x2A
+};
+
+static const uint8_t TagResponseKeyMaterialUUID[16] = {
+ 0x8C, 0xED, 0xC7, 0x06,
+ 0x34, 0xA9, 0xDD, 0xB8,
+ 0x9E, 0x46, 0x57, 0xE3,
+ 0xCC, 0x4B, 0xAB, 0x8D
+};
+
+static uint32_t SecureTagServiceHandle = 0;
+static uint16_t TagIDCharHandle = 0;
+static uint16_t APSyncKeyMaterialCharHandle = 0;
+static uint16_t TagResponseKeyMaterialCharHandle = 0;
+
+static struct sl_bt_ead_key_material_s Ap_sync_key_material = { 0 };
+static psa_key_id_t ead_ap_sync_key_id = AP_SYNC_KEY_MATERIAL_ID;
+
+#define TAG_RESP_KEY_ID_BASE 0x0002
+// -----------------------------------------------------------------------------
+// Forward declarations
+// -----------------------------------------------------------------------------
+static sl_status_t find_tag(sl_bt_evt_scanner_extended_advertisement_report_t *report);
+static sl_status_t construct_advertisement_payload(sl_bt_ead_key_material_p key_material,
+ sl_bt_ead_nonce_p nonce,
+ uint8_t *index);
+static sl_status_t initialize_key(sl_bt_ead_key_material_p key_material);
+static sl_status_t decrypt_tag_response(sl_bt_evt_pawr_advertiser_response_report_t *report,
+ tag_record_t *tag);
+static sl_status_t resolve_tag_id(uint8_t claimed_id,
+ bd_addr address,
+ uint8_t address_type,
+ uint8_t *resolved_id);
+static void stale_timer_cb(sl_sleeptimer_timer_handle_t *handle, void *data);
+static void sweep_stale_tags(void);
+static void export_ead_key_value(psa_key_id_t key_id, struct sl_bt_ead_key_material_s key_material, uint8_t key_material_value[KEY_MATERIAL_SIZE]);
+
+// -----------------------------------------------------------------------------
+// Application entry points
+// -----------------------------------------------------------------------------
+void app_init(void)
+{
+ sl_status_t sc;
+ psa_status_t psa_sc;
+ Ecode_t nvm3_sc;
+ uint32_t stale_scan_period_ticks;
+ uint32_t timeout_ticks;
+ psa_key_handle_t ead_ap_sync_key_handle;
+
+ app_log_info(" ++++++++++++++++++++++++++++++++++++ Ap boot ++++++++++++++++++++++++++++++++++++\r\n");
+
+ sc = sl_sleeptimer_init();
+ app_assert_status(sc);
+
+ sc = sl_sleeptimer_ms32_to_tick(TAG_STALE_SCAN_PERIOD_MS,
+ &stale_scan_period_ticks);
+ app_assert_status(sc);
+
+ sc = sl_sleeptimer_ms32_to_tick(TAG_STALE_TIMEOUT_MS, &timeout_ticks);
+ app_assert_status(sc);
+ tag_stale_timeout_ticks = timeout_ticks;
+
+ sc = sl_sleeptimer_start_periodic_timer(&tag_sweep_timer,
+ stale_scan_period_ticks,
+ stale_timer_cb,
+ NULL,
+ 0,
+ 0);
+ app_assert_status(sc);
+
+ psa_sc = psa_crypto_init();
+ app_assert_status(psa_sc);
+ psa_sc = psa_open_key(ead_ap_sync_key_id,
+ &ead_ap_sync_key_handle);
+ // check if AP sync key exists otherwise create key;
+ if (psa_sc == PSA_SUCCESS) {
+ app_log_info("Existing AP sync PSA key found\r\n");
+ psa_sc = psa_close_key(ead_ap_sync_key_handle);
+ app_assert_status(psa_sc);
+ Ap_sync_key_material.key_id = ead_ap_sync_key_id;
+ nvm3_sc = nvm3_readData(nvm3_defaultHandle,
+ AP_SYNC_KEY_IV_NVM3_KEY,
+ Ap_sync_key_material.iv,
+ sizeof(Ap_sync_key_material.iv));
+ app_assert_status(nvm3_sc);
+ } else if (psa_sc == PSA_ERROR_DOES_NOT_EXIST) {
+ app_log_info("AP sync key missing; creating it\r\n");
+ sc = initialize_key(&Ap_sync_key_material);
+ app_assert_status(sc);
+ sc = sl_bt_ead_store_key(PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_EXPORT,
+ PSA_KEY_LIFETIME_PERSISTENT,
+ &Ap_sync_key_material,
+ &ead_ap_sync_key_id);
+ app_assert_status(sc);
+ nvm3_sc = nvm3_writeData(nvm3_defaultHandle,
+ AP_SYNC_KEY_IV_NVM3_KEY,
+ Ap_sync_key_material.iv,
+ sizeof(Ap_sync_key_material.iv));
+ app_assert_status(nvm3_sc);
+ } else {
+ app_log_error("Failed to open EAD key ID=0x%08lx, PSA status=0x%08lx\r\n",
+ (unsigned long)ead_ap_sync_key_id,
+ (unsigned long)psa_sc);
+ }
+}
+
+void app_process_action(void)
+{
+ if (app_is_process_required()) {
+ /////////////////////////////////////////////////////////////////////////////
+ // Put your additional application code here! //
+ // This is will run each time app_proceed() is called. //
+ // Do not call blocking functions from here! //
+ /////////////////////////////////////////////////////////////////////////////
+ }
+}
+
+/**************************************************************************//**
+ * Bluetooth stack event handler.
+ * This overrides the default weak implementation.
+ *
+ * @param[in] evt Event coming from the Bluetooth stack.
+ *****************************************************************************/
+void sl_bt_on_event(sl_bt_msg_t *evt)
+{
+ sl_status_t sc;
+ static uint8_t connection_handle = 0xFF;
+ static gatt_sequence_state_t gatt_state = GATT_IDLE;
+ static tag_record_t connected_tag = { 0 };
+ static uint8_t provisioning_tag_id_value = 0;
+ static struct sl_bt_ead_nonce_s nonce;
+ static bool connection_in_progress = false;
+
+ switch (SL_BT_MSG_ID(evt->header)) {
+ case sl_bt_evt_system_boot_id: {
+ bd_addr address;
+ uint8_t address_type;
+ sc = sl_bt_system_get_identity_address(&address, &address_type);
+ app_assert_status(sc);
+ app_log_info("Bluetooth %s address: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
+ address_type ? "static random" : "public device",
+ address.addr[5],
+ address.addr[4],
+ address.addr[3],
+ address.addr[2],
+ address.addr[1],
+ address.addr[0]);
+
+ sc = sl_bt_sm_set_bondable_mode(1);
+ app_assert_status(sc);
+ sc = sl_bt_sm_configure(SL_BT_SM_CONFIGURATION_BONDING_REQUIRED
+ | SL_BT_SM_CONFIGURATION_SC_ONLY
+ | SL_BT_SM_CONFIGURATION_BONDING_REQUEST_REQUIRED,
+ sl_bt_sm_io_capability_noinputnooutput);
+ app_assert_status(sc);
+
+ sc = sl_bt_ead_session_init(&Ap_sync_key_material, NULL, &nonce);
+ app_assert_status(sc);
+
+ sc = sl_bt_scanner_set_parameters(sl_bt_scanner_scan_mode_passive,
+ 200,
+ 200);
+ app_assert_status(sc);
+
+ sc = sl_bt_scanner_start(sl_bt_scanner_scan_phy_1m,
+ sl_bt_scanner_discover_observation);
+ app_assert_status(sc);
+ app_log_info("Scanning for Tags\r\n");
+
+ sc = sl_bt_advertiser_create_set(&pawr_advertising_set_handle);
+ app_assert_status(sc);
+
+ sc = sl_bt_pawr_advertiser_start(pawr_advertising_set_handle,
+ PERIODIC_ADV_INTERVAL,
+ PERIODIC_ADV_INTERVAL,
+ 0,
+ SUBEVENT_NUMBER,
+ SUBEVENT_INTERVAL,
+ RESPONSE_SLOT_DELAY,
+ RESPONSE_SLOT_SPACING,
+ RESPONSE_SLOT_NUMBER_PER_SUBVENT);
+ app_assert_status(sc);
+
+ break;
+ }
+
+ case sl_bt_evt_scanner_extended_advertisement_report_id: {
+ sl_bt_evt_scanner_extended_advertisement_report_t *report =
+ &evt->data.evt_scanner_extended_advertisement_report;
+
+ if (connection_in_progress) {
+ break;
+ }
+
+ sc = find_tag(report);
+ if (sc == SL_STATUS_OK) {
+ connection_in_progress = true;
+ sc = sl_bt_connection_open(report->address,
+ report->address_type,
+ sl_bt_gap_phy_1m,
+ &connection_handle);
+ app_assert_status(sc);
+ }
+ break;
+ }
+
+ case sl_bt_evt_connection_opened_id: {
+ sl_bt_evt_connection_opened_t *connection = &evt->data.evt_connection_opened;
+ app_log_info(
+ "opened: connection=%u bonding=%u "
+ "peer=%02X:%02X:%02X:%02X:%02X:%02X type=%u\r\n",
+ connection->connection,
+ connection->bonding,
+ connection->address.addr[5],
+ connection->address.addr[4],
+ connection->address.addr[3],
+ connection->address.addr[2],
+ connection->address.addr[1],
+ connection->address.addr[0],
+ connection->address_type);
+ mbedtls_platform_zeroize(&connected_tag, sizeof(connected_tag));
+ connected_tag.tag_id = TAG_ID_UNASSIGNED;
+ connected_tag.state = TAG_RECORD_PROVISIONING;
+ connected_tag.address = connection->address;
+ connected_tag.address_type = connection->address_type;
+ connected_tag.bonding = connection->bonding;
+ gatt_state = GATT_IDLE;
+ break;
+ }
+
+ case sl_bt_evt_system_error_id: {
+ const sl_bt_evt_system_error_t *error =
+ &evt->data.evt_system_error;
+
+ app_log_error("Bluetooth system error: reason=0x%04X data_len=%u data=",
+ error->reason,
+ error->data.len);
+
+ for (uint8_t i = 0; i < error->data.len; i++) {
+ app_log("%02X", error->data.data[i]);
+ }
+
+ app_log("\r\n");
+ break;
+ }
+
+ case sl_bt_evt_connection_parameters_id: {
+ sl_bt_evt_connection_parameters_t *connection = &evt->data.evt_connection_parameters;
+
+ switch (connection->security_mode) {
+ case sl_bt_connection_mode1_level1:
+ app_log_info("No Security\r\n");
+ sc = sl_bt_gatt_discover_primary_services_by_uuid(connection->connection,
+ sizeof(SecureTagServiceUUID),
+ SecureTagServiceUUID);
+ app_assert_status(sc);
+ gatt_state = GATT_DISCOVER_SERVICE;
+ break;
+ case sl_bt_connection_mode1_level2:
+ app_log_info("Unauthenticated pairing with encryption\r\n");
+ sc = sl_bt_gatt_write_characteristic_value(connection->connection,
+ TagIDCharHandle,
+ sizeof(provisioning_tag_id_value),
+ &provisioning_tag_id_value);
+ app_assert_status(sc);
+ gatt_state = GATT_WRITE_TAG_ID;
+
+ break;
+ case sl_bt_connection_mode1_level3:
+ app_log_info("Authenticated pairing with encryption\r\n");
+ break;
+ case sl_bt_connection_mode1_level4:
+ app_log_info("Authenticated Secure connections pairing with encryption\r\n");
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case sl_bt_evt_gatt_service_id: {
+ sl_bt_evt_gatt_service_t *service = &evt->data.evt_gatt_service;
+ if (memcmp(service->uuid.data,
+ SecureTagServiceUUID,
+ sizeof(SecureTagServiceUUID)) == 0) {
+ SecureTagServiceHandle = service->service;
+ }
+ break;
+ }
+
+ case sl_bt_evt_gatt_characteristic_id: {
+ const sl_bt_evt_gatt_characteristic_t *char_evt =
+ &evt->data.evt_gatt_characteristic;
+
+ switch (gatt_state) {
+ case GATT_DISCOVER_TAG_ID:
+ TagIDCharHandle = char_evt->characteristic;
+ break;
+ case GATT_DISCOVER_AP_SYNC_KEY:
+ APSyncKeyMaterialCharHandle = char_evt->characteristic;
+ break;
+ case GATT_DISCOVER_TAG_RESP_KEY:
+ TagResponseKeyMaterialCharHandle = char_evt->characteristic;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case sl_bt_evt_gatt_characteristic_value_id: {
+ const sl_bt_evt_gatt_characteristic_value_t *char_evt =
+ &evt->data.evt_gatt_characteristic_value;
+ if (char_evt->characteristic == TagIDCharHandle) {
+ connected_tag.tag_id = char_evt->value.data[0];
+ }
+
+ break;
+ }
+
+ case sl_bt_evt_gatt_procedure_completed_id: {
+ const sl_bt_evt_gatt_procedure_completed_t *gatt_evt =
+ &evt->data.evt_gatt_procedure_completed;
+
+ if (gatt_evt->result != SL_STATUS_OK) {
+ gatt_state = GATT_FAILED;
+ app_log_info("Gatt procedure failed rc %04X\r\n", gatt_evt->result);
+ sc = sl_bt_connection_close(gatt_evt->connection);
+ app_assert_status(sc);
+ break;
+ }
+
+ switch (gatt_state) {
+ case GATT_DISCOVER_SERVICE:
+ sc = sl_bt_gatt_discover_characteristics_by_uuid(gatt_evt->connection,
+ SecureTagServiceHandle,
+ sizeof(TagIDCharUUID),
+ TagIDCharUUID);
+ app_assert_status(sc);
+ gatt_state = GATT_DISCOVER_TAG_ID;
+ break;
+
+ case GATT_DISCOVER_TAG_ID:
+ sc = sl_bt_gatt_discover_characteristics_by_uuid(gatt_evt->connection,
+ SecureTagServiceHandle,
+ sizeof(APSyncKeyMaterialUUID),
+ APSyncKeyMaterialUUID);
+ app_assert_status(sc);
+ gatt_state = GATT_DISCOVER_AP_SYNC_KEY;
+ break;
+
+ case GATT_DISCOVER_AP_SYNC_KEY:
+ sc = sl_bt_gatt_discover_characteristics_by_uuid(gatt_evt->connection,
+ SecureTagServiceHandle,
+ sizeof(TagResponseKeyMaterialUUID),
+ TagResponseKeyMaterialUUID);
+ app_assert_status(sc);
+ gatt_state = GATT_DISCOVER_TAG_RESP_KEY;
+ break;
+
+ case GATT_DISCOVER_TAG_RESP_KEY:
+ sc = sl_bt_gatt_read_characteristic_value(gatt_evt->connection,
+ TagIDCharHandle);
+ app_assert_status(sc);
+ gatt_state = GATT_READ_TAG_ID;
+ break;
+
+ case GATT_READ_TAG_ID:
+ {
+ sc = resolve_tag_id(connected_tag.tag_id,
+ connected_tag.address,
+ connected_tag.address_type,
+ &provisioning_tag_id_value);
+ if (sc != SL_STATUS_OK) {
+ app_log_error("No free/stale tag record available\r\n");
+ sc = sl_bt_connection_close(gatt_evt->connection);
+ app_assert_status(sc);
+ gatt_state = GATT_FAILED;
+ break;
+ }
+ connected_tag.tag_id = provisioning_tag_id_value;
+ sc = sl_bt_sm_increase_security(gatt_evt->connection);
+ app_assert_status(sc);
+ app_log_info("requested to increase security\r\n");
+ break;
+ }
+
+ case GATT_WRITE_TAG_ID:
+ {
+ connected_tag.response_subevent = provisioning_tag_id_value;
+ connected_tag.response_slot = provisioning_tag_id_value;
+ app_log_info("Tag ID successfully written, writing AP sync key material\r\n");
+
+ uint8_t Ap_sync_key_material_value[KEY_MATERIAL_SIZE] = { 0 };
+ export_ead_key_value(ead_ap_sync_key_id, Ap_sync_key_material, Ap_sync_key_material_value);
+ sc = sl_bt_gatt_write_characteristic_value(gatt_evt->connection,
+ APSyncKeyMaterialCharHandle,
+ sizeof(Ap_sync_key_material_value),
+ Ap_sync_key_material_value);
+ app_assert_status(sc);
+ mbedtls_platform_zeroize(Ap_sync_key_material_value,
+ sizeof(Ap_sync_key_material_value));
+ gatt_state = GATT_WRITE_AP_SYNC_KEY;
+ break;
+ }
+
+ case GATT_WRITE_AP_SYNC_KEY:
+ {
+ app_log_info("AP sync key successfully written, writing Tag resp key material\r\n");
+ struct sl_bt_ead_key_material_s tag_resp_key_material = { 0 };
+ uint8_t tag_resp_key_material_value[KEY_MATERIAL_SIZE] = { 0 };
+ sc = initialize_key(&tag_resp_key_material);
+ app_assert_status(sc);
+ psa_key_id_t key_id = TAG_RESP_KEY_ID_BASE + connected_tag.tag_id;
+ sc = sl_bt_ead_store_key(PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT,
+ PSA_KEY_LIFETIME_PERSISTENT,
+ &tag_resp_key_material,
+ &key_id);
+ app_assert_status(sc);
+ connected_tag.response_key_material = tag_resp_key_material;
+ memcpy(connected_tag.response_nonce.iv,
+ connected_tag.response_key_material.iv,
+ SL_BT_EAD_IV_SIZE);
+ app_log_info("Stored response decrypt key for tag_id=%d slot=%d\r\n",
+ provisioning_tag_id_value,
+ connected_tag.response_slot);
+ export_ead_key_value(key_id, tag_resp_key_material, tag_resp_key_material_value);
+ sc = sl_bt_gatt_write_characteristic_value(gatt_evt->connection,
+ TagResponseKeyMaterialCharHandle,
+ sizeof(tag_resp_key_material_value),
+ tag_resp_key_material_value);
+ app_assert_status(sc);
+ mbedtls_platform_zeroize(tag_resp_key_material_value,
+ sizeof(tag_resp_key_material_value));
+ gatt_state = GATT_WRITE_TAG_RESP_KEY;
+ break;
+ }
+
+ case GATT_WRITE_TAG_RESP_KEY:
+ {
+ sc = sl_bt_advertiser_past_transfer(connection_handle,
+ 0,
+ pawr_advertising_set_handle);
+ app_assert_status(sc);
+ connected_tag.state = TAG_RECORD_ACTIVE;
+ connected_tag.last_seen_tick = sl_sleeptimer_get_tick_count64();
+ tags[connected_tag.tag_id] = connected_tag;
+ gatt_state = GATT_DONE;
+ break;
+ }
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ case sl_bt_evt_sm_confirm_bonding_id: {
+ app_log_info("confirm bonding\r\n");
+ break;
+ }
+
+ case sl_bt_evt_sm_bonded_id: {
+ app_log_info("device bonded successfully\r\n");
+ break;
+ }
+
+ case sl_bt_evt_sm_bonding_failed_id: {
+ app_log_info("bonding failed, peer address: %2X:%2X:%2X:%2X:%2X:%2X reason 0x%2X, closing connection\r\n",
+ connected_tag.address.addr[5],
+ connected_tag.address.addr[4],
+ connected_tag.address.addr[3],
+ connected_tag.address.addr[2],
+ connected_tag.address.addr[1],
+ connected_tag.address.addr[0],
+ evt->data.evt_sm_bonding_failed.reason);
+ sl_bt_connection_close(evt->data.evt_sm_bonding_failed.connection);
+
+ break;
+ }
+
+ case sl_bt_evt_connection_closed_id: {
+ app_log_info("connection closed, reason 0x%2X\r\n", evt->data.evt_connection_closed.reason);
+ connection_in_progress = false;
+ break;
+ }
+
+ case sl_bt_evt_pawr_advertiser_subevent_data_request_id: {
+ sl_bt_evt_pawr_advertiser_subevent_data_request_t req =
+ evt->data.evt_pawr_advertiser_subevent_data_request;
+
+ for (uint8_t i = 0; i < req.subevent_data_count; i++) {
+ uint8_t subevent_index = (req.subevent_start + i) % SUBEVENT_NUMBER;
+ uint8_t advertisement_len;
+
+ app_log_info("Requesting data for subevent %02X\r\n", subevent_index);
+
+ sc = sl_bt_ead_randomizer_update(&nonce);
+ app_assert_status(sc);
+
+ sc = construct_advertisement_payload(&Ap_sync_key_material,
+ &nonce,
+ &advertisement_len);
+ app_assert_status(sc);
+
+ sc = sl_bt_pawr_advertiser_set_subevent_data(req.advertising_set,
+ subevent_index,
+ 0,
+ RESPONSE_SLOT_NUMBER_PER_SUBVENT,
+ advertisement_len,
+ advertisement_buffer);
+ }
+ break;
+ }
+
+ case sl_bt_evt_pawr_advertiser_response_report_id: {
+ sl_bt_evt_pawr_advertiser_response_report_t *report =
+ &evt->data.evt_pawr_advertiser_response_report;
+
+ if (report->data_status != 0) {
+ break;
+ }
+
+ app_log_info("response for subevent %02X, response slot %02X\r\n",
+ report->subevent,
+ report->response_slot);
+
+ if (report->response_slot >= MAX_TAGS) {
+ break;
+ }
+
+ tag_record_t *tag = &tags[report->response_slot];
+
+ if (tag->state != TAG_RECORD_ACTIVE
+ || tag->response_subevent != report->subevent
+ || tag->response_slot != report->response_slot) {
+ break;
+ }
+
+ sc = decrypt_tag_response(report, tag);
+ if (sc == SL_STATUS_OK) {
+ tag->last_seen_tick = sl_sleeptimer_get_tick_count64();
+ } else {
+ app_log_error("Failed to decrypt response from tag_id=%d slot=%d rc=0x%04lX\r\n",
+ tag->tag_id,
+ report->response_slot,
+ sc);
+ }
+ app_log("\n\r**************************************************************************\n\r");
+ break;
+ }
+
+ case sl_bt_evt_system_external_signal_id: {
+ if (evt->data.evt_system_external_signal.extsignals & TAG_SWEEP_SIGNAL) {
+ sweep_stale_tags();
+ }
+ break;
+ }
+
+ case sl_bt_evt_scanner_legacy_advertisement_report_id: {
+ break;
+ }
+
+ default: {
+ // app_log_info("untracked event id %08lX\r\n",(unsigned long)SL_BT_MSG_ID(evt->header));
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+// Helpers
+// -----------------------------------------------------------------------------
+static sl_status_t construct_advertisement_payload(sl_bt_ead_key_material_p key_material,
+ sl_bt_ead_nonce_p nonce,
+ uint8_t *index)
+{
+ sl_status_t sc = SL_STATUS_FAIL;
+ uint8_t manufacturer_data_buf[BLE_EA_ADV_DATA_LEN];
+ size_t manufacturer_data_len; // len + type + data
+ sl_bt_ead_mic_t message_integraty_check;
+ struct sl_bt_ead_ad_structure_s encrypted_ad_structure;
+ uint8_t encrypted_data_length = BLE_EA_ADV_DATA_LEN;
+
+ *index = 0;
+
+ // Refresh the secret part of the advertisement.
+ secret_number++;
+ snprintf(secret_data, sizeof(secret_data), "secret%02d", secret_number);
+ manufacturer_data_len = (size_t)(2 + strlen(secret_data));
+
+ // Add flags.
+ advertisement_buffer[(*index)++] = 0x02; // Ad structure len
+ advertisement_buffer[(*index)++] = 0x01; // Ad structure type
+ advertisement_buffer[(*index)++] = 0x06; // Ad structure data
+
+ // Add complete local name.
+ advertisement_buffer[(*index)++] = strlen(name) + 1; // Ad structure len
+ advertisement_buffer[(*index)++] = 0x09; // Ad structure type
+ memcpy(advertisement_buffer + *index, name, strlen(name)); // Ad structure data
+ *index += strlen(name);
+
+ // Add encrypted manufacturer specific data.
+ manufacturer_data_buf[0] = strlen(secret_data) + 1; // Ad structure len
+ manufacturer_data_buf[1] = 0xFF; // Ad structure type
+ memcpy(manufacturer_data_buf + 2, secret_data, strlen(secret_data)); // Ad structure data
+
+ sc = sl_bt_ead_encrypt(key_material,
+ nonce,
+ manufacturer_data_len,
+ manufacturer_data_buf,
+ message_integraty_check);
+ app_assert_status(sc);
+
+ encrypted_ad_structure.length = manufacturer_data_len;
+ encrypted_ad_structure.ad_type = SL_BT_ENCRYPTED_DATA_AD_TYPE;
+ encrypted_ad_structure.ad_data = manufacturer_data_buf;
+ encrypted_ad_structure.randomizer = &(nonce->randomizer);
+ encrypted_ad_structure.mic = &message_integraty_check;
+
+ sc = sl_bt_ead_pack_ad_data(&encrypted_ad_structure,
+ &encrypted_data_length,
+ advertisement_buffer + *index);
+ app_assert_status(sc);
+ app_log("Information before encryption:%s\n\r", secret_data);
+ app_log("Information after encryption:\n\r");
+
+ for (uint8_t i = *index; i < *index + encrypted_data_length; i++) {
+ app_log("%02X", advertisement_buffer[i]);
+ }
+
+ app_log("\n\r");
+ app_log("--------------------------------------------------------------------------\n\r");
+ (*index) += encrypted_data_length;
+
+ return sc;
+}
+
+static sl_status_t initialize_key(sl_bt_ead_key_material_p key_material)
+{
+ psa_status_t psa_sc = PSA_SUCCESS;
+ sl_bt_ead_session_key_t session_key = { 0 };
+ sl_bt_ead_iv_t initialization_vector = { 0 };
+
+ psa_sc = psa_generate_random(session_key, SL_BT_EAD_SESSION_KEY_SIZE);
+ if (psa_sc != PSA_SUCCESS) {
+ return SL_STATUS_FAIL;
+ }
+
+ app_log("\r\n");
+
+ psa_sc = psa_generate_random(initialization_vector, SL_BT_EAD_IV_SIZE);
+ if (psa_sc != PSA_SUCCESS) {
+ return SL_STATUS_FAIL;
+ }
+
+ app_log("\r\n");
+ memcpy(key_material->key, session_key, SL_BT_EAD_SESSION_KEY_SIZE);
+ memcpy(key_material->iv, initialization_vector, SL_BT_EAD_IV_SIZE);
+ mbedtls_platform_zeroize(session_key, sizeof(session_key));
+ mbedtls_platform_zeroize(initialization_vector,
+ sizeof(initialization_vector));
+ return SL_STATUS_OK;
+}
+
+static sl_status_t decrypt_tag_response(sl_bt_evt_pawr_advertiser_response_report_t *report,
+ tag_record_t *tag)
+{
+ sl_status_t sc;
+ uint8_t i = 0;
+ struct sl_bt_ead_ad_structure_s response_info;
+ sl_bt_ead_randomizer_t randomizer;
+ sl_bt_ead_mic_t mic;
+ uint8_t decrypted_data_buffer[30];
+
+ if (report == NULL || tag == NULL) {
+ return SL_STATUS_NULL_POINTER;
+ }
+
+ response_info.length = sizeof(decrypted_data_buffer);
+ response_info.randomizer = &randomizer;
+ response_info.ad_data = decrypted_data_buffer;
+ response_info.mic = &mic;
+
+ while (i + 1 < report->data.len) {
+ uint8_t ad_len = report->data.data[i];
+
+ if (ad_len == 0) {
+ break;
+ }
+
+ if ((uint16_t)i + ad_len >= report->data.len) {
+ app_log_error("Invalid response AD length: i=%d ad_len=%d report_len=%d\r\n",
+ i,
+ ad_len,
+ report->data.len);
+ return SL_STATUS_INVALID_PARAMETER;
+ }
+
+ uint8_t ad_type = report->data.data[i + 1];
+
+ if (ad_type == SL_BT_ENCRYPTED_DATA_AD_TYPE) {
+ app_log_info("Encrypted response from tag_id=%d slot=%d, response data:\r\n",
+ tag->tag_id,
+ report->response_slot);
+
+ for (uint8_t j = 0; j < ad_len + 1; j++) {
+ app_log("%02X", report->data.data[i + j]);
+ }
+ app_log("\r\n");
+
+ response_info.length = sizeof(decrypted_data_buffer);
+
+ sc = sl_bt_ead_unpack_ad_data(&report->data.data[i],
+ &response_info);
+ if (sc != SL_STATUS_OK) {
+ app_log_error("response unpack failed rc=0x%04lX\r\n", sc);
+ return sc;
+ }
+
+ memcpy(tag->response_nonce.randomizer,
+ response_info.randomizer,
+ SL_BT_EAD_RANDOMIZER_SIZE);
+
+ sc = sl_bt_ead_decrypt(&tag->response_key_material,
+ &tag->response_nonce,
+ (uint8_t *)response_info.mic,
+ response_info.length,
+ response_info.ad_data);
+
+ if (sc != SL_STATUS_OK) {
+ app_log_error("response decrypt failed rc=0x%04lX\r\n", sc);
+ return sc;
+ }
+
+ app_log_info("Decrypted response from tag_id=%d: ", tag->tag_id);
+
+ for (uint8_t k = 0; k < response_info.length; k++) {
+ app_log("%c", response_info.ad_data[k]);
+ }
+ app_log("\r\n");
+
+ return SL_STATUS_OK;
+ }
+
+ i = i + ad_len + 1;
+ }
+
+ return SL_STATUS_NOT_FOUND;
+}
+
+static sl_status_t find_tag(sl_bt_evt_scanner_extended_advertisement_report_t *report)
+{
+ uint8_t index = 0;
+
+ while (index < report->data.len) {
+ uint8_t ADdatalen = report->data.data[index];
+ uint8_t ADdatatype = report->data.data[index + 1];
+
+ if (ADdatatype == 0x06 || ADdatatype == 0x07) {
+ if (memcmp(&report->data.data[index + 2],
+ SecureTagServiceUUID,
+ sizeof(SecureTagServiceUUID)) == 0) {
+ return SL_STATUS_OK;
+ }
+ }
+
+ index = index + ADdatalen + 1;
+ }
+
+ return SL_STATUS_FAIL;
+}
+
+static bool address_compare(const tag_record_t *tag,
+ bd_addr address,
+ uint8_t address_type)
+{
+ return tag->state != TAG_RECORD_FREE
+ && tag->address_type == address_type
+ && memcmp(tag->address.addr, address.addr, sizeof(address.addr)) == 0;
+}
+
+static sl_status_t find_record_by_address(bd_addr address,
+ uint8_t address_type,
+ uint8_t *tag_id)
+{
+ for (uint8_t i = 0; i < MAX_TAGS; i++) {
+ if (address_compare(&tags[i], address, address_type)) {
+ *tag_id = i;
+ return SL_STATUS_OK;
+ }
+ }
+
+ return SL_STATUS_NOT_FOUND;
+}
+
+static sl_status_t allocate_record(uint8_t *tag_id)
+{
+ for (uint8_t i = 0; i < MAX_TAGS; i++) {
+ if (tags[i].state == TAG_RECORD_FREE || tags[i].state == TAG_RECORD_STALE) {
+ *tag_id = i;
+ return SL_STATUS_OK;
+ }
+ }
+
+ return SL_STATUS_FULL;
+}
+
+static sl_status_t resolve_tag_id(uint8_t claimed_id,
+ bd_addr address,
+ uint8_t address_type,
+ uint8_t *resolved_id)
+{
+ if (claimed_id < MAX_TAGS && address_compare(&tags[claimed_id], address, address_type)) {
+ *resolved_id = claimed_id;
+ return SL_STATUS_OK;
+ }
+
+ if (find_record_by_address(address, address_type, resolved_id) == SL_STATUS_OK) {
+ return SL_STATUS_OK;
+ }
+
+ return allocate_record(resolved_id);
+}
+
+static void sweep_stale_tags(void)
+{
+ uint64_t now = sl_sleeptimer_get_tick_count64();
+
+ for (uint8_t i = 0; i < MAX_TAGS; i++) {
+ tag_record_t *tag = &tags[i];
+
+ if (tag->state == TAG_RECORD_ACTIVE
+ && (now - tag->last_seen_tick) > tag_stale_timeout_ticks) {
+ if (tag->response_key_material.key_id != PSA_KEY_ID_NULL) {
+ sl_bt_ead_delete_key(&tag->response_key_material);
+ }
+ mbedtls_platform_zeroize(&tag->response_nonce,
+ sizeof(tag->response_nonce));
+ tag->state = TAG_RECORD_STALE;
+ tag->bonding = SL_BT_INVALID_BONDING_HANDLE;
+ app_log_info("tag_id=%d marked stale\r\n", tag->tag_id);
+ }
+ }
+}
+
+static void stale_timer_cb(sl_sleeptimer_timer_handle_t *handle, void *data)
+{
+ (void)handle;
+ (void)data;
+ sl_bt_external_signal(TAG_SWEEP_SIGNAL);
+}
+
+static void export_ead_key_value(psa_key_id_t key_id, struct sl_bt_ead_key_material_s key_material, uint8_t key_material_value[KEY_MATERIAL_SIZE])
+{
+ uint8_t session_key_value[SL_BT_EAD_SESSION_KEY_SIZE] = { 0 };
+ size_t exported_length = 0;
+
+ psa_status_t psa_sc = psa_export_key(
+ key_id,
+ session_key_value,
+ sizeof(session_key_value),
+ &exported_length);
+ app_assert_status(psa_sc);
+
+ for (size_t i = 0; i < exported_length / 2; i++) {
+ uint8_t tmp = session_key_value[i];
+ session_key_value[i] =
+ session_key_value[exported_length - 1 - i];
+ session_key_value[exported_length - 1 - i] = tmp;
+ }
+
+ memcpy(key_material_value, session_key_value, SL_BT_EAD_SESSION_KEY_SIZE);
+ memcpy(key_material_value + SL_BT_EAD_SESSION_KEY_SIZE, key_material.iv, SL_BT_EAD_IV_SIZE);
+ mbedtls_platform_zeroize(session_key_value,
+ sizeof(session_key_value));
+}
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/main.c b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/main.c
new file mode 100644
index 0000000..72c8be4
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/access_point/main.c
@@ -0,0 +1,71 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2025 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_main_init.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_main_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_main_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, the start task will be started and software
+ // component initialization will take place there.
+ sl_main_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. The start task will be executed (Highest priority) to complete
+ // the Simplicity SDK components initialization and the user app_init() hook function will be called.
+ sl_main_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+
+ // User provided code.
+ app_init();
+
+ while (1) {
+ // Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_main_process_action();
+
+ // User provided code. Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/app.c b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/app.c
new file mode 100644
index 0000000..3637fca
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/app.c
@@ -0,0 +1,514 @@
+/***************************************************************************//**
+ * @file
+ * @brief Core application logic.
+ *******************************************************************************
+ * # License
+ * Copyright 2024 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#include "sl_bt_api.h"
+#include "sl_main_init.h"
+#include "app_assert.h"
+#include "app.h"
+#include "app_log.h"
+#include
+#include
+#include "sl_bt_ead_core.h"
+#include "psa/crypto.h"
+#include "psa/crypto_values.h"
+#include "sl_sleeptimer.h"
+
+#define U1250_TO_MS(x) ((uint32_t)(x) * 1250u / 1000u) /* 1.25 ms units -> ms */
+#define U0125_TO_US(x) ((uint32_t)(x) * 125u) /* 0.125 ms units -> us */
+
+#define PERIODIC_SYNC_SKIP 0
+#define PERIODIC_SYNC_TIMEOUT 600
+
+#define gattdb_tag_id 0x15
+#define gattdb_ap_sync_key_material 0x17
+#define gattdb_tag_response_key_material 0x19
+
+#define KEY_MATERIAL_SIZE (SL_BT_EAD_SESSION_KEY_SIZE + SL_BT_EAD_IV_SIZE)
+uint8_t tag_id = 0;
+
+static struct sl_bt_ead_key_material_s Ap_sync_key_material = { 0 };
+static struct sl_bt_ead_key_material_s tag_response_key_material = { 0 };
+
+// The advertising set handle allocated from Bluetooth stack.
+static uint8_t advertising_set_handle = 0xff;
+static bool advertising_active = false;
+
+// Response data
+#define BLE_EA_RSP_DATA_LEN 0xBF
+#define RESPONSE_PLAINTEXT_MAX_LEN 16
+uint8_t response_buffer[BLE_EA_RSP_DATA_LEN];
+uint8_t secret_data_len = 0;
+uint8_t secret_number = 0;
+
+static sl_sleeptimer_timer_handle_t out_of_sync_timer;
+#define TAG_OUT_OF_SYNC_PERIOD_MS 10000
+#define TAG_OUT_OF_SYNC_SIGNAL 0x01
+static void out_of_sync_cb(sl_sleeptimer_timer_handle_t *handle, void *data);
+
+uint8_t subevents_subscription_list[] = { 0 };
+
+uint16_t pawr_handle = SL_BT_INVALID_SYNC_HANDLE;
+uint8_t connection = SL_BT_INVALID_CONNECTION_HANDLE;
+bd_addr ap_address = { 0 };
+
+sl_status_t extract_and_decrypt(sl_bt_evt_pawr_sync_subevent_report_t *sync_report,
+ sl_bt_ead_key_material_p key_material,
+ sl_bt_ead_nonce_p nonce);
+
+sl_status_t construct_response_payload(sl_bt_ead_key_material_p key_material, sl_bt_ead_nonce_p nonce, uint8_t* secret_payload, uint8_t* secret_payload_len);
+
+// Application Init.
+void app_init(void)
+{
+ sl_status_t sc;
+ uint32_t out_of_sync_ticks;
+
+ sc = sl_sleeptimer_init();
+ app_assert_status(sc);
+
+ sc = sl_sleeptimer_ms32_to_tick(TAG_OUT_OF_SYNC_PERIOD_MS,
+ &out_of_sync_ticks);
+ app_assert_status(sc);
+ sc = sl_sleeptimer_start_periodic_timer(&out_of_sync_timer,
+ out_of_sync_ticks,
+ out_of_sync_cb,
+ NULL,
+ 0,
+ 0);
+ app_assert_status(sc);
+}
+
+void app_process_action(void)
+{
+ if (app_is_process_required()) {
+ /////////////////////////////////////////////////////////////////////////////
+ // Put your additional application code here! //
+ // This is will run each time app_proceed() is called. //
+ // Do not call blocking functions from here! //
+ /////////////////////////////////////////////////////////////////////////////
+ }
+}
+
+/**************************************************************************//**
+ * Bluetooth stack event handler.
+ * This overrides the default weak implementation.
+ *
+ * @param[in] evt Event coming from the Bluetooth stack.
+ *****************************************************************************/
+void sl_bt_on_event(sl_bt_msg_t *evt)
+{
+ sl_status_t sc;
+ static struct sl_bt_ead_nonce_s ap_sync_nonce, tag_resp_nonce;
+ static psa_key_id_t ap_sync_key_id = PSA_KEY_ID_NULL;
+ static psa_key_id_t tag_resp_key_id = PSA_KEY_ID_NULL;
+
+ switch (SL_BT_MSG_ID(evt->header)) {
+ case sl_bt_evt_system_boot_id:
+ {
+ bd_addr address;
+ uint8_t address_type;
+ app_log_info("++++++++++++++++++++++++++++++++++++ Tag boot ++++++++++++++++++++++++++++++++++++\r\n");
+ sc = sl_bt_system_get_identity_address(&address, &address_type);
+ app_assert_status(sc);
+ app_log_info("Bluetooth %s address: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
+ address_type ? "static random" : "public device",
+ address.addr[5],
+ address.addr[4],
+ address.addr[3],
+ address.addr[2],
+ address.addr[1],
+ address.addr[0]);
+
+ sc = sl_bt_sm_set_bondable_mode(1);
+ app_assert_status(sc);
+ sc = sl_bt_sm_configure(SL_BT_SM_CONFIGURATION_BONDING_REQUIRED
+ | SL_BT_SM_CONFIGURATION_SC_ONLY
+ | SL_BT_SM_CONFIGURATION_BONDING_REQUEST_REQUIRED,
+ sl_bt_sm_io_capability_noinputnooutput);
+ app_assert_status(sc);
+
+ sc = sl_bt_past_receiver_set_default_sync_receive_parameters(
+ sl_bt_past_receiver_mode_synchronize,
+ PERIODIC_SYNC_SKIP,
+ PERIODIC_SYNC_TIMEOUT,
+ sl_bt_sync_report_all
+ );
+
+ sc = sl_bt_advertiser_create_set(&advertising_set_handle);
+ app_assert_status(sc);
+
+ sc = sl_bt_extended_advertiser_generate_data(advertising_set_handle,
+ sl_bt_advertiser_general_discoverable);
+ app_assert_status(sc);
+
+ sc = sl_bt_advertiser_set_timing(
+ advertising_set_handle,
+ 160, // min. adv. interval (milliseconds * 1.6)
+ 160, // max. adv. interval (milliseconds * 1.6)
+ 0, // adv. duration
+ 0); // max. num. adv. events
+ app_assert_status(sc);
+ // Start advertising and enable connections.
+ sc = sl_bt_extended_advertiser_start(advertising_set_handle,
+ sl_bt_extended_advertiser_connectable, 0x00);
+ app_assert_status(sc);
+ advertising_active = true;
+ app_log_info("starting provisioning advertisement\r\n");
+ break;
+ }
+
+ case sl_bt_evt_connection_opened_id:
+ {
+ app_log_info("connection opened\r\n");
+ connection = evt->data.evt_connection_opened.connection;
+ ap_address = evt->data.evt_connection_opened.address;
+ advertising_active = false;
+ break;
+ }
+
+ case sl_bt_evt_connection_closed_id:
+ {
+ app_log_info("connection closed, reason 0x%2X\r\n", evt->data.evt_connection_closed.reason);
+ connection = SL_BT_INVALID_CONNECTION_HANDLE;
+ break;
+ }
+
+ case sl_bt_evt_connection_parameters_id: {
+ switch (evt->data.evt_connection_parameters.security_mode) {
+ case sl_bt_connection_mode1_level1:
+ app_log_info("No Security\r\n");
+ break;
+ case sl_bt_connection_mode1_level2:
+ app_log_info("Unauthenticated pairing with encryption\r\n");
+ break;
+ case sl_bt_connection_mode1_level3:
+ app_log_info("Authenticated pairing with encryption\r\n");
+ break;
+ case sl_bt_connection_mode1_level4:
+ app_log_info("Authenticated Secure Connections pairing with encryption\r\n");
+ break;
+ }
+ break;
+ }
+
+ case sl_bt_evt_gatt_server_attribute_value_id:
+ {
+ sl_bt_evt_gatt_server_attribute_value_t *att_value = &evt->data.evt_gatt_server_attribute_value;
+ switch (att_value->attribute) {
+ case gattdb_tag_id:
+ app_log_info("assigned tag id %d\r\n", att_value->value.data[0]);
+ tag_id = att_value->value.data[0];
+ subevents_subscription_list[0] = tag_id;
+ break;
+ case gattdb_ap_sync_key_material:
+
+ memcpy(Ap_sync_key_material.key,
+ att_value->value.data,
+ SL_BT_EAD_SESSION_KEY_SIZE);
+
+ memcpy(Ap_sync_key_material.iv,
+ att_value->value.data + SL_BT_EAD_SESSION_KEY_SIZE,
+ SL_BT_EAD_IV_SIZE);
+
+ memcpy(ap_sync_nonce.iv,
+ Ap_sync_key_material.iv,
+ SL_BT_EAD_IV_SIZE);
+ sc = sl_bt_ead_store_key(PSA_KEY_USAGE_DECRYPT, PSA_KEY_LIFETIME_VOLATILE, &Ap_sync_key_material, &ap_sync_key_id);
+ app_assert_status(sc);
+ break;
+ case gattdb_tag_response_key_material:
+ memcpy(tag_response_key_material.key,
+ att_value->value.data,
+ SL_BT_EAD_SESSION_KEY_SIZE);
+
+ memcpy(tag_response_key_material.iv,
+ att_value->value.data + SL_BT_EAD_SESSION_KEY_SIZE,
+ SL_BT_EAD_IV_SIZE);
+
+ memcpy(tag_resp_nonce.iv,
+ tag_response_key_material.iv,
+ SL_BT_EAD_IV_SIZE);
+ sc = sl_bt_ead_store_key(PSA_KEY_USAGE_ENCRYPT, PSA_KEY_LIFETIME_VOLATILE, &tag_response_key_material, &tag_resp_key_id);
+ app_assert_status(sc);
+ break;
+ }
+ break;
+ }
+
+ case sl_bt_evt_pawr_sync_transfer_received_id:
+ {
+ sl_bt_evt_pawr_sync_transfer_received_t sync_report = evt->data.evt_pawr_sync_transfer_received;
+ app_log(" sync status %02X\r\n", sync_report.status);
+ app_log(
+ "PAwR sync opened:\r\n"
+ "adv_interval= %" PRIu32 "ms\r\n"
+ "num_subevents= %d\r\n"
+ "subevent_interval= %" PRIu32 "ms\r\n"
+ "rsp_slot_delay= %" PRIu32 "ms\r\n"
+ "rsp_slot_spacing= %" PRIu32 "us\r\n",
+ U1250_TO_MS(sync_report.adv_interval),
+ sync_report.num_subevents,
+ U1250_TO_MS(sync_report.subevent_interval),
+ U1250_TO_MS(sync_report.response_slot_delay),
+ U0125_TO_US(sync_report.response_slot_spacing)
+ );
+ pawr_handle = sync_report.sync;
+ sc = sl_bt_pawr_sync_set_sync_subevents(pawr_handle, sizeof(subevents_subscription_list), subevents_subscription_list);
+ app_assert_status(sc);
+ sc = sl_bt_connection_close(sync_report.connection);
+ app_assert_status(sc);
+ break;
+ }
+
+ case sl_bt_evt_sync_closed_id:
+ {
+ app_log_info("Sync closed: handle=0x%04X reason=0x%04X\r\n",
+ evt->data.evt_sync_closed.sync,
+ evt->data.evt_sync_closed.reason);
+ pawr_handle = SL_BT_INVALID_SYNC_HANDLE;
+ break;
+ }
+
+ case sl_bt_evt_pawr_sync_opened_id:
+ {
+ app_log_info("sync opened\r\n");
+ break;
+ }
+
+ case sl_bt_evt_pawr_sync_subevent_report_id:
+ {
+ sl_bt_evt_pawr_sync_subevent_report_t *sync_report = &evt->data.evt_pawr_sync_subevent_report;
+ for (uint8_t index = 0; index < sizeof(subevents_subscription_list) / sizeof(uint8_t); index++) {
+ if (subevents_subscription_list[index] == sync_report->subevent) {
+ app_log("--------------------------------------------------------------------------\n\r");
+ app_log_info(
+ "PAwR report: sync=0x%04X subevent=%u status=%u len=%u counter=%u\r\n",
+ sync_report->sync,
+ sync_report->subevent,
+ sync_report->data_status,
+ sync_report->data.len,
+ sync_report->counter);
+ if (sync_report->data_status == 255) {
+ app_log_info("Failed to receive subevent data in this subevent\r\n");
+ break;
+ }
+ sc = extract_and_decrypt(sync_report, &Ap_sync_key_material, &ap_sync_nonce);
+ if (sc != 0) {
+ app_log("failed to decrypt the message\r\n");
+ sc = sl_bt_sync_close(sync_report->sync);
+ app_assert_status(sc);
+ pawr_handle = SL_BT_INVALID_SYNC_HANDLE;
+ break;
+ }
+ sc = sl_bt_ead_randomizer_update(&tag_resp_nonce);
+ app_assert_status(sc);
+
+ secret_number++;
+
+ secret_data_len = BLE_EA_RSP_DATA_LEN;
+
+ sc = construct_response_payload(&tag_response_key_material,
+ &tag_resp_nonce,
+ response_buffer,
+ &secret_data_len);
+ app_assert_status(sc);
+
+ sc = sl_bt_pawr_sync_set_response_data(pawr_handle,
+ sync_report->event_counter,
+ sync_report->subevent,
+ sync_report->subevent,
+ tag_id,
+ secret_data_len,
+ response_buffer);
+ if (sc == SL_STATUS_BT_CTRL_TOO_LATE) {
+ app_log_warning("TAG PAWR response was too late, skipping\r\n");
+ } else {
+ app_assert_status(sc);
+ }
+ }
+ }
+ break;
+ }
+
+ case sl_bt_evt_sm_confirm_bonding_id: {
+ app_log_info("new bonding request\r\n");
+ sl_bt_sm_bonding_confirm(evt->data.evt_sm_confirm_bonding.connection, 0x01);
+ break;
+ }
+
+ case sl_bt_evt_sm_bonded_id:
+ {
+ app_log_info("device bonded successfully\r\n");
+ break;
+ }
+
+ case sl_bt_evt_sm_bonding_failed_id:
+ {
+ app_log_info("bonding failed, peer address: %2X:%2X:%2X:%2X:%2X:%2X reason 0x%2X, closing connection\r\n",
+ ap_address.addr[5],
+ ap_address.addr[4],
+ ap_address.addr[3],
+ ap_address.addr[2],
+ ap_address.addr[1],
+ ap_address.addr[0],
+ evt->data.evt_sm_bonding_failed.reason);
+ break;
+ }
+
+ case sl_bt_evt_system_external_signal_id:
+ {
+ if (evt->data.evt_system_external_signal.extsignals & TAG_OUT_OF_SYNC_SIGNAL) {
+ if (pawr_handle == SL_BT_INVALID_SYNC_HANDLE && connection == SL_BT_INVALID_CONNECTION_HANDLE && !advertising_active) {
+ sc = sl_bt_extended_advertiser_generate_data(advertising_set_handle,
+ sl_bt_advertiser_general_discoverable);
+ app_assert_status(sc);
+ sc = sl_bt_extended_advertiser_start(advertising_set_handle,
+ sl_bt_extended_advertiser_connectable, 0x00);
+ app_assert_status(sc);
+ advertising_active = true;
+ app_log_info("sync lost, restarting provisioning advertisement\r\n");
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ // app_log_info("untracked event id %08lX\r\n",(unsigned long)SL_BT_MSG_ID(evt->header));
+ break;
+ }
+ }
+}
+
+sl_status_t extract_and_decrypt(sl_bt_evt_pawr_sync_subevent_report_t *sync_report,
+ sl_bt_ead_key_material_p key_material,
+ sl_bt_ead_nonce_p nonce)
+{
+ sl_status_t sc = SL_STATUS_FAIL;
+ uint8_t ad_len;
+ uint8_t ad_type;
+ uint8_t i = 0;
+ struct sl_bt_ead_ad_structure_s advertisement_info;
+ sl_bt_ead_randomizer_t randomizer;
+ uint8_t encrypted_data_buffer[30];
+ sl_bt_ead_mic_t mic;
+
+ app_log("Decrypting\r\n");
+
+ advertisement_info.length = sizeof(encrypted_data_buffer);
+ advertisement_info.randomizer = &randomizer;
+ advertisement_info.ad_data = encrypted_data_buffer;
+ advertisement_info.mic = &mic;
+
+ while (i < sync_report->data.len) {
+ ad_len = sync_report->data.data[i];
+ ad_type = sync_report->data.data[i + 1];
+ if (ad_type == SL_BT_ENCRYPTED_DATA_AD_TYPE) {
+ app_log("Subevent information encrypted:\r\n");
+ for (uint8_t j = 0; j < ad_len + 1; j++) {
+ app_log("%02X", sync_report->data.data[i + j]);
+ }
+ sc = sl_bt_ead_unpack_ad_data(&sync_report->data.data[i], &advertisement_info);
+ if (sc != 0) {
+ app_log("unpacking unsuccessful with rc %08lX\r\n", sc);
+ }
+ memcpy(nonce->randomizer, advertisement_info.randomizer, SL_BT_EAD_RANDOMIZER_SIZE);
+ sc = sl_bt_ead_decrypt(key_material, nonce, (uint8_t *)advertisement_info.mic, advertisement_info.length, advertisement_info.ad_data);
+ if (sc != 0) {
+ app_log("decrypting unsuccessful with rc %08lX\r\n", sc);
+ } else {
+ app_log("\r\nSubevent information decrypted:");
+ for (uint8_t i = 2; i < advertisement_info.length; i++) {
+ app_log("%c", advertisement_info.ad_data[i]);
+ }
+ app_log("\r\n");
+ }
+ }
+ i = i + ad_len + 1;
+ }
+ return sc;
+}
+
+sl_status_t construct_response_payload(sl_bt_ead_key_material_p key_material,
+ sl_bt_ead_nonce_p nonce,
+ uint8_t *response_payload,
+ uint8_t *response_payload_len)
+{
+ sl_status_t sc;
+ uint8_t plaintext[RESPONSE_PLAINTEXT_MAX_LEN];
+ uint8_t packed_len = BLE_EA_RSP_DATA_LEN;
+ size_t plaintext_len;
+ sl_bt_ead_mic_t mic;
+ struct sl_bt_ead_ad_structure_s encrypted_ad_structure;
+
+ snprintf((char *)plaintext,
+ sizeof(plaintext),
+ "secret%02d",
+ secret_number);
+
+ plaintext_len = strlen((char *)plaintext);
+
+ app_log("Response Information before encryption: %s\r\n",
+ plaintext);
+
+ sc = sl_bt_ead_encrypt(key_material,
+ nonce,
+ plaintext_len,
+ plaintext,
+ mic);
+ app_assert_status(sc);
+
+ encrypted_ad_structure.length = plaintext_len;
+ encrypted_ad_structure.ad_type = SL_BT_ENCRYPTED_DATA_AD_TYPE;
+ encrypted_ad_structure.ad_data = plaintext;
+ encrypted_ad_structure.randomizer = &(nonce->randomizer);
+ encrypted_ad_structure.mic = &mic;
+
+ sc = sl_bt_ead_pack_ad_data(&encrypted_ad_structure,
+ &packed_len,
+ response_payload);
+ app_assert_status(sc);
+
+ *response_payload_len = packed_len;
+
+ app_log("Response Information after encryption:\r\n");
+ for (uint8_t i = 0; i < packed_len; i++) {
+ app_log("%02X", response_payload[i]);
+ }
+ app_log("\r\n");
+
+ return SL_STATUS_OK;
+}
+
+static void out_of_sync_cb(sl_sleeptimer_timer_handle_t *handle, void *data)
+{
+ (void)handle;
+ (void)data;
+ sl_bt_external_signal(TAG_OUT_OF_SYNC_SIGNAL);
+}
diff --git a/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/main.c b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/main.c
new file mode 100644
index 0000000..72c8be4
--- /dev/null
+++ b/advertising/periodic_advertisement_with_responses/encrypted_pawr/src/tag/main.c
@@ -0,0 +1,71 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief main() function.
+ *******************************************************************************
+ * # License
+ * Copyright 2025 Silicon Laboratories Inc. www.silabs.com
+ *******************************************************************************
+ *
+ * SPDX-License-Identifier: Zlib
+ *
+ * The licensor of this software is Silicon Laboratories Inc.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ ******************************************************************************/
+#include "sl_component_catalog.h"
+#include "sl_main_init.h"
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+#include "sl_power_manager.h"
+#endif
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+#include "sl_main_kernel.h"
+#else // SL_CATALOG_KERNEL_PRESENT
+#include "sl_main_process_action.h"
+#endif // SL_CATALOG_KERNEL_PRESENT
+
+int main(void)
+{
+ // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
+ // Note that if the kernel is present, the start task will be started and software
+ // component initialization will take place there.
+ sl_main_init();
+
+#if defined(SL_CATALOG_KERNEL_PRESENT)
+ // Start the kernel. The start task will be executed (Highest priority) to complete
+ // the Simplicity SDK components initialization and the user app_init() hook function will be called.
+ sl_main_kernel_start();
+#else // SL_CATALOG_KERNEL_PRESENT
+
+ // User provided code.
+ app_init();
+
+ while (1) {
+ // Silicon Labs components process action routine
+ // must be called from the super loop.
+ sl_main_process_action();
+
+ // User provided code. Application process.
+ app_process_action();
+
+#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
+ // Let the CPU go to sleep if the system allows it.
+ sl_power_manager_sleep();
+#endif
+ }
+#endif // SL_CATALOG_KERNEL_PRESENT
+}
diff --git a/advertising/periodic_advertisement_with_responses/README.md b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/README.md
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/README.md
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/README.md
diff --git a/advertising/periodic_advertisement_with_responses/SimplicityStudio/readme.md b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/readme.md
similarity index 92%
rename from advertising/periodic_advertisement_with_responses/SimplicityStudio/readme.md
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/readme.md
index fada19f..06de136 100644
--- a/advertising/periodic_advertisement_with_responses/SimplicityStudio/readme.md
+++ b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/readme.md
@@ -1,6 +1,6 @@
# Periodic Advertisement Example
-The readme file of this project can be found [here](https://github.com/SiliconLabs/bluetooth_stack_features/blob/master/advertising/periodic_advertisement_with_responses/README.md).
+The readme file of this project can be found [here](https://github.com/SiliconLabs/bluetooth_stack_features/blob/master/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/README.md).
.
> Note: In this project all the necessary software components are installed, source files are copied, and configurations are set, hence you can disregard the Setting Up section of the online readme file. Nevertheless, if you want to add the demonstrated feature to your own project, it might be good to know what software components you must install, and what configurations you must set beforehand, hence reading through the Setting Up section might be useful.
diff --git a/advertising/periodic_advertisement_with_responses/SimplicityStudio/soc_pawr_advertiser.slcp b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/soc_pawr_advertiser.slcp
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/SimplicityStudio/soc_pawr_advertiser.slcp
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/soc_pawr_advertiser.slcp
diff --git a/advertising/periodic_advertisement_with_responses/SimplicityStudio/soc_pawr_scanner.slcp b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/soc_pawr_scanner.slcp
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/SimplicityStudio/soc_pawr_scanner.slcp
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/SimplicityStudio/soc_pawr_scanner.slcp
diff --git a/advertising/periodic_advertisement_with_responses/config/gatt_configuration.btconf b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/config/gatt_configuration.btconf
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/config/gatt_configuration.btconf
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/config/gatt_configuration.btconf
diff --git a/advertising/periodic_advertisement_with_responses/images/console_output.png b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/console_output.png
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/images/console_output.png
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/console_output.png
diff --git a/advertising/periodic_advertisement_with_responses/images/pawr_timing.png b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/pawr_timing.png
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/images/pawr_timing.png
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/pawr_timing.png
diff --git a/advertising/periodic_advertisement_with_responses/images/sequence.png b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/sequence.png
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/images/sequence.png
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/images/sequence.png
diff --git a/advertising/periodic_advertisement_with_responses/inc/advertiser/app.h b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/inc/advertiser/app.h
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/inc/advertiser/app.h
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/inc/advertiser/app.h
diff --git a/advertising/periodic_advertisement_with_responses/inc/scanner/app.h b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/inc/scanner/app.h
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/inc/scanner/app.h
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/inc/scanner/app.h
diff --git a/advertising/periodic_advertisement_with_responses/src/pawr_advertiser/app.c b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_advertiser/app.c
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/src/pawr_advertiser/app.c
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_advertiser/app.c
diff --git a/advertising/periodic_advertisement_with_responses/src/pawr_advertiser/main.c b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_advertiser/main.c
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/src/pawr_advertiser/main.c
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_advertiser/main.c
diff --git a/advertising/periodic_advertisement_with_responses/src/pawr_scanner/app.c b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_scanner/app.c
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/src/pawr_scanner/app.c
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_scanner/app.c
diff --git a/advertising/periodic_advertisement_with_responses/src/pawr_scanner/main.c b/advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_scanner/main.c
similarity index 100%
rename from advertising/periodic_advertisement_with_responses/src/pawr_scanner/main.c
rename to advertising/periodic_advertisement_with_responses/pawr_sync_transfer/src/pawr_scanner/main.c
diff --git a/bluetooth_stack_features_app_templates.xml b/bluetooth_stack_features_app_templates.xml
index ce143d8..88d4d36 100644
--- a/bluetooth_stack_features_app_templates.xml
+++ b/bluetooth_stack_features_app_templates.xml
@@ -461,8 +461,8 @@
-
-
+
+
@@ -473,8 +473,32 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -488,8 +512,8 @@
solely on the private address and advertising data.
">
-
-
+
+
@@ -503,8 +527,8 @@
solely on the private address and advertising data.
">
-
-
+
+