Imported more library files

Not compiling currently
This commit is contained in:
2025-04-12 23:37:19 +01:00
parent 264a3462e0
commit 9d06f983af
2518 changed files with 1021900 additions and 52 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
/***************************************************************************//**
* @brief Debugging helpers used internally by the Bluetooth stack
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BGCOMMON_DEBUG_H
#define SLI_BGCOMMON_DEBUG_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup sli_bgcommon_debug
* @{
*
* @brief Debugging helpers used internally by the Bluetooth stack
*
* The functions provided by this file are used by the Bluetooth stack to access
* device-specific registers that the device-agnostic Bluetooth libraries cannot
* take a direct dependency to.
*
******************************************************************************/
/**
* @brief Enable the MCU cycle counter
*/
void sli_bgcommon_debug_init_cycle_count(void);
/**
* @brief Get the current MCU cycle count
*/
uint32_t sli_bgcommon_debug_get_cycle_count(void);
/** @} end sli_bgcommon_debug */
#ifdef __cplusplus
}
#endif
#endif // SLI_BGCOMMON_DEBUG_H

View File

@@ -0,0 +1,31 @@
/***************************************************************************//**
* @brief Debugging helpers used internally by the Bluetooth stack
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include <em_device.h>
#include "sli_bgcommon_debug.h"
// Enable the MCU cycle counter
void sli_bgcommon_debug_init_cycle_count(void)
{
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
// Get the current MCU cycle count
uint32_t sli_bgcommon_debug_get_cycle_count(void)
{
return DWT->CYCCNT;
}

View File

@@ -0,0 +1,311 @@
/***************************************************************************//**
* @brief Bluetooth Link Layer configuration API
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 _SL_BTCTRL_LINKLAYER_H_
#define _SL_BTCTRL_LINKLAYER_H_
#include "sl_status.h"
#include <stdint.h>
void sl_bt_controller_init(void);
void sl_bt_controller_deinit(void);
void sl_btctrl_init(void);
/**
* Allocate memory buffers for controller
*
* @param memsize size of memory to allocate
* @returns number of memory buffers allocated
*/
uint32_t sl_btctrl_init_mem(uint32_t memsize);
/**
* Configures how many maximum sized ACL data packets
* can the controller store.
*/
void sl_btctrl_configure_le_buffer_size(uint8_t count);
/**
* Release all memory allocated by controller
*/
void sli_btctrl_deinit_mem(void);
void sli_btctrl_set_interrupt_priorities();
sl_status_t sl_btctrl_init_ll(void);
void sli_btctrl_set_address(uint8_t *address);
//Initialize memory objects used by LinkLayer
//In future these should be configured individually
sl_status_t sl_btctrl_init_basic(uint8_t connections, uint8_t adv_sets, uint8_t whitelist);
void sli_btctrl_events_init(void);
enum sl_btctrl_channelmap_flags{
SL_BTCTRL_CHANNELMAP_FLAG_ACTIVE_ADAPTIVITY = 0x01,
SL_BTCTRL_CHANNELMAP_FLAG_PASSIVE_ADAPTIVITY= 0x02,
};
/**
* Initialize and enable adaptive frequency hopping
*/
sl_status_t sl_btctrl_init_afh(uint32_t flags);
/**
* Enable high power use under appropriate conditions
*/
void sl_btctrl_init_highpower(void);
/**
* @brief Initilize periodic advertiser
*/
void sl_btctrl_init_periodic_adv();
/**
* @brief Initilize periodic advertiser
*/
void sl_btctrl_init_periodic_scan();
/**
* Configuration for Periodic Advertising with Responses.
*/
struct sl_btctrl_pawr_advertiser_config {
/**
* Number of advertising sets supporting PAwR.
* If set to zero, previously allocated PAwR sets are only freed. */
uint8_t max_pawr_sets;
/**
* Hint to the controller what will be the maximum advertised data length.
* The value does not prevent using longer advertising data. Value zero means
* that maximum data length can expected to be up to the length of Periodic
* Advertising Delay. */
uint8_t max_advertised_data_length_hint;
/**
* The number of subevent advertising packets requested from the host
* at once. */
uint8_t subevent_data_request_count;
/**
* How many subevents before airing a subevent its data is requested from
* the host. */
uint8_t subevent_data_request_advance;
};
/**
* Configuration of synchronizer for Periodic Advertising with Responses.
*/
struct sl_btctrl_pawr_synchronizer_config {
/**
* Number of advertising sets supporting PArR.
* If set to zero, previously allocated PArR sets are only freed. */
uint8_t max_pawr_sets;
};
/**
* @brief Enable and initialize support for the PAwR advertiser.
* @param[in] pawr_adv_config PAwR advertiser configuration.
* @return SL_STATUS_OK, or an appropriate error code. */
sl_status_t sl_btctrl_pawr_advertiser_configure(struct sl_btctrl_pawr_advertiser_config *pawr_adv_config);
/**
* @brief Enable and initialize support for PAwR sync/receiver.
* @param[in] pawr_sync_config PAwR synchronizer configuration.
* @return SL_STATUS_OK, or an appropriate error code. */
sl_status_t sl_btctrl_pawr_synchronizer_configure(struct sl_btctrl_pawr_synchronizer_config *pawr_sync_config);
/**
* @brief Allocate memory for synchronized scanners
*
* @param num_scan Number of Periodic Scanners Allowed
* @return SL_STATUS_OK if allocation was succesfull, failure reason otherwise
*/
sl_status_t sl_btctrl_alloc_periodic_scan(uint8_t num_scan);
/**
* @brief Allocate memory for periodic advertisers
*
* @param num_adv Number of advertisers to allocate
*/
sl_status_t sl_btctrl_alloc_periodic_adv(uint8_t num_adv);
/**
* Call to import the conn scheduler state variables in the binary
*/
void sli_btctrl_enable_conn_scheduler_state(void);
/**
* @brief Set maximum number of advertisement reports allowed to be queued
*
* @param num_adv Maximum number of advertisement reports allowed to be queued
*/
void sl_btctrl_configure_max_queued_adv_reports(uint8_t num_reports);
/**
* Call to enable the even connection scheduling algorithm.
* This function should be called before link layer initialization.
*/
void sl_btctrl_enable_even_connsch();
/**
* Call to enable the PAwR aware connection scheduling algorithm.
* This function should be called before link layer initialization.
*/
void sl_btctrl_enable_pawr_connsch();
/**
* Call to enable the legacy connection scheduling algorithm.
* This function should be called before link layer initialization.
*/
void sl_btctrl_enable_legacy_connsch();
/**
* Call to enable connection statistics collection.
*/
void sl_btctrl_init_conn_statistics(void);
/**
* Call to initialize multiprotocol
* in bluetooth controller
*/
void sl_btctrl_init_multiprotocol();
/**
* Link with symbol to enable radio watchdog
*/
void sl_btctrl_enable_radio_watchdog();
/**
* Initialize CTE receiver
*/
sl_status_t sl_btctrl_init_cte_receiver();
/**
* Initialize CTE transmitter
*/
sl_status_t sl_btctrl_init_cte_transmitter();
/**
* Initialize both CTE receiver and transmitter
*
* Note: This is for backward compatibility. It is recommend to
* use sl_btctrl_init_cte_receiver and sl_btctrl_init_cte_transmitter
* functions instead.
*/
sl_status_t sl_btctrl_init_cte();
/**
* Initialize Channel Sounding
*/
struct sl_btctrl_cs_config {
/** number of channel sounding configurations per connection */
uint8_t configs_per_connection;
/** number of simultaneous channel sounding procedures */
uint8_t procedures;
};
sl_status_t sl_btctrl_init_cs(const struct sl_btctrl_cs_config *config);
/**
* Check if event bitmap indicates pending events
* @return bool pending events
*/
bool sli_pending_btctrl_events(void);
/**
* Disable the support for Coded and Simulscan PHYs.
*/
void sl_btctrl_disable_coded_phy(void);
/**
* Disable the support for 2M PHY.
*/
void sl_btctrl_disable_2m_phy(void);
/**
* Initialize adv component
*/
void sl_btctrl_init_adv(void);
void sl_btctrl_init_conn(void);
void sl_btctrl_init_subrate(void);
sl_status_t sl_btctrl_allocate_conn_subrate_memory(uint8_t connectionsCount);
void sl_btctrl_init_phy(void);
void sl_btctrl_init_adv_ext(void);
void sl_btctrl_init_privacy(void);
sl_status_t sl_btctrl_allocate_resolving_list_memory(uint8_t resolvingListSize);
/**
* @brief Initialize extended scanner state
*
*/
void sl_btctrl_init_scan_ext(void);
void sl_btctrl_init_scan(void);
/**
* @brief return true if controller is initialized
*
*/
bool sl_btctrl_is_initialized();
/**
* @brief Sets PAST initiator feature bit,
* and links in PAST sender and ll_adv_sync symbols to the project.
*/
void sl_btctrl_init_past_local_sync_transfer(void);
/**
* @brief Sets PAST initiator feature bit,
* and links in PAST sender, ll_scan_sync and ll_scan_sync_registry symbols to the project.
*/
void sl_btctrl_init_past_remote_sync_transfer(void);
/**
* @brief Sets PAST receiver feature bit,
* and links in PAST receiver, ll_scan_sync and ll_scan_sync_registry symbols to the project.
*/
void sl_btctrl_init_past_receiver(void);
/**
* @brief Configure how often to send the Number Of Completed Packets HCI event.
* @param[in] packets When the controller has transmitted this number of ACL data packets it will send
* the Number Of Completed Packets HCI event to the host.
* @param[in] events When this number of connection events have passed and the controller did not yet report
* all the transmitted packets, then it will send the Number Of Completed Packets HCI event to the host.
*/
void sl_btctrl_configure_completed_packets_reporting(uint8_t packets, uint8_t events);
#endif

View File

@@ -0,0 +1,363 @@
/***************************************************************************//**
* @brief Silicon Labs BGAPI types and macros
*******************************************************************************
* # License
* <b>Copyright 2019-2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BGAPI_H
#define SL_BGAPI_H
#include <stdint.h>
#include <stddef.h>
#include "sl_status.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Macros to declare deprecated functions */
#if defined(__IAR_SYSTEMS_ICC__)
#define SL_BGAPI_DEPRECATED _Pragma("deprecated")
#elif defined(__GNUC__)
#define SL_BGAPI_DEPRECATED __attribute__((deprecated))
#else
#define SL_BGAPI_DEPRECATED
#endif
/* Compatibility */
#ifndef PACKSTRUCT
/*Default packed configuration*/
#ifdef __GNUC__
#ifdef _WIN32
#define PACKSTRUCT(decl) decl __attribute__((__packed__, gcc_struct))
#else
#define PACKSTRUCT(decl) decl __attribute__((__packed__))
#endif
#define ALIGNED __attribute__((aligned(0x4)))
#elif __IAR_SYSTEMS_ICC__
#define PACKSTRUCT(decl) __packed decl
#define ALIGNED
#elif _MSC_VER /*msvc*/
#define PACKSTRUCT(decl) __pragma(pack(push, 1) ) decl __pragma(pack(pop) )
#define ALIGNED
#else
#define PACKSTRUCT(a) a PACKED
#endif
#endif
/**
* The maximum BGAPI command payload size.
*/
#ifndef SL_BGAPI_MAX_PAYLOAD_SIZE
#define SL_BGAPI_MAX_PAYLOAD_SIZE 256
#endif
/***************************************************************************//**
* @addtogroup sl_bgapi_types BGAPI Types
* @brief Common types in BGAPI protocol
* @{
*/
#ifndef SL_BT_TYPE_UINT8ARRARY
#define SL_BT_TYPE_UINT8ARRARY
/** @brief Variable-length uint8_t array. Maximum length: 255 */
typedef struct {
uint8_t len; /**< Number of bytes stored in @p data */
uint8_t data[]; /**< Data bytes*/
} uint8array;
#endif
#ifndef SL_BT_TYPE_BYTE_ARRARY
#define SL_BT_TYPE_BYTE_ARRARY
/** @brief Variable-length int8_t array. Maximum length: 65535 */
typedef struct {
uint16_t len; /**< Number of bytes stored in @p data */
int8_t data[]; /**< Data bytes*/
} byte_array;
#endif
#ifndef SL_BT_TYPE_BDADDR
#define SL_BT_TYPE_BDADDR
/** @brief Bluetooth address */
typedef struct {
uint8_t addr[6]; /**< @brief Bluetooth address in reverse byte order */
} bd_addr;
#endif
#ifndef SL_BT_TYPE_UUID128
#define SL_BT_TYPE_UUID128
/** @brief 128-bit UUID */
typedef struct {
uint8_t data[16]; /**< 128-bit UUID */
} uuid_128;
#endif
#ifndef SL_BT_TYPE_AES_KEY128
#define SL_BT_TYPE_AES_KEY128
/** @brief 128-bit AES key */
typedef struct {
uint8_t data[16]; /**< 128-bit AES key */
} aes_key_128;
#endif
#ifndef SL_BT_TYPE_UUID16
#define SL_BT_TYPE_UUID16
/** @brief 16-bit UUID */
typedef struct {
uint8_t data[2]; /**< 16-bit UUID */
} sl_bt_uuid_16_t;
#endif
#ifndef SL_BT_TYPE_UUID64
#define SL_BT_TYPE_UUID64
/** @brief 64-bit UUID */
typedef struct {
uint8_t data[8]; /**< 64-bit UUID */
} sl_bt_uuid_64_t;
#endif
/** @} */ // end addtogroup sl_bgapi_types
/******************************************************************************/
/** @brief Internal function prototype for BGAPI command handlers */
typedef void (*sl_bgapi_handler)(const void*);
typedef enum sl_bgapi_msg_types {
sl_bgapi_msg_type_cmd = 0x00,
sl_bgapi_msg_type_rsp = 0x00,
sl_bgapi_msg_type_evt = 0x80
} sl_bgapi_msg_types_t;
enum sl_bgapi_dev_types {
sl_bgapi_dev_type_app = 0x00,
sl_bgapi_dev_type_bt = 0x20,
sl_bgapi_dev_type_btmesh = 0x28,
sl_bgapi_dev_type_bgapi_debug = 0x30,
};
/***************************************************************************//**
* @addtogroup sl_bgapi_types BGAPI Types
* @brief Common types in BGAPI protocol
* @{
*/
/**
* @brief The length of a BGAPI message header which is 4 bytes
*/
#define SL_BGAPI_MSG_HEADER_LEN (4)
/**
* @brief The length of the BGAPI message payload of a generic error response
*
* See function @ref sl_bgapi_set_error_response for how to generate a generic
* error response.
*/
#define SL_BGAPI_MSG_ERROR_PAYLOAD_LEN (2)
/**
* @brief Get the device type of a BGAPI message
*
* @param HDR The header of the message as a uint32_t integer
*/
#define SL_BGAPI_MSG_DEVICE_TYPE(HDR) ((HDR) & 0x38)
/**
* @brief Get the identifier of a BGAPI message including device type, class ID,
* message type and message ID.
*
* @param HDR The header of the message as a uint32_t integer
*/
#define SL_BGAPI_MSG_ID(HDR) ((HDR) & 0xffff00f8)
/**
* @brief Get the data payload length in a BGAPI message.
*
* @param HDR The header of the message as a uint32_t integer
*/
#define SL_BGAPI_MSG_LEN(HDR) ((((HDR) & 0x7) << 8) | (((HDR) & 0xff00) >> 8))
/**
* @brief The bit indicating whether data of a BGAPI message is encrypted
*/
#define SL_BGAPI_BIT_ENCRYPTED (1 << 6) // Bit
/**
* @brief Check whether data of a BGAPI message is encrypted.
*
* @param HDR The BGAPI header of the message as a uint32_t integer
*/
#define SL_BGAPI_MSG_ENCRYPTED(HDR) ((HDR)&SL_BGAPI_BIT_ENCRYPTED)
/**
* @brief Construct a BGAPI message header from an event ID and payload length.
*
* It is the caller's responsibility to verify that the input values are within
* valid range.
*
* @param[in] evt_id The full event ID constant, for example
* `sl_bt_evt_system_boot_id`
* @param[in] payload_len Length of the full BGAPI message payload
*
* @return The header as a `uint32_t` value
*/
#define SL_BGAPI_MSG_HEADER_FROM_ID_AND_LEN(evt_id, payload_len) \
((uint32_t) (((uint32_t) (evt_id)) \
| (((uint32_t) (payload_len) & 0x00FF) << 8) \
| (((uint32_t) (payload_len) & 0x0700) >> 8))) \
/** @} */ // end addtogroup sl_bgapi_types
/******************************************************************************/
/**
* @addtogroup sl_bgapi_functions BGAPI Functions
* @{
*
* @brief Functions provided by the BGAPI protocol
*/
/**
* @brief Lock the BGAPI for exclusive access.
*
* NOTE: This function is provided for NCP/CPC components that need to handle
* BGAPI commands and responses in their binary format in an application that
* uses an RTOS. Normal application code that issues BGAPI commands by calling
* API functions defined by protocol stacks must never call this function
* directly.
*
* See the documentation of @ref sl_bgapi_handle_command for the full sequence
* that must be followed when processing commands in their binary format.
*
* @return SL_STATUS_OK if the lock has been obtained, otherwise an error code
*/
sl_status_t sl_bgapi_lock(void);
/**
* @brief Release the lock obtained by @ref sl_bgapi_lock
*
* NOTE: This function is provided for NCP/CPC components that need to handle
* BGAPI commands and responses in their binary format in an application that
* uses an RTOS. Normal application code that issues BGAPI commands by calling
* API functions defined by protocol stacks must never call this function
* directly.
*
* See the documentation of @ref sl_bgapi_handle_command for the full sequence
* that must be followed when processing commands in their binary format.
*/
void sl_bgapi_unlock(void);
/**
* @brief Handle a BGAPI command in binary format.
*
* NOTE: This function is provided for NCP/CPC components that need to handle
* BGAPI commands and responses in their binary format. Normal application code
* that issues BGAPI commands by calling API functions defined by protocol
* stacks must never call this function directly.
*
* If the application uses an RTOS, the caller must protect the BGAPI handling
* by obtaining the BGAPI lock with @ref sl_bgapi_lock, handle the command with
* @ref sl_bgapi_handle_command, read the response from the buffer returned by
* @ref sl_bgapi_get_command_response, and then release the lock with @ref
* sl_bgapi_unlock. Here's an example of the full sequence that's required:
*
* @code
* // Lock BGAPI for exclusive access
* sl_status_t status = sl_bgapi_lock();
* if (status != SL_STATUS_OK) {
* // Locking will only fail if there are fatal unrecoverable errors with the
* // RTOS primitives, so caller may choose to just assert in case of errors.
* }
*
* // Process the command
* sl_bgapi_handle_command(hdr, data);
*
* // Read the response
* void *rsp = sl_bgapi_get_command_response();
* uint32_t rsp_header = *((uint32_t *)rsp);
* size_t rsp_len = SL_BGAPI_MSG_LEN(rsp_header) + SL_BGAPI_MSG_HEADER_LEN;
* // Send the `rsp_len` bytes of response starting from `rsp`
*
* // Finally unlock the BGAPI to allow other commands to proceed
* sl_bgapi_unlock();
* @endcode
*
* Empty stub implementations are provided for @ref sl_bgapi_lock and @ref
* sl_bgapi_unlock, so the same sequence can be used for all NCP/CPC
* implementations even if an RTOS is not present.
*
* @param[in] hdr The BGAPI command header
* @param[in] data The payload data associated with the command
*/
void sl_bgapi_handle_command(uint32_t hdr, const void* data);
/**
* @brief Get the response of a handled BGAPI command.
*
* NOTE: This function is provided for NCP/CPC components that need to handle
* BGAPI commands and responses in their binary format. Normal application code
* that issues BGAPI commands by calling API functions defined by protocol
* stacks must never call this function directly.
*
* See the documentation of @ref sl_bgapi_handle_command for the full sequence
* that must be followed when processing commands in their binary format.
*
* @return Pointer to the BGAPI response structure that was filled when the
* command was executed in @ref sl_bgapi_handle_command.
*/
void* sl_bgapi_get_command_response(void);
/**
* @brief Set a generic error response to the specified buffer.
*
* NOTE: This function is provided for NCP/CPC components that need to handle
* BGAPI commands and responses in their binary format. Normal application code
* that issues BGAPI commands by calling API functions defined by protocol
* stacks must never call this function directly.
*
* This function is available for NCP components that have detected fatal errors
* in command processing (for example have failed to receive a complete command
* message from the NCP host) and need to generate an error response without
* going through the normal BGAPI command processing.
*
* @param[in] command_hdr The header of the command that we are responding to.
* It is possible in certain types of failures that the NCP implementation
* does not even have the full command header. In these cases it is
* recommended that the NCP implementation sets the unavailable bytes of the
* header to value zero to avoid transmitting uninitialized bytes. BGAPI
* commands are processed one command at a time and the recipient will be able
* to handle the error response even if it's missing the device ID, the class
* ID, or the command ID.
*
* @param[in] result The value to set to the @p result field of the error
* response.
*
* @param[out] response The response buffer to fill
*
* @param[in] response_buf_size The size of the response buffer. The caller must
* provide a buffer that has at least @ref SL_BGAPI_MSG_HEADER_LEN + @ref
* SL_BGAPI_MSG_ERROR_PAYLOAD_LEN bytes available.
*/
void sl_bgapi_set_error_response(uint32_t command_hdr,
uint16_t result,
void *response,
size_t response_buf_size);
/** @} */ // end addtogroup sl_bgapi_functions
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
/***************************************************************************//**
* @brief BT API source code compatibility for deprecated items
*******************************************************************************
* # License
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BT_API_COMPATIBILITY_H
#define SL_BT_API_COMPATIBILITY_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Deprecated and replaced by sl_bt_gap_phy_t.
*/
typedef enum
{
sl_bt_gap_1m_phy = 0x1, /**< (0x1) 1M PHY */
sl_bt_gap_2m_phy = 0x2, /**< (0x2) 2M PHY */
sl_bt_gap_coded_phy = 0x4, /**< (0x4) Coded PHY, 125k (S=8) or 500k (S=2) */
sl_bt_gap_any_phys = 0xff /**< (0xff) Any PHYs the device supports */
} sl_bt_gap_phy_type_t;
/**
* Deprecated and replaced by sl_bt_gap_phy_coding_t.
*/
typedef enum
{
sl_bt_gap_1m_phy_uncoded = 0x1, /**< (0x1) 1M PHY */
sl_bt_gap_2m_phy_uncoded = 0x2, /**< (0x2) 2M PHY */
sl_bt_gap_coded_phy_125k = 0x4, /**< (0x4) 125k Coded PHY (S=8) */
sl_bt_gap_coded_phy_500k = 0x8 /**< (0x8) 500k Coded PHY (S=2) */
} sl_bt_gap_phy_and_coding_type_t;
/**
* Deprecated and replaced by sl_bt_legacy_advertiser_connection_mode_t and
* sl_bt_extended_advertiser_connection_mode_t.
*/
typedef enum
{
sl_bt_advertiser_non_connectable = 0x0, /**< (0x0) Non-connectable
non-scannable */
sl_bt_advertiser_connectable_scannable = 0x2, /**< (0x2) Undirected
connectable scannable.
This mode can only be
used in legacy
advertising PDUs. */
sl_bt_advertiser_scannable_non_connectable = 0x3, /**< (0x3) Undirected
scannable
(Non-connectable but
responds to scan
requests) */
sl_bt_advertiser_connectable_non_scannable = 0x4 /**< (0x4) Undirected
connectable
non-scannable. This
mode can only be used
in extended advertising
PDUs. */
} sl_bt_advertiser_connection_mode_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,82 @@
/***************************************************************************//**
* @brief Bluetooth Link Layer configuration
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 SL_BT_BLUETOOTH_LL_PRIORITIES_DEFINED
#define SL_BT_BLUETOOTH_LL_PRIORITIES_DEFINED
typedef struct {
uint8_t scan_min;
uint8_t scan_max;
uint8_t adv_min;
uint8_t adv_max;
uint8_t conn_min;
uint8_t conn_max;
uint8_t init_min;
uint8_t init_max;
uint8_t rail_mapping_offset;
uint8_t rail_mapping_range;
uint8_t _reserved;
uint8_t adv_step;
uint8_t scan_step;
uint8_t pawr_tx_min;
uint8_t pawr_tx_max;
uint8_t pawr_rx_min;
uint8_t pawr_rx_max;
} sl_bt_bluetooth_ll_priorities;
//Default priority configuration
#define SL_BT_BLUETOOTH_PRIORITIES_DEFAULT { 191, 143, 175, 127, 135, 0, 55, 15, 16, 16, 0, 4, 4, 15, 5, 20, 10 }
#define SL_BT_BLUETOOTH_PA_AUTOMODE 0xff
#define SL_BT_BLUETOOTH_HIGHEST_PA 0xfe
#define SL_BT_BLUETOOTH_RAIL_UTIL_PA 0xfd
#include "sl_common.h"
SL_PACK_START(1)
typedef struct {
int8_t golden_rssi_min_1m; //<! Golden range lowest RSSI for 1M PHY.
int8_t golden_rssi_max_1m; //<! Golden range highest RSSI for 1M PHY.
int8_t golden_rssi_min_2m; //<! Golden range lowest RSSI for 2M PHY.
int8_t golden_rssi_max_2m; //<! Golden range highest RSSI for 2M PHY.
int8_t golden_rssi_min_coded_s8; //<! Golden range lowest RSSI for Coded PHY w/ S=8.
int8_t golden_rssi_max_coded_s8; //<! Golden range highest RSSI for Coded PHY w/ S=8.
int8_t golden_rssi_min_coded_s2; //<! Golden range lowest RSSI for Coded PHY w/ S=2.
int8_t golden_rssi_max_coded_s2; //<! Golden range highest RSSI for Coded PHY w/ S=2.
uint8_t activate_power_control;
} SL_ATTRIBUTE_PACKED sl_bt_ll_power_control_config_t;
SL_PACK_END()
#define SL_BT_USE_MAX_POWER_LEVEL_SUPPORTED_BY_RADIO 0x7fff
#define SL_BT_USE_MIN_POWER_LEVEL_SUPPORTED_BY_RADIO 0x7fff
#endif

View File

@@ -0,0 +1,150 @@
/***************************************************************************//**
* @file
* @brief Adaptation for running Bluetooth in RTOS
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BT_RTOS_ADAPTATION_H
#define SL_BT_RTOS_ADAPTATION_H
#include "sl_bt_api.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup bluetooth_rtos_adaptation Bluetooth RTOS adaptation
* @{
*
* @brief Bluetooth RTOS adaptation
*
* The Bluetooth RTOS adaptation component implements the relevant interfaces
* for running the Bluetooth stack in an RTOS. The component creates the
* required RTOS synchronization primitives and tasks for the Bluetooth stack
* and handles the inter-process communication (IPC) required when the
* application calls a BGAPI command.
*
* If the Bluetooth Event System IPC component (`bluetooth_event_system_ipc`) is
* included in the application, Bluetooth events are delivered using the IPC
* mechanism provided by the `event_system` component. See @ref
* bluetooth_event_system for the description of that mechanism. In this
* configuration no event task is created by the RTOS adaptation.
*
* If the Bluetooth Event System IPC component (`bluetooth_event_system_ipc`) is
* not included in the application, the RTOS adaptation component creates an
* event task that delivers the events to the application as direct callbacks to
* sl_bt_process_event() and sl_bt_on_event() functions.
*
* To guarantee thread safety and avoid the risk of deadlocks, the Bluetooth
* RTOS adaptation implementation makes the following promises with regard to
* the locking mechanism provided in the API:
*
* 1. The stack will never directly call sl_bt_process_event() or
* sl_bt_on_event() from within the same callstack that is calling a command
* function. The callbacks always come from a processing loop in an event
* task created for this purpose.
*
* 2. The stack uses @ref sl_bgapi_lock() and @ref sl_bgapi_unlock() to
* synchronize the handling of individual BGAPI commands, and the application
* must never directly call these. Individual BGAPI commands are safe to be
* called from multiple threads without additional locking. See @ref
* sl_bt_bluetooth_pend() for description of when an application needs to use
* additional locking to guarantee atomicity across multiple commands.
*
* 3. The stack will never internally obtain the @ref sl_bt_bluetooth_pend()
* lock. It is safe for the application to obtain the lock also from within
* the sl_bt_on_event() callback.
*/
/**
* @brief Initialize Bluetooth RTOS Adaptation
*
* This function is called automatically at the right time in the generated
* initialization sequence. The application does not need to and must not call
* this function directly.
*
* @return SL_STATUS_OK if succeeds, otherwise error
*/
sl_status_t sl_bt_rtos_init();
/**
* @brief Obtain the Bluetooth host stack command lock
*
* Starting from Gecko SDK v3.1.2, all BGAPI command functions have automatic
* locking to make them thread-safe. Using @ref sl_bt_bluetooth_pend() and @ref
* sl_bt_bluetooth_post() is therefore no longer required for individual calls
* to the BGAPI.
*
* The application only needs to use @ref sl_bt_bluetooth_pend() and @ref
* sl_bt_bluetooth_post() to protect sections of code where multiple commands
* need to be performed atomically in a thread-safe manner. This includes cases
* such as using @ref sl_bt_system_data_buffer_write() to write data to the
* system buffer followed by a call to @ref
* sl_bt_extended_advertiser_set_long_data() to set that data to an advertiser
* set. To synchronize access to the shared system buffer, the application would
* need to lock by calling @ref sl_bt_bluetooth_pend() before @ref
* sl_bt_system_data_buffer_write(), and release the lock by calling @ref
* sl_bt_bluetooth_post() after @ref sl_bt_extended_advertiser_set_long_data().
*
* @return SL_STATUS_OK if mutex has been obtained
*/
sl_status_t sl_bt_bluetooth_pend();
/**
* @brief Release the Bluetooth host stack command lock
*
* See @ref sl_bt_bluetooth_pend() for description of how an application needs
* to use the locking to guarantee thread-safety.
*
* @return SL_STATUS_OK the mutex has been released
*/
sl_status_t sl_bt_bluetooth_post();
/** @cond DOXYGEN_INCLUDE_INTERNAL */
/**
* @brief Hooks for API, called from tasks using Bluetooth API
*/
void sli_bt_cmd_handler_rtos_delegate(uint32_t header, sl_bgapi_handler handler, const void* payload);
/**
* @brief Called by Bluetooth stack to wake up the link layer task
*/
void sli_bt_rtos_ll_callback(void);
/**
* @brief Called by Bluetooth stack to wake up the host stack task
*/
void sli_bt_rtos_stack_callback(void);
/**
* @brief Called by system initialization when kernel is starting.
*/
void sli_bt_rtos_adaptation_kernel_start();
/**
* @brief Called by Bluetooth Event System IPC to mark an event as handled
*/
void sli_bt_rtos_set_event_handled();
/** @endcond */ // DOXYGEN_INCLUDE_INTERNAL
/** @} end bluetooth_rtos_adaptation */
#ifdef __cplusplus
}
#endif
#endif //SL_BT_RTOS_ADAPTATION_H

View File

@@ -0,0 +1,86 @@
/***************************************************************************//**
* @brief Bluetooth stack configuration
*******************************************************************************
* # License
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BT_STACK_CONFIG_H
#define SL_BT_STACK_CONFIG_H
#include <stdint.h>
#include "sl_bt_ll_config.h"
typedef struct {
uint32_t max_buffer_memory; //!< Maximum number of bytes to use for data buffers
uint32_t linklayer_config;
sl_bt_bluetooth_ll_priorities * linklayer_priorities; //Priority configuration, if NULL uses default values
}sl_bt_stack_config_t;
/** Flag indicating Bluetooth runs in RTOS */
#define SL_BT_CONFIG_FLAG_RTOS 256
/** Flag indicating Bluetooth can allow EM2 with inaccurate LF clock */
#define SL_BT_CONFIG_FLAG_INACCURATE_LFCLK_EM2 512
/**
* <b>Deprecated</b> and replaced by @ref sli_bt_linklayer_wakeup_t implemented
* by the bluetooth_host_adaptation component.
*/
typedef void (*sl_bt_priority_schedule_callback)(void);
/**
* <b>Deprecated</b> and replaced by @ref sli_bt_host_wakeup_t implemented
* by the bluetooth_host_adaptation component.
*/
typedef void (*sl_bt_stack_schedule_callback)(void);
#define SL_BT_RF_CONFIG_ANTENNA (1 << 0)
typedef struct {
int16_t tx_gain; // RF TX gain. Unit: 0.1 dBm. For example, -20 means -2.0 dBm (signal loss).
int16_t rx_gain; // RF RX gain. Unit: 0.1 dBm.
uint8_t flags; // bit 0 is enabling antenna config, other bits 1-7 are reserved.
uint8_t antenna; // A configuration for antenna selection.
// Value should be come from RAIL_AntennaSel_t enum.
// See antenna path selection in RAIL rail_chip_specific.h.
int16_t tx_min_power; // Minimum TX power level. Unit: 0.1 dBm.
int16_t tx_max_power; // Maximum TX power level. Unit: 0.1 dBm.
} sl_bt_rf_config_t;
typedef struct {
uint32_t config_flags;
sl_bt_stack_config_t bluetooth;
// GATT database (pointer of "sli_bt_gattdb_t*" type)
const void* gattdb;
/**
* <b>Deprecated</b> and replaced by @ref sli_bt_host_adaptation_linklayer_wakeup
* implemented by the bluetooth_host_adaptation component.
*
* Callback for priority scheduling, used for RTOS support.
*/
sl_bt_priority_schedule_callback scheduler_callback;
/**
* <b>Deprecated</b> and replaced by @ref sli_bt_host_adaptation_host_wakeup
* implemented by the bluetooth_host_adaptation component.
*
* Callback for requesting Bluetooth stack scheduling, used for RTOS support.
*/
sl_bt_stack_schedule_callback stack_schedule_callback;
uint8_t max_timers; // Max number of soft timers, up to 16, the application will use through SL_BT_API. Default: 4
sl_bt_rf_config_t rf;
}sl_bt_configuration_t;
#endif

View File

@@ -0,0 +1,38 @@
/***************************************************************************//**
* @brief Initialization APIs for Bluetooth stack
*******************************************************************************
* # License
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BT_STACK_INIT_H
#define SL_BT_STACK_INIT_H
#include "sl_status.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize the Bluetooth stack.
*
* @return SL_STATUS_OK if the initialization was successful; Other error code
* indicates a failure.
*/
sl_status_t sl_bt_stack_init();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,22 @@
/***************************************************************************//**
* @brief Deprecated Bluetooth API data type header
*******************************************************************************
* # License
* <b>Copyright 2019-2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
/*
* "sl_bt_types.h" is deprecated and replaced by "sl_bt_api.h". We include
* "sl_bt_api.h" here to maintain source code compatibility with files that only
* include "sl_bt_types.h".
*/
#include "sl_bt_api.h"

View File

@@ -0,0 +1,84 @@
/***************************************************************************//**
* @brief Bluetooth stack version definition
*******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SL_BT_VERSION_H
#define SL_BT_VERSION_H
/***************************************************************************//**
* @addtogroup sl_bt_version Bluetooth SDK version
* @brief Bluetooth SDK version information
* @{
*/
/**
* @brief The major number of Bluetooth SDK version
*
* An increment indicates incompatible Bluetooth API changes.
*/
#define SL_BT_VERSION_MAJOR 9
/**
* @brief The minor number of Bluetooth SDK version
*
* An increment indicates new backwards compatible functionalities.
*/
#define SL_BT_VERSION_MINOR 0
/**
* @brief The patch number of Bluetooth SDK version
*
* An increment indicates backwards compatible bug fixes.
*/
#define SL_BT_VERSION_PATCH 1
/**
* @brief The build number which the Bluetooth SDK was created from
*/
#define SL_BT_VERSION_BUILD 341
/**
* @brief The hash value of the build the Bluetooth SDK was created from
*/
#define SL_BT_VERSION_HASH {0x4d,0x9c,0xee,0x3e,0x47,0x47,0x76,0xad,0x6d,0x0c,0xc3,0x0c,0xe5,0x8c,0x68,0x88,0xd9,0xd6,0x50,0xd4}
/**
* Deprecated and replaced by SL_BT_VERSION_MAJOR
*/
#define BG_VERSION_MAJOR SL_BT_VERSION_MAJOR
/**
* Deprecated and replaced by SL_BT_VERSION_MINOR
*/
#define BG_VERSION_MINOR SL_BT_VERSION_MINOR
/**
* Deprecated and replaced by SL_BT_VERSION_PATCH
*/
#define BG_VERSION_PATCH SL_BT_VERSION_PATCH
/**
* Deprecated and replaced by SL_BT_VERSION_BUILD
*/
#define BG_VERSION_BUILD SL_BT_VERSION_BUILD
/**
* Deprecated and replaced by SL_BT_VERSION_HASH
*/
#define BG_VERSION_HASH SL_BT_VERSION_HASH
/** @} */ // end addtogroup sl_bt_version
#endif

View File

@@ -0,0 +1,107 @@
/***************************************************************************//**
* @brief Silicon Labs internal API provided by the BGAPI protocol
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BGAPI_H
#define SLI_BGAPI_H
#include "sl_status.h"
#include "sl_bgapi.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @cond DOXYGEN_INCLUDE_INTERNAL */
/***************************************************************************//**
* @addtogroup sli_bgapi BGAPI Protocol internal API
* @{
*
* @brief Silicon Labs internal API to the BGAPI Protocol
*
* The BGAPI Protocol provides some services that are needed internally by
* Silicon Labs components. The APIs provided by this file must not be used by
* application code.
*/
// -----------------------------------------------------------------------------
// Silicon Labs internal types for the BGAPI protocol
/**
* @brief Type definition for the command handler delegate function.
*
* The command handler delegate is used by the BGAPI protocol to handle a
* command. The default delegate @ref sli_bgapi_cmd_handler_delegate executes
* the BGAPI command handler function as a direct function call. The RTOS
* adaptation uses @ref sli_bgapi_set_cmd_handler_delegate to set a special
* delegate that handles the required inter-process communication (IPC) when an
* RTOS is used.
*
* @param[in] header The BGAPI command header of the command to process
* @param[in] handler The handler function to process the BGAPI command
* @param[in] payload The BGAPI command payload data of the command to process
*/
typedef void sli_bgapi_cmd_handler_delegate_t (uint32_t header,
sl_bgapi_handler handler,
const void* payload);
#define SLI_BGAPI_BUFFER_SIZE (SL_BGAPI_MSG_HEADER_LEN + SL_BGAPI_MAX_PAYLOAD_SIZE)
/**
* @brief The default command handler delegate function.
*/
sli_bgapi_cmd_handler_delegate_t sli_bgapi_cmd_handler_delegate;
// -----------------------------------------------------------------------------
// Silicon Labs internal functions to control the BGAPI protocol
/**
* @brief Set the BGAPI command handler delegate.
*
* @param[in] cmd_handler_delegate Pointer to the command handler delegate function
*/
void sli_bgapi_set_cmd_handler_delegate(sli_bgapi_cmd_handler_delegate_t *cmd_handler_delegate);
/**
* @brief Pop an event out of the BGAPI event queue of a specific device.
*
* @param[in] dev_type The BGAPI device to pop events from
* @param[in] event_buffer_size The size of the supplied event buffer
* @param[out] event_buffer The event buffer to receive the popped event
*
* @return SL_STATUS_OK if successful, otherwise an error code
*/
sl_status_t sli_bgapi_pop_event(uint8_t dev_type,
size_t event_buffer_size,
void *event_buffer);
/**
* @brief Set the BGAPI command/response buffer.
*
* @param[in] buffer The buffer to use for BGAPI command/response data
* @return The previous buffer
*/
void *sli_bgapi_set_buffer(void *buffer);
/** @} end sli_bgapi */
/** @endcond */ // DOXYGEN_INCLUDE_INTERNAL
#ifdef __cplusplus
}
#endif
#endif // SLI_BGAPI_H

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file
* @brief Configuration types for "accept_list"
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_ACCEPT_LIST_CONFIG_H
#define SLI_BT_ACCEPT_LIST_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "accept_list"
*
* See "sl_bt_accept_list_config.h" for detailed description of each
* configuration parameter.
*/
typedef struct {
uint8_t accept_list_size; ///< Set to value of SL_BT_CONFIG_ACCEPT_LIST_SIZE
} sli_bt_accept_list_config_t;
#endif // SLI_BT_ACCEPT_LIST_CONFIG_H

View File

@@ -0,0 +1,30 @@
/***************************************************************************//**
* @file sli_bt_advertiser_config.h
* @brief Configuration types for "advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_ADVERTISER_CONFIG_H
#define SLI_BT_ADVERTISER_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "advertiser"
*/
typedef struct {
uint8_t max_advertisers; ///< Set to value of SL_BT_CONFIG_MAX_ADVERTISERS
} sli_bt_advertiser_config_t;
#endif // SLI_BT_ADVERTISER_CONFIG_H

View File

@@ -0,0 +1,216 @@
/***************************************************************************//**
* @brief Internal types and defines for Bluetooth configuration
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_CONFIG_DEFS_H
#define SLI_BT_CONFIG_DEFS_H
#include "sl_status.h"
/** @brief Forward declaration of the internal feature structure */
struct sli_bt_feature;
/** @brief Forward declaration of the internal BGAPI class structure */
struct sli_bgapi_class;
/**
* @brief Forward declaration of internal feature config structure
*
* Note that this is only used as an opaque type that is never instantiated
* directly. The actual configuration structure is defined and populated in
* feature-specific files.
*/
struct sli_bt_feature_config;
/** @brief Structure to specify the use of a feature and its configuration */
struct sli_bt_feature_use {
const struct sli_bt_feature *feature; /**< Pointer to the feature definition */
const struct sli_bt_feature_config *config; /**< Pointer to the feature-specific configuration */
};
/**
* @brief Macro that expands to the name of a BGAPI class structure
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] class_name Short class name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_BGAPI_CLASS_NAME(category_name, class_name, mode) \
sli_bgapi_class_ ## category_name ## _ ## class_name ## _ ## mode
/**
* @brief Macro to forward declare a BGAPI class structure
*/
#define SLI_BT_DECLARE_BGAPI_CLASS(category_name, class_name) \
extern const struct sli_bgapi_class SLI_BT_BGAPI_CLASS_NAME(category_name, class_name, full); \
extern const struct sli_bgapi_class SLI_BT_BGAPI_CLASS_NAME(category_name, class_name, optimized)
#ifdef SL_BT_API_FULL
/**
* @brief Macro to declare the use of a BGAPI class
*
* This macro is used by stack-specific initialization code to declare the use
* of a BGAPI class in the array of used BGAPI classes.
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] class_name Short class name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_USE_BGAPI_CLASS(category_name, class_name) \
& SLI_BT_BGAPI_CLASS_NAME(category_name, class_name, full)
#else
#define SLI_BT_USE_BGAPI_CLASS(category_name, class_name) \
& SLI_BT_BGAPI_CLASS_NAME(category_name, class_name, optimized)
#endif
/**
* @brief Macro that expands to the name of a feature definition structure
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
* @param[in] init_mode Feature initialization mode without quotes: init_always
* or on_demand
*/
#define SLI_BT_FEATURE_DEFINITION_NAME(category_name, feature_name, init_mode) \
sli_feature_ ## category_name ## _ ## feature_name ## _ ## init_mode
/**
* @brief Macro that expands to the name of a feature configuration structure
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_FEATURE_CONFIG_NAME(category_name, feature_name) \
sli_feature_ ## category_name ## _ ## feature_name ## _config
/**
* @brief Macro to forward declare a feature definition structure
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_DECLARE_FEATURE(category_name, feature_name) \
extern const struct sli_bt_feature SLI_BT_FEATURE_DEFINITION_NAME(category_name, feature_name, init_always); \
extern const struct sli_bt_feature SLI_BT_FEATURE_DEFINITION_NAME(category_name, feature_name, on_demand)
/**
* @brief Macro to forward declare an instance of a feature configuration structure
*
* This macro is used by stack-specific initialization code to declare relevant
* configuration structures before populating the array of optional features.
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_DECLARE_FEATURE_CONFIG(category_name, feature_name) \
extern const struct sli_bt_feature_config SLI_BT_FEATURE_CONFIG_NAME(category_name, feature_name)
/**
* @brief Macro to define an instance of a feature configuration structure
*
* This macro is used by the internal feature-specific configuration files
* `sli_bt_*_config.c` to define an instance of the feature configuration
* structure. The intended use is to assign the value directly. For example:
*
* @code
* SLI_BT_DEFINE_FEATURE_CONFIG(bt, advertiser, sli_bt_advertiser_config_t) = {
* .max_advertisers = SL_BT_CONFIG_MAX_ADVERTISERS
* };
* @endcode
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
* @param[in] type The C language type of the configuration, for example
* sli_bt_advertiser_config_t
*/
#define SLI_BT_DEFINE_FEATURE_CONFIG(category_name, feature_name, type) \
const type SLI_BT_FEATURE_CONFIG_NAME(category_name, feature_name)
/**
* @brief Internal helper to implement @ref SLI_BT_USE_FEATURE
*
* This macro provides the extra layer of indirection that's needed to expand
* `SLI_BT_INIT_MODE` before it's used as a parameter to @ref
* SLI_BT_FEATURE_DEFINITION_NAME(). Files that define feature uses should
* invoke @ref SLI_BT_USE_FEATURE() instead of this helper.
*/
#define SLI_BT_USE_FEATURE_MODE(category_name, feature_name, init_mode) \
{ &SLI_BT_FEATURE_DEFINITION_NAME(category_name, feature_name, init_mode), NULL }
/**
* @brief Macro to declare the use of an optional feature that has no configuration
*
* This macro is used by stack-specific initialization code to declare the use
* of a feature in the array of optional features.
*
* Files that invoke this macro must define `SLI_BT_INIT_MODE` to either
* init_always or on_demand to decide the initialization mode of all features.
* When the init_always mode is used, the de-init functions are omitted to
* eliminate code that's not needed in the build.
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
*/
#define SLI_BT_USE_FEATURE(category_name, feature_name) \
SLI_BT_USE_FEATURE_MODE(category_name, feature_name, SLI_BT_INIT_MODE)
/**
* @brief Internal helper to implement @ref SLI_BT_USE_FEATURE_WITH_CONFIG
*
* This macro provides the extra layer of indirection that's needed to expand
* `SLI_BT_INIT_MODE` before it's used as a parameter to @ref
* SLI_BT_FEATURE_DEFINITION_NAME(). Files that define feature uses should
* invoke @ref SLI_BT_USE_FEATURE_WITH_CONFIG() instead of this helper.
*/
#define SLI_BT_USE_FEATURE_MODE_WITH_CONFIG(category_name, feature_name, init_mode, config_name) \
{ &SLI_BT_FEATURE_DEFINITION_NAME(category_name, feature_name, init_mode), &config_name }
/**
* @brief Macro to declare the use of an optional feature with configuration
*
* This macro is used by stack-specific initialization code to declare the use
* of a feature in the array of optional features.
*
* Files that invoke this macro must define `SLI_BT_INIT_MODE` to either
* init_always or on_demand to decide the initialization mode of all features.
* When the init_always mode is used, the de-init functions are omitted to
* eliminate code that's not needed in the build.
*
* @param[in] category_name Short category name string without quotes, for
* example bt, btmesh, or btctrl
* @param[in] feature_name Short feature name string without quotes, for example
* advertiser or connection
* @param[in] config_name The name of the configuration structure. The caller
* should use @ref SLI_BT_FEATURE_CONFIG_NAME() to get the name of the
* configuration structure.
*/
#define SLI_BT_USE_FEATURE_WITH_CONFIG(category_name, feature_name, config_name) \
SLI_BT_USE_FEATURE_MODE_WITH_CONFIG(category_name, feature_name, SLI_BT_INIT_MODE, config_name)
#endif // SLI_BT_CONFIG_DEFS_H

View File

@@ -0,0 +1,31 @@
/***************************************************************************//**
* @file sli_bt_connection_config.h
* @brief Configuration types for "connection"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_CONNECTION_CONFIG_H
#define SLI_BT_CONNECTION_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "connection"
*/
typedef struct {
uint8_t max_connections; ///< Set to value of SL_BT_CONFIG_MAX_CONNECTIONS_SUM
uint16_t data_len; ///< Set to value of SL_BT_CONFIG_CONNECTION_DATA_LENGTH
} sli_bt_connection_config_t;
#endif // SLI_BT_CONNECTION_CONFIG_H

View File

@@ -0,0 +1,30 @@
/***************************************************************************//**
* @file sli_bt_dynamic_gattdb_config.h
* @brief Configuration types for "dynamic_gattdb"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_DYNAMIC_GATTDB_CONFIG_H
#define SLI_BT_DYNAMIC_GATTDB_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "dynamic_gattdb"
*/
typedef struct {
uint8_t max_dynamic_gattdbs; ///< Set to value of SL_BT_CONFIG_MAX_DYNAMIC_GATTDBS_SUM
} sli_bt_dynamic_gattdb_config_t;
#endif // SLI_BT_DYNAMIC_GATTDB_CONFIG_H

View File

@@ -0,0 +1,108 @@
/***************************************************************************//**
* @brief Bluetooth GATT database structure definition
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_GATT_DEF_H
#define SLI_BT_GATT_DEF_H
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint16_t len; //size of buffer
uint8_t data[];
} sli_bt_gattdb_value_t;
typedef struct {
uint8_t properties; //Characteristic properties, same as in characteristic descriptor gatt_char_prop
uint16_t max_len; //Maximum length of data in buffer
uint16_t len; //current size of data in buffer
uint8_t data[]; //size is max_len
} sli_bt_gattdb_attribute_chrvalue_t;
typedef struct {
uint8_t flags; //client characteristic flags allowed 1-notification, 2-indication)
uint8_t clientconfig_index; // index to client config.
} sli_bt_gattdb_attribute_config_t;
typedef struct {
uint8_t properties; //Characteristic properties, same as in characteristic descriptor gatt_char_prop
uint16_t char_uuid; // characteristic UUID handle
} sli_bt_gattdb_attribute_characteristic_t;
typedef struct {
uint16_t start; //Included Service Attribute Handle
uint16_t end; //End Group Handle
} sli_bt_gattdb_attribute_service_include_t;
typedef struct {
uint16_t handle;
uint16_t uuid;
uint16_t permissions; //gatt_attribute_permission
uint16_t caps; // Capability bit flags
uint8_t datatype; //Just use uint8_t Do not use enum type, may cause compatibility troubles
uint8_t state;
union {
const sli_bt_gattdb_value_t *constdata; //generic constant data
sli_bt_gattdb_attribute_chrvalue_t *dynamicdata; //Modifiable data
sli_bt_gattdb_attribute_config_t configdata;
sli_bt_gattdb_attribute_characteristic_t characteristic;
sli_bt_gattdb_attribute_service_include_t service_include;
};
} sli_bt_gattdb_attribute_t;
struct sli_bt_gattdb_s {
const sli_bt_gattdb_attribute_t *attributes;
uint16_t attribute_table_size;
uint16_t attribute_num;
const uint16_t *uuid16;
uint16_t uuid16_table_size;
uint16_t uuid16_num;
const uint8_t *uuid128;
uint16_t uuid128_table_size;
uint16_t uuid128_num;
uint8_t num_ccfg;
uint16_t caps_mask;
uint16_t enabled_caps;
};
typedef struct sli_bt_gattdb_s sli_bt_gattdb_t;
extern const sli_bt_gattdb_t *static_gattdb;
/**
* @addtogroup dynamic_gatt_config
*
* Dynamic GATT database configuration.
*/
/**
* Flag indicating GATT caching should be enabled. When enabled, a Generic
* Attribute Profile Service will be created in database if one doesn't exist.
**/
#define SLI_BT_GATTDB_CONFIG_FLAG_ENABLE_GATT_CACHING (0x01)
/**
* Flag indicating the static database should be included if one exists.
*/
#define SLI_BT_GATTDB_CONFIG_FLAG_INCLUDE_STATIC_DB (0X02)
typedef struct {
uint32_t flags;
} sli_bt_gattdb_config_t;
/** @} (end addtogroup dynamic_gatt_config) */
#endif

View File

@@ -0,0 +1,127 @@
/***************************************************************************//**
* @brief System adaptation layer used internally by Bluetooth host stack
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_HOST_ADAPTATION_H
#define SLI_BT_HOST_ADAPTATION_H
#include <stdint.h>
#include "sl_status.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup sli_bt_host_adaptation
* @{
*
* @brief System adaptation layer used internally by Bluetooth host stack
*
* The functions provided by this file are used by the Bluetooth host stack to
* perform operations that cannot be performed using device-agnostic APIs from
* within the Bluetooth libraries. These are typically operations that depend on
* the target device or the Platform configuration. The application does not
* need to and must not call these functions directly.
*
******************************************************************************/
/**
* @brief Function prototype for waking up the Bluetooth link layer task
*/
typedef void sli_bt_linklayer_wakeup_t (void);
/**
* @brief Function prototype for waking up the Bluetooth host task
*/
typedef void sli_bt_host_wakeup_t (void);
/**
* @brief Pointer to the function that wakes up the Bluetooth linklayer task
*/
extern sli_bt_linklayer_wakeup_t *const sli_bt_host_adaptation_linklayer_wakeup;
/**
* @brief Pointer to the function that wakes up the Bluetooth host task
*/
extern sli_bt_host_wakeup_t *const sli_bt_host_adaptation_host_wakeup;
/**
* @brief Initialize the device interrupts in a baremetal app
*
* This is called once during the boot time initialization.
*/
void sli_bt_host_adaptation_init_interrupts(void);
/**
* @brief Get the bootloader version information
*
* @param[out] bootloader_version Set to the bootloader version number if a
* bootloader is available
*
* @return SL_STATUS_OK if a bootloader is available and the version was
* obtained. SL_STATUS_NOT_AVAILABLE if the application does not use a
* bootloader.
*/
sl_status_t sli_bt_host_adaptation_get_bootloader_version(uint32_t *bootloader_version);
/**
* @brief Reset the chip
*
* This function never returns.
*/
void sli_bt_host_adaptation_chip_reset(void);
/**
* @brief Write a custom Bluetooth identity address into the Bluetooth region of NVM3
*
* @param[in] address_type Address type sl_bt_gap_public_address or sl_bt_gap_static_address
* @param[in] address Pointer to the address to write into NVM3
* @return SL_STATUS_OK if the operation succeeded
*/
sl_status_t sli_bt_host_adaptation_write_custom_address(uint8_t address_type,
const uint8_t *address);
/**
* @brief Load custom Bluetooth identity address from NVM3
*
* The operation succeeds if both the custom address and address type entries exist in NVM3.
*
* @param[out] address_type Pointer to return the address type value read from NVM3. Value 0
* indicates the address is a public device address, and 1 indicates the address
* is a static device address.
* @param[out] address Pointer to return the address read from NVM3
* @return SL_STATUS_OK if the operation succeeded
*/
sl_status_t sli_bt_host_adaptation_read_custom_address(uint8_t *address_type,
uint8_t *address);
/**
* @brief Set HFXO CTUNE using the value stored in the Bluetooth space of NVM3
*
* Setting the HFXO CTUNE with this method is deprecated. Currently the functionality is
* provided for keeping backwards compatibility with legacy SDKs, and the support will be
* discontinued in future SDK releases. The recommended method is to store CTUNE value in the
* MFG_CTUNE token.
*/
void sli_bt_host_adaptation_read_and_set_ctune();
/** @} end sli_bt_host_adaptation */
#ifdef __cplusplus
}
#endif
#endif // SLI_BT_HOST_ADAPTATION_H

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file sli_bt_l2cap_config.h
* @brief Configuration types for "l2cap"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_L2CAP_CONFIG_H
#define SLI_BT_L2CAP_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "l2cap"
*
* See "sl_bluetooth_l2cap_config.h" for detailed description of each
* configuration parameter.
*/
typedef struct {
uint8_t max_l2cap_coc_channels; ///< Set to value of SL_BT_CONFIG_USER_L2CAP_COC_CHANNELS
} sli_bt_l2cap_config_t;
#endif // SLI_BT_L2CAP_CONFIG_H

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file sli_bt_pawr_advertiser_config.h
* @brief Configuration types for "pawr_advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_PAWR_ADVERTISER_CONFIG_H
#define SLI_BT_PAWR_ADVERTISER_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "pawr_advertiser"
*
* See "sl_bt_pawr_advertiser_config.h" for detailed description of each
* configuration parameter.
*/
typedef struct {
uint8_t max_pawr_advertisers; ///< Set to value of SL_BT_CONFIG_MAX_PAWR_ADVERTISERS
} sli_bt_pawr_advertiser_config_t;
#endif // SLI_BT_PAWR_ADVERTISER_CONFIG_H

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file sli_bt_periodic_advertiser_config.h
* @brief Configuration types for "periodic_advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_PERIODIC_ADVERTISER_CONFIG_H
#define SLI_BT_PERIODIC_ADVERTISER_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "periodic_advertiser"
*
* See "sl_bt_periodic_advertiser_config.h" for detailed description of each
* configuration parameter.
*/
typedef struct {
uint8_t max_periodic_advertisers; ///< Set to value of SL_BT_CONFIG_MAX_PERIODIC_ADVERTISERS
} sli_bt_periodic_advertiser_config_t;
#endif // SLI_BT_PERIODIC_ADVERTISER_CONFIG_H

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file sli_bt_sync_config.h
* @brief Configuration types for "sync"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#ifndef SLI_BT_SYNC_CONFIG_H
#define SLI_BT_SYNC_CONFIG_H
#include "sli_bt_config_defs.h"
/**
* @brief Configuration structure used by "sync"
*
* See "sl_bt_sync_config.h" for detailed description of each configuration
* parameter.
*/
typedef struct {
uint8_t max_periodic_syncs; ///< Set to value of SL_BT_CONFIG_MAX_PERIODIC_ADVERTISING_SYNC
} sli_bt_sync_config_t;
#endif // SLI_BT_SYNC_CONFIG_H

View File

@@ -0,0 +1,909 @@
/***************************************************************************//**
* @brief Adaptation for running Bluetooth in RTOS
*******************************************************************************
* # License
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <cmsis_os2.h>
#include "sl_core.h"
#include "sl_bluetooth.h"
#include "sli_bgapi.h"
#include "sl_bt_stack_config.h"
#include "sl_bt_rtos_config.h"
#include "sl_bt_rtos_adaptation.h"
#include "sl_component_catalog.h"
#include "sl_memory_manager.h"
#ifdef CONFIGURATION_HEADER
#include CONFIGURATION_HEADER
#endif // CONFIGURATION_HEADER
#if defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
#include "sli_bt_event_system.h"
#endif
// Definitions for Bluetooth state flags that are needed already before the RTOS
// kernel has been started, i.e. if the application calls
// `sl_bt_system_start_bluetooth()` from `app_init()`. These flags are used with
// the static state variable `bluetooth_state_flags`.
#define SLI_BT_RTOS_STATE_FLAG_KERNEL_STARTED 0x01U // The RTOS kernel has been started
#define SLI_BT_RTOS_STATE_FLAG_STARTING 0x02U // The Bluetooth stack is starting
#define SLI_BT_RTOS_STATE_FLAG_STARTED 0x04U // The Bluetooth stack has successfully started
#define SLI_BT_RTOS_STATE_FLAG_STOPPING 0x08U // The Bluetooth stack is stopping
// The event flags defined below are specific to a thread and are used with the
// thread context's `event_flags` field. The values would not necessarily need
// to be unique between threads. We still choose unique values to make it easier
// to detect if a flag of one thread is accidentally used with another.
// Common event flags used with @ref wait_bluetooth_rtos_thread_event_flags
#define SLI_BT_RTOS_EVENT_FLAG_ERROR 0x80000000U // An error has occurred while waiting for events
// Event flags for the Bluetooth thread
#define SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_WAKEUP 0x00000001U // Bluetooth task needs an update
#define SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_COMMAND_WAITING 0x00000002U // Bluetooth command is waiting to be processed
#define SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED 0x00000004U // Bluetooth event posted to the event handler thread has been handled
#define SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_STOPPED 0x00000008U // Bluetooth stack has been stopped
// Event flags for the Link Layer thread
#define SLI_BT_RTOS_LINKLAYER_THREAD_FLAG_WAKEUP 0x00000100U // Linklayer task needs an update
// Event flags for the event handler thread
#define SLI_BT_RTOS_EVENT_THREAD_FLAG_EVENT_WAITING 0x00010000U // Bluetooth event is waiting to be processed
static volatile uint8_t bluetooth_state_flags = 0;
static volatile sl_bt_msg_t bluetooth_evt_instance;
static volatile uint32_t command_header;
static volatile void* command_data;
static volatile sl_bgapi_handler command_handler_func = NULL;
/**
* @brief Structure to represent a thread in the Bluetooth RTOS adaptation
*/
typedef struct {
osThreadId_t thread_id; ///< The ID of the thread
osSemaphoreId_t wakeup_semaphore_id; ///< The ID of the wakeup semaphore
volatile uint32_t event_flags; ///< Event flags to be handled after wakeup
} sli_bt_rtos_thread_t;
//Bluetooth stack thread
static void bluetooth_thread(void *p_arg);
static sli_bt_rtos_thread_t thread_bluetooth;
static const osThreadAttr_t thread_bluetooth_attr = {
.name = "Bluetooth stack",
.stack_size = SL_BT_RTOS_HOST_STACK_TASK_STACK_SIZE,
.priority = (osPriority_t) SL_BT_RTOS_HOST_STACK_TASK_PRIORITY
};
static const osSemaphoreAttr_t semaphore_bluetooth_attr = {
.name = "Bluetooth stack wakeup"
};
//Bluetooth linklayer thread
static void linklayer_thread(void *p_arg);
static sli_bt_rtos_thread_t thread_linklayer;
static const osThreadAttr_t thread_linklayer_attr = {
.name = "Bluetooth linklayer",
.stack_size = SL_BT_RTOS_LINK_LAYER_TASK_STACK_SIZE,
.priority = (osPriority_t) SL_BT_RTOS_LINK_LAYER_TASK_PRIORITY
};
static const osSemaphoreAttr_t semaphore_linklayer_attr = {
.name = "Bluetooth linklayer wakeup"
};
// The Bluetooth event handler thread is only used when Event System IPC is not
// included
#if !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
static sli_bt_rtos_thread_t thread_event_handler;
static void event_handler_thread(void *p_arg);
static const osThreadAttr_t thread_event_handler_attr = {
.name = "Bluetooth event handler",
.stack_size = SL_BT_RTOS_EVENT_HANDLER_STACK_SIZE,
.priority = (osPriority_t) SL_BT_RTOS_EVENT_HANDLER_TASK_PRIORITY
};
static const osSemaphoreAttr_t semaphore_event_handler_attr = {
.name = "Bluetooth event handler wakeup"
};
#endif // !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
static volatile osMutexId_t bluetooth_mutex_id;
static const osMutexAttr_t bluetooth_mutex_attr = {
.name = "Bluetooth Mutex",
.attr_bits = osMutexRecursive | osMutexPrioInherit,
};
static volatile osMutexId_t bgapi_mutex_id;
static const osMutexAttr_t bgapi_mutex_attr = {
.name = "BGAPI Mutex",
.attr_bits = osMutexRecursive | osMutexPrioInherit,
};
static volatile osSemaphoreId_t bgapi_response_semaphore_id;
static const osSemaphoreAttr_t bgapi_response_semaphore_attr = {
.name = "BGAPI response"
};
static uint32_t bgapi_command_recursion_count = 0;
/**
* @brief Convert CMSIS-RTOS2 osStatus_t to @ref sl_status_t
*/
static sl_status_t os2sl_status(osStatus_t ret)
{
switch (ret) {
case osOK:
return SL_STATUS_OK;
case osErrorTimeout:
return SL_STATUS_TIMEOUT;
case osErrorISR:
return SL_STATUS_ISR;
case osErrorParameter:
return SL_STATUS_INVALID_PARAMETER;
default:
return SL_STATUS_FAIL;
}
}
/**
* @brief Delete a Bluetooth RTOS adaptation thread
*
* @param[out] thread The thread structure that records the info for the thread
* to delete
*/
static void delete_bluetooth_rtos_thread(sli_bt_rtos_thread_t *thread)
{
EFM_ASSERT(thread != NULL);
if (thread->thread_id != NULL) {
(void) osThreadTerminate(thread->thread_id);
thread->thread_id = NULL;
}
if (thread->wakeup_semaphore_id != NULL) {
(void) osSemaphoreDelete(thread->wakeup_semaphore_id);
thread->wakeup_semaphore_id = NULL;
}
}
/**
* @brief Create a Bluetooth RTOS adaptation thread
*
* This function creates a wakeup semaphore and the corresponding thread to use
* for Bluetooth RTOS adaptation. The thread function @p thread_func will
* receive a pointer to @p thread as the thread argument.
*
* To support the special case where the event thread is disabled by
* configuration, this function may be called with @p thread_func set to NULL.
* In this case the thread is not created, but the wakeup semaphore and the
* event flags can be used by any calling thread to wait for an event.
*
* Note that this function does not automatically assign `thread_id` in @p
* thread. To avoid race conditions between the calling thread and the thread
* that is created, some thread creation calls need special consideration in
* assigning the handle. This function gives the callers the flexibility to
* choose when to assign `thread_id` in @p thread.
*
* @param[out] thread The thread structure that records the info for this thread
* @param[out] thread_id Set to the thread ID for the created thread
* @param[in] semaphore_attr Attributes of the wakeup semaphore
* @param[in] thread_func Thread function
* @param[in] thread_attr Attributes of the thread to create
*/
static sl_status_t create_bluetooth_rtos_thread(sli_bt_rtos_thread_t *thread,
osThreadId_t *thread_id,
const osSemaphoreAttr_t *semaphore_attr,
osThreadFunc_t thread_func,
const osThreadAttr_t *thread_attr)
{
// Parameters must have been supplied and we can't yet have the RTOS objects
EFM_ASSERT(thread != NULL);
EFM_ASSERT(thread_id != NULL);
EFM_ASSERT(thread->thread_id == NULL);
EFM_ASSERT(thread->wakeup_semaphore_id == NULL);
// Thread will typically immmediately start waiting on the wakeup semaphore,
// so init event flags and create the semaphore first
thread->event_flags = 0;
uint32_t max_count = 1;
uint32_t initial_count = 0;
thread->wakeup_semaphore_id = osSemaphoreNew(max_count, initial_count, semaphore_attr);
if (thread->wakeup_semaphore_id == NULL) {
return SL_STATUS_FAIL;
}
// Create the thread itself, if a function was supplied
if (thread_func != NULL) {
*thread_id = osThreadNew(thread_func, thread, thread_attr);
if (*thread_id == NULL) {
(void) osSemaphoreDelete(thread->wakeup_semaphore_id);
thread->wakeup_semaphore_id = NULL;
return SL_STATUS_FAIL;
}
} else {
*thread_id = NULL;
}
return SL_STATUS_OK;
}
/**
* @brief Set event flags to the specifed Bluetooth RTOS adaptation thread
*
* This function sets the specified event flags to a Bluetooth RTOS adaptation
* thread. The flags are bitwise OR'ed, i.e. flag bits that are zero do not
* affect flags that have already been set. Flag bits that are set to one are
* set to the thread and the target thread is woken up.
*
* @param[in,out] thread The thread structure that records the info for this thread
* @param[in] event_flags The event flags to set
*/
static void set_bluetooth_rtos_thread_event_flags(sli_bt_rtos_thread_t *thread,
uint32_t event_flags)
{
CORE_DECLARE_IRQ_STATE;
// Set the flags in an atomic section
CORE_ENTER_ATOMIC();
thread->event_flags |= event_flags;
CORE_EXIT_ATOMIC();
// To avoid any risk of a race condition, we err on the side of caution and
// always wakeup the target thread. The threads don't react to the number of
// wakeups, but to seeing flags set, so redundant wakeups are not a problem.
// Also, since we're using a binary semaphore, the number of wakeups won't
// accumulate. If we wake up the thread multiple times, the semaphore clamps
// at one token, the thread wakes up once, and sees all the flags accumulated
// so far.
//
// We deliberately don't check the return code when we release the semaphore.
// The only possible errors documented by CMSIS-RTOS2 is reaching the maximum
// count (this is OK for us, as we're deliberately using a binary semaphore
// that clamps to one token), and having a NULL or invalid semaphore ID. That
// can only happen if someone else corrupts our memory, as the semaphore
// creation is checked for success before the threads start using it. That
// error would be unrecoverable anyway.
(void) osSemaphoreRelease(thread->wakeup_semaphore_id);
}
/**
* @brief Pop the current event flags in the specifed Bluetooth RTOS adaptation thread
*
* This function returns a bitmask of event flags that were set and clears those
* bits in the thread structure.
*
* @param[in,out] thread The thread structure that records the info for this thread
* @param[in] event_flags The event flags to wait for
*
* @return The event flags that were set and have been cleared
*/
static uint32_t pop_bluetooth_rtos_thread_event_flags(sli_bt_rtos_thread_t *thread)
{
CORE_DECLARE_IRQ_STATE;
// Check and clear the flags atomically
CORE_ENTER_ATOMIC();
uint32_t event_flags = thread->event_flags;
if (event_flags != 0) {
thread->event_flags = 0;
}
CORE_EXIT_ATOMIC();
return event_flags;
}
/**
* @brief Wait for event flags in the specifed Bluetooth RTOS adaptation thread
*
* This function waits until at least one event flag has become set for the
* thread. If flags are set already, the function returns immediately. The
* function returns a bitmask of event flags that were set and clears those bits
* in the thread structure.
*
* @param[in,out] thread The thread structure that records the info for this thread
* @param[in] event_flags The event flags to wait for
*
* @return The event flags that were set and have been cleared. If an error
* occurs, the flag bit @ref SLI_BT_RTOS_EVENT_FLAG_ERROR is set in the return
* value.
*/
static uint32_t wait_bluetooth_rtos_thread_event_flags(sli_bt_rtos_thread_t *thread)
{
// Loop until we see a flag set or an error occurs
while (1) {
// Pop the current flags
uint32_t event_flags = pop_bluetooth_rtos_thread_event_flags(thread);
// If any flags were set, we're done
if (event_flags != 0) {
return event_flags;
}
// Wait on the wakeup semaphore
osStatus_t os_status = osSemaphoreAcquire(thread->wakeup_semaphore_id, osWaitForever);
if (os_status != osOK) {
// An error has occurred. Set the error bit and store the `sl_status_t` in
// the other bits.
sl_status_t status = os2sl_status(os_status);
return SLI_BT_RTOS_EVENT_FLAG_ERROR | (uint32_t) status;
}
}
}
static sl_status_t start_rtos_adaptation()
{
// This function is called internally in this file. Callers guarantee the
// necessary locking, so we can manipulate the flags safely.
// If the Bluetooth stack is stopping, we cannot accept a new request to start
// the stack until the previous stopping has finished
if (bluetooth_state_flags & SLI_BT_RTOS_STATE_FLAG_STOPPING) {
return SL_STATUS_INVALID_STATE;
}
// If the stack is already starting or started, the new request to start
// requires no actions
if (bluetooth_state_flags & (SLI_BT_RTOS_STATE_FLAG_STARTING | SLI_BT_RTOS_STATE_FLAG_STARTED)) {
return SL_STATUS_OK;
}
// We need to start the stack now. First create the mutex for Bluetooth stack.
sl_status_t status = SL_STATUS_FAIL;
EFM_ASSERT(bluetooth_mutex_id == NULL);
bluetooth_mutex_id = osMutexNew(&bluetooth_mutex_attr);
if (bluetooth_mutex_id == NULL) {
goto cleanup;
}
// We have committed to starting the stack and we expect
// `bluetooth_thread()` to continue the start-up.
bluetooth_state_flags |= SLI_BT_RTOS_STATE_FLAG_STARTING;
// Create thread for Bluetooth stack. Note that we specifically do *not*
// assign `thread_bluetooth.thread_id` here. When the thread is created, its
// priority may be higher than the current thread, so Bluetooth starts running
// before this thread has a chance to set the thread ID. To solve this
// potential race condition, we let the Bluetooth thread itself set
// `thread_bluetooth.thread_id` when it starts running. This way setting the
// thread ID is always synchronous to starting the stack inside the thread.
osThreadId_t host_stack_tid = NULL;
status = create_bluetooth_rtos_thread(&thread_bluetooth,
&host_stack_tid,
&semaphore_bluetooth_attr,
bluetooth_thread,
&thread_bluetooth_attr);
if (status != SL_STATUS_OK) {
// We failed to create the thread, so the start won't be able to proceed.
// Clear the starting flag to keep the state consistent.
bluetooth_state_flags &= ~SLI_BT_RTOS_STATE_FLAG_STARTING;
goto cleanup;
}
// Now we're ready to handle BGAPI commands via the RTOS adaptation. Set the
// BGAPI delegate.
sli_bgapi_set_cmd_handler_delegate(sli_bt_cmd_handler_rtos_delegate);
return SL_STATUS_OK;
cleanup:
// Cleanup everything we managed to create
if (bluetooth_mutex_id != NULL) {
(void) osMutexDelete(bluetooth_mutex_id);
bluetooth_mutex_id = NULL;
}
return status;
}
sl_status_t sl_bt_rtos_init()
{
// Initialize the Bluetooth stack
sl_bt_init();
// The Bluetooth stack including its RTOS adaptation is started with a BGAPI
// command. The BGAPI synchronization primitives are therefore always created
// already at init-time and are never deleted.
uint32_t max_count = 1;
uint32_t initial_count = 0;
bgapi_response_semaphore_id = osSemaphoreNew(max_count, initial_count, &bgapi_response_semaphore_attr);
if (bgapi_response_semaphore_id == NULL) {
return SL_STATUS_FAIL;
}
bgapi_mutex_id = osMutexNew(&bgapi_mutex_attr);
bgapi_command_recursion_count = 0;
if (bgapi_mutex_id == NULL) {
(void) osSemaphoreDelete(bgapi_response_semaphore_id);
bgapi_response_semaphore_id = NULL;
return SL_STATUS_FAIL;
}
// When Event System IPC is in use, let it initialize itself
#if defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
sl_status_t event_system_status = sli_bt_init_event_system();
if (event_system_status != SL_STATUS_OK) {
return event_system_status;
}
#endif
// When Bluetooth on-demand start feature is not present, the RTOS adaptation
// is always started already at init-time.
#if !defined(SL_CATALOG_BLUETOOTH_ON_DEMAND_START_PRESENT)
sl_status_t status = start_rtos_adaptation();
if (status != SL_STATUS_OK) {
return status;
}
#endif // defined(SL_CATALOG_BLUETOOTH_ON_DEMAND_START_PRESENT)
return SL_STATUS_OK;
}
// This callback is called from interrupt context (Kernel Aware) to wake up the
// link layer task
void sli_bt_rtos_ll_callback()
{
set_bluetooth_rtos_thread_event_flags(&thread_linklayer,
SLI_BT_RTOS_LINKLAYER_THREAD_FLAG_WAKEUP);
}
// This callback is called by the Bluetooth stack to wakeup the Bluetooth
// thread. This call may come from a thread or from interrupt context.
void sli_bt_rtos_stack_callback()
{
set_bluetooth_rtos_thread_event_flags(&thread_bluetooth,
SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_WAKEUP);
}
// Called by Bluetooth Event System IPC to mark an event as handled
void sli_bt_rtos_set_event_handled()
{
// Signal the host stack thread that the event has been handled
set_bluetooth_rtos_thread_event_flags(&thread_bluetooth,
SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED);
}
/**
* Internal stack function to get how long the Bluetooth stack can sleep.
*
* @return 0 if the stack cannot sleep;
* Maximum value of uint32_t if the stack has no task scheduled to process;
* The ticks (in sleeptimer frequency) the stack needs to wake up to process a task
*/
extern uint32_t sli_bt_can_sleep_ticks();
/**
* Internal stack function to start the Bluetooth stack.
*
* @return SL_STATUS_OK if the stack was successfully started
*/
extern sl_status_t sli_bt_system_start_bluetooth();
#if defined(SL_CATALOG_BTMESH_PRESENT)
// This is to avoid casting a function pointer to a different type in the
// event_types table.
static sl_status_t _btmesh_pop_event(sl_bt_msg_t *msg)
{
return sl_btmesh_pop_event((sl_btmesh_msg_t*) msg);
}
#endif
typedef struct {
enum sl_bgapi_dev_types dev_type;
bool (*event_pending_fn)(void);
sl_status_t (*pop_event_fn)(sl_bt_msg_t *buffer);
} bgapi_device_type;
static const bgapi_device_type bgapi_device_table[] = {
{ sl_bgapi_dev_type_bt, sl_bt_event_pending, sl_bt_pop_event },
#if defined(SL_CATALOG_BTMESH_PRESENT)
{ sl_bgapi_dev_type_btmesh, sl_btmesh_event_pending, _btmesh_pop_event },
#endif
};
#define NUM_BGAPI_DEVICES (sizeof(bgapi_device_table) / sizeof(bgapi_device_table[0]))
//Bluetooth task, it waits for events from bluetooth and handles them
void bluetooth_thread(void *p_arg)
{
(void)p_arg;
// Set the Bluetooth thread ID now that we're running
thread_bluetooth.thread_id = osThreadGetId();
uint8_t next_evt_index_to_check = 0;
uint32_t flags = SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED;
// Create thread for Linklayer
sl_status_t start_status = create_bluetooth_rtos_thread(&thread_linklayer,
&thread_linklayer.thread_id,
&semaphore_linklayer_attr,
linklayer_thread,
&thread_linklayer_attr);
// Create thread for Bluetooth event handler when Event System IPC is not used
#if !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
if (start_status == SL_STATUS_OK) {
start_status = create_bluetooth_rtos_thread(&thread_event_handler,
&thread_event_handler.thread_id,
&semaphore_event_handler_attr,
event_handler_thread,
&thread_event_handler_attr
);
}
#endif // !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
// Start the Bluetooth stack
if (start_status == SL_STATUS_OK) {
start_status = sli_bt_system_start_bluetooth();
}
#if defined(SL_CATALOG_BTMESH_PRESENT)
// Bluetooth Mesh calls Bluetooth's BGAPI commands internally. In order to not
// collide with external commands, a temporary BGAPI buffer needs to be used.
void *tmp_bgapi_buffer = sl_malloc(SLI_BGAPI_BUFFER_SIZE);
if (tmp_bgapi_buffer == NULL) {
start_status = SL_STATUS_ALLOCATION_FAILED;
}
#endif
if (start_status == SL_STATUS_OK) {
// bluetooth mesh must have bluetooth started before it is initalizes
#if defined(SL_CATALOG_BTMESH_PRESENT)
sl_btmesh_init();
#endif
// Starting the stack has succeeded and we update the state accordingly.
uint8_t updated_state_flags = bluetooth_state_flags;
updated_state_flags &= ~SLI_BT_RTOS_STATE_FLAG_STARTING;
updated_state_flags |= SLI_BT_RTOS_STATE_FLAG_STARTED;
bluetooth_state_flags = updated_state_flags;
} else {
// We failed to start, so consider the stack stopped already in the local
// flags. This way we won't enter the processing loop at all, but proceed to
// cleaning up after the loop. The state flags in `bluetooth_state_flags`
// continue to show the "starting" state until we've finished cleaning up.
flags |= SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_STOPPED;
}
// We run the command processing loop as long as the stack has not been stopped
while ((flags & SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_STOPPED) == 0) {
//Command needs to be sent to Bluetooth stack
if (flags & SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_COMMAND_WAITING) {
uint32_t header = command_header;
sl_bgapi_handler cmd_handler = command_handler_func;
sli_bgapi_cmd_handler_delegate(header, cmd_handler, (void*)command_data);
command_handler_func = NULL;
flags &= ~SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_COMMAND_WAITING;
osSemaphoreRelease(bgapi_response_semaphore_id);
}
#if defined(SL_CATALOG_BTMESH_PRESENT)
// Set a temporary BGAPI buffer for the section in which internal BGAPI
// calls might occur.
void *orig_bgapi_buffer = sli_bgapi_set_buffer(tmp_bgapi_buffer);
#endif
//Run Bluetooth stack. Pop the next event for application
sl_bt_run();
if (flags & SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED) {
bool event_popped = false;
sl_status_t status = SL_STATUS_OK;
for (uint8_t i = 0; i < NUM_BGAPI_DEVICES; i++) {
// Try to get an event of a device type that was _not_ handled previously, in order to
// prevent one device type from "starving" the other device type(s).
// For example, Bluetooth scan reports could flood in so fast that we'd never process
// BT Mesh events, if we always checked for Bluetooth events first.
uint8_t evt_index = (next_evt_index_to_check + i) % NUM_BGAPI_DEVICES;
const bgapi_device_type *dev = &bgapi_device_table[evt_index];
if (dev->event_pending_fn()) {
status = dev->pop_event_fn((sl_bt_msg_t*) &bluetooth_evt_instance);
if (status == SL_STATUS_OK) {
// Next round, start the search from the next event type (wrapping around if needed)
next_evt_index_to_check = (evt_index + 1) % NUM_BGAPI_DEVICES;
event_popped = true;
}
break;
}
}
if (status != SL_STATUS_OK) {
continue;
}
if (event_popped) {
// Always clear the local flag once an event was popped. The flag gets
// set when the event has been handled and the corresponding thread
// event flag is signalled by `sli_bt_rtos_set_event_handled()`.
flags &= ~SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED;
#if defined(SL_CATALOG_BTMESH_PRESENT)
sl_btmesh_bgapi_listener((sl_bt_msg_t*) &bluetooth_evt_instance);
#endif
#if defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
// Publish the event to Event System IPC
sl_status_t publish_status = sli_bt_publish_to_event_system((sl_bt_msg_t*) &bluetooth_evt_instance);
if (publish_status != SL_STATUS_OK) {
// Failed to publish the event. This is potentially fatal, but there
// is not much we can do here. Assert in a debug build.
EFM_ASSERT(0);
}
#else // defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
// Signal the event handler task to deliver the event
set_bluetooth_rtos_thread_event_flags(&thread_event_handler,
SLI_BT_RTOS_EVENT_THREAD_FLAG_EVENT_WAITING);
#endif // defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
}
}
#if defined(SL_CATALOG_BTMESH_PRESENT)
// Restore the original BGAPI buffer after the section in which internal BGAPI
// calls might occur.
sli_bgapi_set_buffer(orig_bgapi_buffer);
#endif
uint32_t timeout = sli_bt_can_sleep_ticks();
if (timeout == 0 && (flags & SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED)) {
continue;
}
// Wait for any flag to get set
flags |= wait_bluetooth_rtos_thread_event_flags(&thread_bluetooth);
if ((flags & SLI_BT_RTOS_EVENT_FLAG_ERROR) != 0) {
// In case of error, reset the flags and continue
flags = SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED;
continue;
}
}
// The stack has stopped processing commands and has already finished its own
// cleanup of resources. It's now time for the RTOS adaptation to cleanup its
// own resources. First delete the threads that we created for the link layer
// and for the event handler.
delete_bluetooth_rtos_thread(&thread_linklayer);
#if !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
delete_bluetooth_rtos_thread(&thread_event_handler);
#endif
// Delete the synchronization primitives
(void) osMutexDelete(bluetooth_mutex_id);
bluetooth_mutex_id = NULL;
// In case we've failed to start, we will directly deliver a system error
// event to the application in the code below. To allow the application to
// retry when it gets the error event, we need to clean all global state first
// and finish the cleanup locally in the current thread when the event handler
// returns. We take ownership of all remaining RTOS objects (this thread and
// its wakeup semaphore) and clear the state to indicate the kernel is started
// but the stack is stopped.
thread_bluetooth.thread_id = NULL;
(void) osSemaphoreDelete(thread_bluetooth.wakeup_semaphore_id);
thread_bluetooth.wakeup_semaphore_id = NULL;
bluetooth_state_flags = SLI_BT_RTOS_STATE_FLAG_KERNEL_STARTED;
// Generate the right event to indicate the stack is not running
if (start_status != SL_STATUS_OK) {
// We failed to start the stack. Generate a system error event.
uint32_t evt_len = sizeof(bluetooth_evt_instance.data.evt_system_error);
bluetooth_evt_instance.header = sl_bt_evt_system_error_id | (evt_len << 8);
bluetooth_evt_instance.data.evt_system_error.reason = (uint16_t) start_status;
bluetooth_evt_instance.data.evt_system_error.data.len = 0;
} else {
// The stack started successfully, so the stopping has been a deliberate
// request with the on-demand start feature. Generate the "system stopped"
// event and deliver it directly to the application with a function call
// from this thread. Note that the "system stopped" event has no
// event-specific fields, so only the header needs to be set.
bluetooth_evt_instance.header = sl_bt_evt_system_stopped_id;
}
// Publish via event system or call the application directly
#if defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
sli_bt_publish_to_event_system((sl_bt_msg_t*) &bluetooth_evt_instance);
#else
sl_bt_process_event((sl_bt_msg_t*) &bluetooth_evt_instance);
#endif
// Finally terminate this thread itself
(void) osThreadTerminate(osThreadGetId());
}
static void linklayer_thread(void *p_arg)
{
// The input parameter is our thread structure
sli_bt_rtos_thread_t *thread = (sli_bt_rtos_thread_t *) p_arg;
while (1) {
// Wait for any flag to get set. Only the link layer flag is expected in
// this thread.
uint32_t flags = wait_bluetooth_rtos_thread_event_flags(thread);
EFM_ASSERT(flags == SLI_BT_RTOS_LINKLAYER_THREAD_FLAG_WAKEUP);
// Handle the event
sl_bt_priority_handle();
}
}
// Event task, this calls the application code
#if !defined(SL_CATALOG_BLUETOOTH_EVENT_SYSTEM_IPC_PRESENT)
static void event_handler_thread(void *p_arg)
{
// The input parameter is our thread structure
sli_bt_rtos_thread_t *thread = (sli_bt_rtos_thread_t *) p_arg;
while (1) {
// Wait for any flag to get set. Only the "event waiting" flag is expected
// in this thread.
uint32_t flags = wait_bluetooth_rtos_thread_event_flags(thread);
EFM_ASSERT(flags == SLI_BT_RTOS_EVENT_THREAD_FLAG_EVENT_WAITING);
switch (SL_BGAPI_MSG_DEVICE_TYPE(bluetooth_evt_instance.header)) {
case sl_bgapi_dev_type_bt:
sl_bt_process_event((sl_bt_msg_t*) &bluetooth_evt_instance);
break;
#if defined(SL_CATALOG_BTMESH_PRESENT)
case sl_bgapi_dev_type_btmesh:
sl_btmesh_process_event((sl_btmesh_msg_t*) &bluetooth_evt_instance);
break;
#endif
default:
// This should not be possible
EFM_ASSERT(0);
break;
}
// Signal the host stack thread that the event has been handled
set_bluetooth_rtos_thread_event_flags(&thread_bluetooth,
SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_EVENT_HANDLED);
}
}
#endif
//hooks for API
//called from tasks using Bluetooth API
void sli_bt_cmd_handler_rtos_delegate(uint32_t header, sl_bgapi_handler handler, const void* payload)
{
command_header = header;
command_handler_func = handler;
command_data = (void*)payload;
if (osThreadGetId() == thread_bluetooth.thread_id) {
// If we're already in the Bluetooth stack thread, the BGAPI command will be handled as a direct
// function call; as opposed to signalling ourselves that there's a command waiting, like what
// would happen in all other threads
handler(payload);
return;
}
// We're starting a new command. The response semaphore cannot have an
// available token yet.
EFM_ASSERT(osSemaphoreGetCount(bgapi_response_semaphore_id) == 0);
// Command structure is filled, notify the stack
set_bluetooth_rtos_thread_event_flags(&thread_bluetooth,
SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_COMMAND_WAITING);
// Wait for response
osSemaphoreAcquire(bgapi_response_semaphore_id, osWaitForever);
}
// Lock the BGAPI for exclusive access
sl_status_t sl_bgapi_lock(void)
{
// The BGAPI is not allowed to be called from an ISR
if (CORE_InIrqContext()) {
return SL_STATUS_ISR;
}
// If the kernel has not been started yet, the BGAPI command call must be a
// call from `app_init()` to start the Bluetooth stack. The init is
// single-threaded and we can safely proceed without the lock.
if ((bluetooth_state_flags & SLI_BT_RTOS_STATE_FLAG_KERNEL_STARTED) == 0) {
return SL_STATUS_OK;
}
osStatus_t ret = osMutexAcquire(bgapi_mutex_id, 0);
if (ret == osOK) {
// Able to immediately acquire
return SL_STATUS_OK;
} else if ((ret != osOK)
&& (osThreadGetId() == thread_bluetooth.thread_id)) {
// No need to re-acquire, but increment recursion counter since the Bluetooth thread
// is allowed to call BGAPI commands recursively
bgapi_command_recursion_count++;
return SL_STATUS_OK;
} else {
// Otherwise wait for the mutex
ret = osMutexAcquire(bgapi_mutex_id, osWaitForever);
return os2sl_status(ret);
}
}
// Release the lock obtained by @ref sl_bgapi_lock
void sl_bgapi_unlock(void)
{
// If the kernel has not been started yet, the lock has not been obtained and
// the unlock is ignored
if ((bluetooth_state_flags & SLI_BT_RTOS_STATE_FLAG_KERNEL_STARTED) == 0) {
return;
}
if (bgapi_command_recursion_count > 0) {
// Do not release the mutex if we are in a recursive call.
bgapi_command_recursion_count--;
return;
}
(void) osMutexRelease(bgapi_mutex_id);
}
// Called by system initialization when kernel is starting.
void sli_bt_rtos_adaptation_kernel_start()
{
bluetooth_state_flags |= SLI_BT_RTOS_STATE_FLAG_KERNEL_STARTED;
}
// Start the Bluetooth RTOS adaptation
sl_status_t sli_bt_start_rtos_adaptation()
{
return start_rtos_adaptation();
}
// Prepare for stopping the Bluetooth RTOS adaptation
void sli_bt_prepare_to_stop_rtos_adaptation()
{
// This function is called in the context of the Bluetooth thread when
// processing the command sl_bt_system_stop_bluetooth(). The BGAPI lock is
// already held when we enter this function and we can safely manipulate the
// state flags. The BGAPI command handling verifies the current state and
// calls this function only when it's really time to begin stopping. We can
// simply always set the flag.
bluetooth_state_flags |= SLI_BT_RTOS_STATE_FLAG_STOPPING;
// We stop processing BGAPI commands via the RTOS adaptation, as the stack has
// already committed to stopping. The BGAPI device has changed to a state
// where only commands that are available when the stack is stopped are
// reachable if the application calls a BGAPI command. It is therefore safe to
// handle BGAPI commands via the default delegate until the stack is
// restarted.
sli_bgapi_set_cmd_handler_delegate(sli_bgapi_cmd_handler_delegate);
}
// Stop the Bluetooth RTOS adaptation
void sli_bt_stop_rtos_adaptation()
{
// Set the event flag to indicate that the stack has been stopped. The
// Bluetooth thread will cleanup and exit.
set_bluetooth_rtos_thread_event_flags(&thread_bluetooth,
SLI_BT_RTOS_BLUETOOTH_THREAD_FLAG_STOPPED);
}
sl_status_t sl_bt_bluetooth_pend()
{
osStatus_t ret = osMutexAcquire(bluetooth_mutex_id, osWaitForever);
return os2sl_status(ret);
}
sl_status_t sl_bt_bluetooth_post()
{
osStatus_t ret = osMutexRelease(bluetooth_mutex_id);
return os2sl_status(ret);
}
const sl_bt_msg_t* sl_bt_rtos_get_event()
{
return (const sl_bt_msg_t*) &bluetooth_evt_instance;
}

View File

@@ -0,0 +1,832 @@
/***************************************************************************//**
* @brief Initialization APIs for Bluetooth stack
*******************************************************************************
* # License
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
// Include the catalog first to make sure everything below can see it
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#else // SL_COMPONENT_CATALOG_PRESENT
#error The SL component catalog required by Bluetooth stack is not present in the build
#endif // SL_COMPONENT_CATALOG_PRESENT
// Define the initilization mode for the configuration definition headers. The
// initialization mode for the Bluetooth stack depends on the on-demand start
// component. When on-demand start is used, features support de-initialization.
// When on-demand start is not used, the de-init functions are omitted to
// eliminate code that's not needed in the build.
#if defined(SL_CATALOG_BLUETOOTH_ON_DEMAND_START_PRESENT)
#define SLI_BT_INIT_MODE on_demand
#else
#define SLI_BT_INIT_MODE init_always
#endif
#include "sl_status.h"
#include "sl_bt_api.h"
#include "sl_bt_stack_config.h"
#include "sl_bt_stack_init.h"
#include "sl_bluetooth_config.h"
#include "sl_btctrl_linklayer.h"
#include "sli_bt_gattdb_def.h"
#include "sli_bt_config_defs.h"
#ifdef SL_CATALOG_GATT_CONFIGURATION_PRESENT
extern const sli_bt_gattdb_t gattdb;
#else
const sli_bt_gattdb_t gattdb = { 0 };
#endif // SL_CATALOG_GATT_CONFIGURATION_PRESENT
// Forward declaration of BGAPI classes
SLI_BT_DECLARE_BGAPI_CLASS(bt, system);
SLI_BT_DECLARE_BGAPI_CLASS(bt, nvm);
SLI_BT_DECLARE_BGAPI_CLASS(bt, gap);
SLI_BT_DECLARE_BGAPI_CLASS(bt, sm);
SLI_BT_DECLARE_BGAPI_CLASS(bt, external_bondingdb);
SLI_BT_DECLARE_BGAPI_CLASS(bt, accept_list);
SLI_BT_DECLARE_BGAPI_CLASS(bt, resolving_list);
SLI_BT_DECLARE_BGAPI_CLASS(bt, advertiser);
SLI_BT_DECLARE_BGAPI_CLASS(bt, legacy_advertiser);
SLI_BT_DECLARE_BGAPI_CLASS(bt, extended_advertiser);
SLI_BT_DECLARE_BGAPI_CLASS(bt, periodic_advertiser);
SLI_BT_DECLARE_BGAPI_CLASS(bt, scanner);
SLI_BT_DECLARE_BGAPI_CLASS(bt, sync);
SLI_BT_DECLARE_BGAPI_CLASS(bt, pawr_advertiser);
SLI_BT_DECLARE_BGAPI_CLASS(bt, sync_scanner);
SLI_BT_DECLARE_BGAPI_CLASS(bt, periodic_sync);
SLI_BT_DECLARE_BGAPI_CLASS(bt, pawr_sync);
SLI_BT_DECLARE_BGAPI_CLASS(bt, past_receiver);
SLI_BT_DECLARE_BGAPI_CLASS(bt, advertiser_past);
SLI_BT_DECLARE_BGAPI_CLASS(bt, sync_past);
SLI_BT_DECLARE_BGAPI_CLASS(bt, cs);
SLI_BT_DECLARE_BGAPI_CLASS(bt, cs_test);
SLI_BT_DECLARE_BGAPI_CLASS(bt, l2cap);
SLI_BT_DECLARE_BGAPI_CLASS(bt, connection);
SLI_BT_DECLARE_BGAPI_CLASS(bt, gatt);
SLI_BT_DECLARE_BGAPI_CLASS(bt, gattdb);
SLI_BT_DECLARE_BGAPI_CLASS(bt, gatt_server);
SLI_BT_DECLARE_BGAPI_CLASS(bt, cte_receiver);
SLI_BT_DECLARE_BGAPI_CLASS(bt, cte_transmitter);
SLI_BT_DECLARE_BGAPI_CLASS(bt, test);
SLI_BT_DECLARE_BGAPI_CLASS(bt, coex);
SLI_BT_DECLARE_BGAPI_CLASS(bt, resource);
SLI_BT_DECLARE_BGAPI_CLASS(bt, connection_analyzer);
// Forward declaration of the internal Bluetooth stack init function
sl_status_t sli_bt_init_stack(const sl_bt_configuration_t *config,
const struct sli_bt_feature_use *features,
const struct sli_bgapi_class * const *bgapi_classes);
// Some features do not correspond directly to a particular component but are
// needed depending on a specific combination of components. Decide the derived
// feature selections here to simplify the feature inclusion rules below.
// Extended advertising feature is included if it's explicitly used, but only
// when there's no device incompatibility.
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_ADVERTISER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_EXTENDED_ADVERTISING_INCOMPATIBLE_PRESENT)
#define SLI_BT_ENABLE_EXTENDED_ADVERTISER_FEATURE
#endif
// The scanner event handler is included if the legacy or extended scanner
// component is used.
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_LEGACY_SCANNER_PRESENT) \
|| defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_SCANNER_PRESENT)
#define SLI_BT_ENABLE_SCANNER_BASE
#endif
// Extended scanner feature is included if it's explicitly used, but only when
// there's no device incompatibility.
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_SCANNER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_EXTENDED_SCANNING_INCOMPATIBLE_PRESENT)
#define SLI_BT_ENABLE_EXTENDED_SCANNER_FEATURE
#endif
// If the build configuration needs a specific feature, we pick it for inclusion
// in the feature and BGAPI lists, as applicable.
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYSTEM_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, system);
#define SLI_BT_FEATURE_SYSTEM SLI_BT_USE_FEATURE(bt, system),
#define SLI_BT_BGAPI_SYSTEM SLI_BT_USE_BGAPI_CLASS(bt, system),
#else
#define SLI_BT_FEATURE_SYSTEM
#define SLI_BT_BGAPI_SYSTEM
#endif
#if defined(SL_CATALOG_BLUETOOTH_ON_DEMAND_START_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, on_demand_start);
#define SLI_BT_FEATURE_ON_DEMAND_START SLI_BT_USE_FEATURE(bt, on_demand_start),
#else
#define SLI_BT_FEATURE_ON_DEMAND_START
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_NVM_PRESENT)
#define SLI_BT_BGAPI_NVM SLI_BT_USE_BGAPI_CLASS(bt, nvm),
#else
#define SLI_BT_BGAPI_NVM
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_GAP_PRESENT)
#define SLI_BT_BGAPI_GAP SLI_BT_USE_BGAPI_CLASS(bt, gap),
#else
#define SLI_BT_BGAPI_GAP
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SM_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, sm);
#define SLI_BT_FEATURE_SM SLI_BT_USE_FEATURE(bt, sm),
#define SLI_BT_BGAPI_SM SLI_BT_USE_BGAPI_CLASS(bt, sm),
#else
#define SLI_BT_FEATURE_SM
#define SLI_BT_BGAPI_SM
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_BUILTIN_BONDING_DATABASE_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, builtin_bonding_database);
#define SLI_BT_FEATURE_BUILTIN_BONDING_DATABASE SLI_BT_USE_FEATURE(bt, builtin_bonding_database),
#else
#define SLI_BT_FEATURE_BUILTIN_BONDING_DATABASE
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTERNAL_BONDING_DATABASE_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, external_bonding_database);
#define SLI_BT_FEATURE_EXTERNAL_BONDING_DATABASE SLI_BT_USE_FEATURE(bt, external_bonding_database),
#define SLI_BT_BGAPI_EXTERNAL_BONDINGDB SLI_BT_USE_BGAPI_CLASS(bt, external_bondingdb),
#else
#define SLI_BT_FEATURE_EXTERNAL_BONDING_DATABASE
#define SLI_BT_BGAPI_EXTERNAL_BONDINGDB
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ACCEPT_LIST_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, accept_list);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, accept_list);
#define SLI_BT_FEATURE_ACCEPT_LIST SLI_BT_USE_FEATURE_WITH_CONFIG(bt, accept_list, SLI_BT_FEATURE_CONFIG_NAME(bt, accept_list)),
#define SLI_BT_BGAPI_ACCEPT_LIST SLI_BT_USE_BGAPI_CLASS(bt, accept_list),
#else
#define SLI_BT_FEATURE_ACCEPT_LIST
#define SLI_BT_BGAPI_ACCEPT_LIST
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_RESOLVING_LIST_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, resolving_list);
#define SLI_BT_FEATURE_RESOLVING_LIST SLI_BT_USE_FEATURE(bt, resolving_list),
#define SLI_BT_BGAPI_RESOLVING_LIST SLI_BT_USE_BGAPI_CLASS(bt, resolving_list),
#else
#define SLI_BT_FEATURE_RESOLVING_LIST
#define SLI_BT_BGAPI_RESOLVING_LIST
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_FEATURE_LEGACY_ADVERTISER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_ADVERTISER_PRESENT)
#error Incomplete Bluetooth advertiser feature detected. Add component \
bluetooth_feature_legacy_advertiser for advertising with legacy \
advertising PDUs. Add component bluetooth_feature_extended_advertiser \
for advertising with extended advertising PDUs.
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, advertiser);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, advertiser);
#define SLI_BT_FEATURE_ADVERTISER SLI_BT_USE_FEATURE_WITH_CONFIG(bt, advertiser, SLI_BT_FEATURE_CONFIG_NAME(bt, advertiser)),
#define SLI_BT_BGAPI_ADVERTISER SLI_BT_USE_BGAPI_CLASS(bt, advertiser),
#else
#define SLI_BT_FEATURE_ADVERTISER
#define SLI_BT_BGAPI_ADVERTISER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_LEGACY_ADVERTISER_PRESENT)
#define SLI_BT_BGAPI_LEGACY_ADVERTISER SLI_BT_USE_BGAPI_CLASS(bt, legacy_advertiser),
#else
#define SLI_BT_BGAPI_LEGACY_ADVERTISER
#endif
#if defined(SLI_BT_ENABLE_EXTENDED_ADVERTISER_FEATURE)
SLI_BT_DECLARE_FEATURE(bt, extended_advertiser);
#define SLI_BT_FEATURE_EXTENDED_ADVERTISER SLI_BT_USE_FEATURE(bt, extended_advertiser),
#else
#define SLI_BT_FEATURE_EXTENDED_ADVERTISER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_ADVERTISER_PRESENT)
#define SLI_BT_BGAPI_EXTENDED_ADVERTISER SLI_BT_USE_BGAPI_CLASS(bt, extended_advertiser),
#else
#define SLI_BT_BGAPI_EXTENDED_ADVERTISER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_ADVERTISER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, periodic_advertiser);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, periodic_advertiser);
#define SLI_BT_FEATURE_PERIODIC_ADVERTISER SLI_BT_USE_FEATURE_WITH_CONFIG(bt, periodic_advertiser, SLI_BT_FEATURE_CONFIG_NAME(bt, periodic_advertiser)),
#define SLI_BT_BGAPI_PERIODIC_ADVERTISER SLI_BT_USE_BGAPI_CLASS(bt, periodic_advertiser),
#else
#define SLI_BT_FEATURE_PERIODIC_ADVERTISER
#define SLI_BT_BGAPI_PERIODIC_ADVERTISER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_ADVERTISER_PRESENT)
#define SLI_BT_BGAPI_PAWR_ADVERTISER SLI_BT_USE_BGAPI_CLASS(bt, pawr_advertiser),
#else
#define SLI_BT_BGAPI_PAWR_ADVERTISER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SCANNER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_FEATURE_LEGACY_SCANNER_PRESENT) \
&& !defined(SL_CATALOG_BLUETOOTH_FEATURE_EXTENDED_SCANNER_PRESENT)
#error Incomplete Bluetooth scanner feature detected. Add component \
bluetooth_feature_legacy_scanner for scanning advertisements in legacy \
advertising PDUs. Add component bluetooth_feature_extended_scanner for \
scanning advertisements in legacy or extended advertising PDUs.
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SCANNER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, scanner);
#define SLI_BT_FEATURE_SCANNER SLI_BT_USE_FEATURE(bt, scanner),
#define SLI_BT_BGAPI_SCANNER SLI_BT_USE_BGAPI_CLASS(bt, scanner),
#else
#define SLI_BT_FEATURE_SCANNER
#define SLI_BT_BGAPI_SCANNER
#endif
#if defined(SLI_BT_ENABLE_SCANNER_BASE)
SLI_BT_DECLARE_FEATURE(bt, scanner_base);
#define SLI_BT_FEATURE_SCANNER_BASE SLI_BT_USE_FEATURE(bt, scanner_base),
#else
#define SLI_BT_FEATURE_SCANNER_BASE
#endif
#if defined(SLI_BT_ENABLE_EXTENDED_SCANNER_FEATURE)
SLI_BT_DECLARE_FEATURE(bt, extended_scanner);
#define SLI_BT_FEATURE_EXTENDED_SCANNER SLI_BT_USE_FEATURE(bt, extended_scanner),
#else
#define SLI_BT_FEATURE_EXTENDED_SCANNER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, sync);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, sync);
#define SLI_BT_FEATURE_SYNC SLI_BT_USE_FEATURE_WITH_CONFIG(bt, sync, SLI_BT_FEATURE_CONFIG_NAME(bt, sync)),
#define SLI_BT_BGAPI_SYNC SLI_BT_USE_BGAPI_CLASS(bt, sync),
#else
#define SLI_BT_FEATURE_SYNC
#define SLI_BT_BGAPI_SYNC
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_SCANNER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, sync_scanner);
#define SLI_BT_FEATURE_SYNC_SCANNER SLI_BT_USE_FEATURE(bt, sync_scanner),
#else
#define SLI_BT_FEATURE_SYNC_SCANNER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_SCANNER_PRESENT)
#define SLI_BT_BGAPI_SYNC_SCANNER SLI_BT_USE_BGAPI_CLASS(bt, sync_scanner),
#else
#define SLI_BT_BGAPI_SYNC_SCANNER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_SYNC_PRESENT)
#define SLI_BT_BGAPI_PERIODIC_SYNC SLI_BT_USE_BGAPI_CLASS(bt, periodic_sync),
#else
#define SLI_BT_BGAPI_PERIODIC_SYNC
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_SYNC_PRESENT)
#define SLI_BT_BGAPI_PAWR_SYNC SLI_BT_USE_BGAPI_CLASS(bt, pawr_sync),
#else
#define SLI_BT_BGAPI_PAWR_SYNC
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAST_RECEIVER_PRESENT)
#define SLI_BT_BGAPI_PAST_RECEIVER SLI_BT_USE_BGAPI_CLASS(bt, past_receiver),
#else
#define SLI_BT_BGAPI_PAST_RECEIVER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PAST_PRESENT)
#define SLI_BT_BGAPI_ADVERTISER_PAST SLI_BT_USE_BGAPI_CLASS(bt, advertiser_past),
#else
#define SLI_BT_BGAPI_ADVERTISER_PAST
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PAST_PRESENT)
#define SLI_BT_BGAPI_SYNC_PAST SLI_BT_USE_BGAPI_CLASS(bt, sync_past),
#else
#define SLI_BT_BGAPI_SYNC_PAST
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CS_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, cs);
#define SLI_BT_FEATURE_CS SLI_BT_USE_FEATURE(bt, cs),
#define SLI_BT_BGAPI_CS SLI_BT_USE_BGAPI_CLASS(bt, cs),
#else
#define SLI_BT_FEATURE_CS
#define SLI_BT_BGAPI_CS
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CS_TEST_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, cs_test);
#define SLI_BT_FEATURE_CS_TEST SLI_BT_USE_FEATURE(bt, cs_test),
#define SLI_BT_BGAPI_CS_TEST SLI_BT_USE_BGAPI_CLASS(bt, cs_test),
#else
#define SLI_BT_FEATURE_CS_TEST
#define SLI_BT_BGAPI_CS_TEST
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_L2CAP_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, l2cap);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, l2cap);
#define SLI_BT_FEATURE_L2CAP SLI_BT_USE_FEATURE_WITH_CONFIG(bt, l2cap, SLI_BT_FEATURE_CONFIG_NAME(bt, l2cap)),
#define SLI_BT_BGAPI_L2CAP SLI_BT_USE_BGAPI_CLASS(bt, l2cap),
#else
#define SLI_BT_FEATURE_L2CAP
#define SLI_BT_BGAPI_L2CAP
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, connection);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, connection);
#define SLI_BT_FEATURE_CONNECTION SLI_BT_USE_FEATURE_WITH_CONFIG(bt, connection, SLI_BT_FEATURE_CONFIG_NAME(bt, connection)),
#define SLI_BT_BGAPI_CONNECTION SLI_BT_USE_BGAPI_CLASS(bt, connection),
#else
#define SLI_BT_FEATURE_CONNECTION
#define SLI_BT_BGAPI_CONNECTION
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_STATISTICS_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, connection_statistics);
#define SLI_BT_FEATURE_CONNECTION_STATISTICS SLI_BT_USE_FEATURE(bt, connection_statistics),
#else
#define SLI_BT_FEATURE_CONNECTION_STATISTICS
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_USER_POWER_CONTROL_PRESENT) \
&& defined(SL_CATALOG_BLUETOOTH_FEATURE_POWER_CONTROL_PRESENT)
#error bluetooth_feature_power_control and bluetooth_feature_user_power_control cannot coexist.
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_POWER_CONTROL_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, power_control);
#define SLI_BT_FEATURE_POWER_CONTROL SLI_BT_USE_FEATURE(bt, power_control),
#else
#define SLI_BT_FEATURE_POWER_CONTROL
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_USER_POWER_CONTROL_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, user_power_control);
#define SLI_BT_FEATURE_USER_POWER_CONTROL SLI_BT_USE_FEATURE(bt, user_power_control),
#else
#define SLI_BT_FEATURE_USER_POWER_CONTROL
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_GATT_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, gatt);
#define SLI_BT_FEATURE_GATT SLI_BT_USE_FEATURE(bt, gatt),
#define SLI_BT_BGAPI_GATT SLI_BT_USE_BGAPI_CLASS(bt, gatt),
#else
#define SLI_BT_FEATURE_GATT
#define SLI_BT_BGAPI_GATT
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_DYNAMIC_GATTDB_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, dynamic_gattdb);
SLI_BT_DECLARE_FEATURE_CONFIG(bt, dynamic_gattdb);
#define SLI_BT_FEATURE_DYNAMIC_GATTDB SLI_BT_USE_FEATURE_WITH_CONFIG(bt, dynamic_gattdb, SLI_BT_FEATURE_CONFIG_NAME(bt, dynamic_gattdb)),
#define SLI_BT_BGAPI_DYNAMIC_GATTDB SLI_BT_USE_BGAPI_CLASS(bt, gattdb),
#else
#define SLI_BT_FEATURE_DYNAMIC_GATTDB
#define SLI_BT_BGAPI_DYNAMIC_GATTDB
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_GATT_SERVER_PRESENT)
#define SLI_BT_BGAPI_GATT_SERVER SLI_BT_USE_BGAPI_CLASS(bt, gatt_server),
#else
#define SLI_BT_BGAPI_GATT_SERVER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_AOA_RECEIVER_PRESENT) \
|| defined(SL_CATALOG_BLUETOOTH_FEATURE_AOD_RECEIVER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, cte_receiver);
#define SLI_BT_FEATURE_CTE_RECEIVER SLI_BT_USE_FEATURE(bt, cte_receiver),
#define SLI_BT_BGAPI_CTE_RECEIVER SLI_BT_USE_BGAPI_CLASS(bt, cte_receiver),
#else
#define SLI_BT_FEATURE_CTE_RECEIVER
#define SLI_BT_BGAPI_CTE_RECEIVER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_AOA_TRANSMITTER_PRESENT) \
|| defined(SL_CATALOG_BLUETOOTH_FEATURE_AOD_TRANSMITTER_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, cte_transmitter);
#define SLI_BT_FEATURE_CTE_TRANSMITTER SLI_BT_USE_FEATURE(bt, cte_transmitter),
#define SLI_BT_BGAPI_CTE_TRANSMITTER SLI_BT_USE_BGAPI_CLASS(bt, cte_transmitter),
#else
#define SLI_BT_FEATURE_CTE_TRANSMITTER
#define SLI_BT_BGAPI_CTE_TRANSMITTER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_TEST_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, test);
#define SLI_BT_FEATURE_TEST SLI_BT_USE_FEATURE(bt, test),
#define SLI_BT_BGAPI_TEST SLI_BT_USE_BGAPI_CLASS(bt, test),
#else
#define SLI_BT_FEATURE_TEST
#define SLI_BT_BGAPI_TEST
#endif
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT)
#define SLI_BT_BGAPI_COEX SLI_BT_USE_BGAPI_CLASS(bt, coex),
#else
#define SLI_BT_BGAPI_COEX
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_RESOURCE_REPORT_PRESENT)
#define SLI_BT_BGAPI_RESOURCE SLI_BT_USE_BGAPI_CLASS(bt, resource),
#else
#define SLI_BT_BGAPI_RESOURCE
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_USE_ACCURATE_API_ADDRESS_TYPES_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, accurate_api_address_types);
#define SLI_BT_FEATURE_ACCURATE_API_ADDRESS_TYPES SLI_BT_USE_FEATURE(bt, accurate_api_address_types),
#else
#define SLI_BT_FEATURE_ACCURATE_API_ADDRESS_TYPES
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_ANALYZER_PRESENT)
#define SLI_BT_BGAPI_CONNECTION_ANALYZER SLI_BT_USE_BGAPI_CLASS(bt, connection_analyzer),
#else
#define SLI_BT_BGAPI_CONNECTION_ANALYZER
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_SUBRATING_PRESENT)
SLI_BT_DECLARE_FEATURE(bt, connection_subrate);
#define SLI_BT_FEATURE_CONNECTION_SUBRATE SLI_BT_USE_FEATURE(bt, connection_subrate),
#else
#define SLI_BT_FEATURE_CONNECTION_SUBRATE
#endif
/** @brief Structure that specifies the Bluetooth configuration */
static const sl_bt_configuration_t bt_config = SL_BT_CONFIG_DEFAULT;
/** @brief Table of used Bluetooth features */
static const struct sli_bt_feature_use bt_used_features[] =
{
// Invoke the feature inclusion macro for each feature. Depending on the build
// configuration, the feature inclusion rules above have defined the macro to
// either empty or the relevant feature use declaration.
SLI_BT_FEATURE_ON_DEMAND_START
SLI_BT_FEATURE_SYSTEM
SLI_BT_FEATURE_SM
SLI_BT_FEATURE_BUILTIN_BONDING_DATABASE
SLI_BT_FEATURE_EXTERNAL_BONDING_DATABASE
SLI_BT_FEATURE_ACCEPT_LIST
SLI_BT_FEATURE_RESOLVING_LIST
SLI_BT_FEATURE_SCANNER
SLI_BT_FEATURE_SCANNER_BASE
SLI_BT_FEATURE_EXTENDED_SCANNER
SLI_BT_FEATURE_SYNC
SLI_BT_FEATURE_SYNC_SCANNER
SLI_BT_FEATURE_ADVERTISER
SLI_BT_FEATURE_EXTENDED_ADVERTISER
SLI_BT_FEATURE_PERIODIC_ADVERTISER
SLI_BT_FEATURE_CS
SLI_BT_FEATURE_CS_TEST
SLI_BT_FEATURE_L2CAP
SLI_BT_FEATURE_CONNECTION
SLI_BT_FEATURE_CONNECTION_STATISTICS
SLI_BT_FEATURE_CONNECTION_SUBRATE
SLI_BT_FEATURE_DYNAMIC_GATTDB
SLI_BT_FEATURE_CTE_RECEIVER
SLI_BT_FEATURE_CTE_TRANSMITTER
SLI_BT_FEATURE_TEST
SLI_BT_FEATURE_POWER_CONTROL
SLI_BT_FEATURE_USER_POWER_CONTROL
SLI_BT_FEATURE_GATT
SLI_BT_FEATURE_ACCURATE_API_ADDRESS_TYPES
{ NULL, NULL }
};
/** @brief Table of used BGAPI classes */
static const struct sli_bgapi_class * const bt_bgapi_classes[] =
{
// Invoke the BGAPI class inclusion macro for each feature that provides a
// BGAPI class. Depending on the build configuration, the feature inclusion
// rules above have defined the macro to either empty or the relevant BGAPI
// class declaration.
SLI_BT_BGAPI_SYSTEM
SLI_BT_BGAPI_NVM
SLI_BT_BGAPI_GAP
SLI_BT_BGAPI_SM
SLI_BT_BGAPI_EXTERNAL_BONDINGDB
SLI_BT_BGAPI_ACCEPT_LIST
SLI_BT_BGAPI_RESOLVING_LIST
SLI_BT_BGAPI_ADVERTISER
SLI_BT_BGAPI_LEGACY_ADVERTISER
SLI_BT_BGAPI_EXTENDED_ADVERTISER
SLI_BT_BGAPI_PERIODIC_ADVERTISER
SLI_BT_BGAPI_PAWR_ADVERTISER
SLI_BT_BGAPI_SCANNER
SLI_BT_BGAPI_SYNC
SLI_BT_BGAPI_SYNC_SCANNER
SLI_BT_BGAPI_PERIODIC_SYNC
SLI_BT_BGAPI_PAWR_SYNC
SLI_BT_BGAPI_PAST_RECEIVER
SLI_BT_BGAPI_ADVERTISER_PAST
SLI_BT_BGAPI_SYNC_PAST
SLI_BT_BGAPI_CS
SLI_BT_BGAPI_CS_TEST
SLI_BT_BGAPI_L2CAP
SLI_BT_BGAPI_CONNECTION
SLI_BT_BGAPI_GATT
SLI_BT_BGAPI_DYNAMIC_GATTDB
SLI_BT_BGAPI_GATT_SERVER
SLI_BT_BGAPI_CTE_RECEIVER
SLI_BT_BGAPI_CTE_TRANSMITTER
SLI_BT_BGAPI_TEST
SLI_BT_BGAPI_COEX
SLI_BT_BGAPI_RESOURCE
SLI_BT_BGAPI_CONNECTION_ANALYZER
NULL
};
// Forward declaration of Bluetooth controller init functions
extern sl_status_t sl_bt_ll_deinit();
#include "sl_bt_ll_config.h"
extern sl_status_t ll_connPowerControlEnable(const sl_bt_ll_power_control_config_t *);
extern void sl_bt_init_app_controlled_tx_power();
extern sl_status_t sl_btctrl_init_sniff(uint8_t);
extern void sl_btctrl_deinit_sniff(void);
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT)
#include "coexistence-ble.h"
#endif
/**
* @brief Initialize controller features according to the feature selection.
*
* This function is called by the Bluetooth host stack when Bluetooth is started.
*/
sl_status_t sli_bt_init_controller_features()
{
sl_status_t status = SL_STATUS_OK;
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT)
sl_bt_init_coex_hal();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_MULTIPROTOCOL_PRESENT)
sl_btctrl_init_multiprotocol();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_RADIO_WATCHDOG_PRESENT)
sl_btctrl_enable_radio_watchdog();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PRESENT)
sl_btctrl_init_adv();
#endif
#if defined(SLI_BT_ENABLE_EXTENDED_ADVERTISER_FEATURE)
sl_btctrl_init_adv_ext();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SCANNER_PRESENT)
sl_btctrl_init_scan();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EVEN_SCHEDULING_PRESENT)
sl_btctrl_enable_even_connsch();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_PAWR_SCHEDULING_PRESENT)
sl_btctrl_enable_pawr_connsch();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_PRESENT)
sl_btctrl_init_conn();
#if !defined(SL_CATALOG_BLUETOOTH_CONNECTION_PHY_UPDATE_INCOMPATIBLE_PRESENT)
sl_btctrl_init_phy();
#endif
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_STATISTICS_PRESENT)
sl_btctrl_init_conn_statistics();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_SUBRATING_PRESENT)
sl_btctrl_init_subrate();
status = sl_btctrl_allocate_conn_subrate_memory(SL_BT_CONFIG_MAX_CONNECTIONS);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_POWER_CONTROL_PRESENT)
#include "sl_bt_power_control_config.h"
const sl_bt_ll_power_control_config_t power_control_config = {
.activate_power_control = SL_BT_ACTIVATE_POWER_CONTROL,
.golden_rssi_min_1m = SL_BT_GOLDEN_RSSI_MIN_1M,
.golden_rssi_max_1m = SL_BT_GOLDEN_RSSI_MAX_1M,
.golden_rssi_min_2m = SL_BT_GOLDEN_RSSI_MIN_2M,
.golden_rssi_max_2m = SL_BT_GOLDEN_RSSI_MAX_2M,
.golden_rssi_min_coded_s8 = SL_BT_GOLDEN_RSSI_MIN_CODED_S8,
.golden_rssi_max_coded_s8 = SL_BT_GOLDEN_RSSI_MAX_CODED_S8,
.golden_rssi_min_coded_s2 = SL_BT_GOLDEN_RSSI_MIN_CODED_S2,
.golden_rssi_max_coded_s2 = SL_BT_GOLDEN_RSSI_MAX_CODED_S2
};
status = ll_connPowerControlEnable(&power_control_config);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_USER_POWER_CONTROL_PRESENT)
sl_bt_init_app_controlled_tx_power();
#endif
#if defined(SLI_BT_ENABLE_EXTENDED_SCANNER_FEATURE)
sl_btctrl_init_scan_ext();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_ADVERTISER_PRESENT)
#include "sl_bt_periodic_advertiser_config.h"
sl_btctrl_init_periodic_adv();
sl_btctrl_alloc_periodic_adv(SL_BT_CONFIG_MAX_PERIODIC_ADVERTISERS);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_ADVERTISER_PRESENT)
#include "sl_bt_pawr_advertiser_config.h"
struct sl_btctrl_pawr_advertiser_config pawr_config = {
.max_pawr_sets = SL_BT_CONFIG_MAX_PAWR_ADVERTISERS,
.max_advertised_data_length_hint = SL_BT_CONFIG_MAX_PAWR_ADVERTISED_DATA_LENGTH_HINT,
.subevent_data_request_count = SL_BT_CONFIG_PAWR_PACKET_REQUEST_COUNT,
.subevent_data_request_advance = SL_BT_CONFIG_PAWR_PACKET_REQUEST_ADVANCE,
};
status = sl_btctrl_pawr_advertiser_configure(&pawr_config);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PRESENT)
#include "sl_bluetooth_periodic_sync_config.h"
sl_btctrl_init_periodic_scan();
status = sl_btctrl_alloc_periodic_scan(SL_BT_CONFIG_MAX_PERIODIC_ADVERTISING_SYNC);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_SYNC_PRESENT)
#include "sl_bt_pawr_sync_config.h"
struct sl_btctrl_pawr_synchronizer_config pawr_sync_config = {
.max_pawr_sets = SL_BT_CONFIG_MAX_PAWR_SYNCHRONIZERS,
};
status = sl_btctrl_pawr_synchronizer_configure(&pawr_sync_config);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_RESOLVING_LIST_PRESENT)
#include "sl_bt_resolving_list_config.h"
sl_btctrl_init_privacy();
status = sl_btctrl_allocate_resolving_list_memory(SL_BT_CONFIG_RESOLVING_LIST_SIZE);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_AFH_PRESENT)
status = sl_btctrl_init_afh(1);
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_HIGH_POWER_PRESENT)
sl_btctrl_init_highpower();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PHY_SUPPORT_CONFIG_PRESENT)
#include "sl_btctrl_phy_support_config.h"
#if SL_BT_CONTROLLER_2M_PHY_SUPPORT == 0
sl_btctrl_disable_2m_phy();
#endif
#if SL_BT_CONTROLLER_CODED_PHY_SUPPORT == 0
sl_btctrl_disable_coded_phy();
#endif
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_AOA_RECEIVER_PRESENT) \
|| defined(SL_CATALOG_BLUETOOTH_FEATURE_AOD_RECEIVER_PRESENT)
status = sl_btctrl_init_cte_receiver();
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_AOA_TRANSMITTER_PRESENT) \
|| defined(SL_CATALOG_BLUETOOTH_FEATURE_AOD_TRANSMITTER_PRESENT)
status = sl_btctrl_init_cte_transmitter();
if (status != SL_STATUS_OK) {
return status;
}
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PAST_PRESENT)
sl_btctrl_init_past_local_sync_transfer();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PAST_PRESENT)
sl_btctrl_init_past_remote_sync_transfer();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAST_RECEIVER_PRESENT)
sl_btctrl_init_past_receiver();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CS_PRESENT)
#include "sl_bluetooth_cs_config.h"
struct sl_btctrl_cs_config cs_config = { 0 };
cs_config.configs_per_connection = SL_BT_CONFIG_MAX_CS_CONFIGS_PER_CONNECTION;
cs_config.procedures = SL_BT_CONFIG_MAX_CS_PROCEDURES;
sl_btctrl_init_cs(&cs_config);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_ANALYZER_PRESENT)
#include "sl_bluetooth_connection_analyzer_config.h"
status = sl_btctrl_init_sniff(SL_BT_CONFIG_MAX_CONNECTION_ANALYZERS);
if (status != SL_STATUS_OK) {
return status;
}
#endif
return status;
}
/**
* @brief De-initialize controller features according to the feature selection.
*
* This function is called by the Bluetooth host stack when Bluetooth is stopped.
*/
void sli_bt_deinit_controller_features()
{
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_ANALYZER_PRESENT)
sl_btctrl_deinit_sniff();
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_RESOLVING_LIST_PRESENT)
sl_btctrl_allocate_resolving_list_memory(0);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PRESENT)
sl_btctrl_alloc_periodic_scan(0);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_ADVERTISER_PRESENT)
struct sl_btctrl_pawr_advertiser_config pawr_config = {
.max_pawr_sets = 0,
.max_advertised_data_length_hint = 0,
.subevent_data_request_count = 0,
.subevent_data_request_advance = 0,
};
(void) sl_btctrl_pawr_advertiser_configure(&pawr_config);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_SYNC_PRESENT)
struct sl_btctrl_pawr_synchronizer_config pawr_sync_config = {
.max_pawr_sets = 0,
};
(void) sl_btctrl_pawr_synchronizer_configure(&pawr_sync_config);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_ADVERTISER_PRESENT)
(void) sl_btctrl_alloc_periodic_adv(0);
#endif
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_SUBRATING_PRESENT)
sl_btctrl_allocate_conn_subrate_memory(0);
#endif
(void) sl_bt_ll_deinit();
}
// Initialize the Bluetooth stack.
sl_status_t sl_bt_stack_init()
{
// Initialize the Bluetooth stack with the given configuration, features, and BGAPI classes
return sli_bt_init_stack(&bt_config, bt_used_features, bt_bgapi_classes);
}

View File

@@ -0,0 +1,28 @@
/***************************************************************************//**
* @file sli_bt_accept_list_config.c
* @brief Configuration instance for "accept_list"
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_accept_list_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ACCEPT_LIST_PRESENT)
#include "sl_bt_accept_list_config.h"
SLI_BT_DEFINE_FEATURE_CONFIG(bt, accept_list, sli_bt_accept_list_config_t) = {
.accept_list_size = SL_BT_CONFIG_ACCEPT_LIST_SIZE
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_ACCEPT_LIST_PRESENT

View File

@@ -0,0 +1,33 @@
/***************************************************************************//**
* @file sli_bt_advertiser_config.c
* @brief Configuration instance for "advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_advertiser_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PRESENT)
#include "sl_bluetooth.h" // For SL_BT_COMPONENT_ADVERTISERS
#include "sl_bluetooth_config.h"
// Note that advertiser configuration is not dictated directly by the advertiser
// component's configuration file. The top-level Bluetooth stack configuration
// calculates a sum of all advertiser needs, and that value is used to configure
// the advertiser feature.
SLI_BT_DEFINE_FEATURE_CONFIG(bt, advertiser, sli_bt_advertiser_config_t) = {
.max_advertisers = SL_BT_CONFIG_MAX_ADVERTISERS
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_ADVERTISER_PRESENT

View File

@@ -0,0 +1,35 @@
/***************************************************************************//**
* @file sli_bt_connection_config.c
* @brief Configuration instanc for "connection"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_connection_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_PRESENT)
#include "sl_bluetooth.h" // For SL_BT_COMPONENT_CONNECTIONS
#include "sl_bluetooth_config.h"
#include "sl_bluetooth_connection_config.h"
// Note that connection configuration is not dictated directly by the connection
// component's configuration file. The top-level Bluetooth stack configuration
// calculates a sum of all connection needs, and that value is used to configure
// the connection feature.
SLI_BT_DEFINE_FEATURE_CONFIG(bt, connection, sli_bt_connection_config_t) = {
.max_connections = SL_BT_CONFIG_MAX_CONNECTIONS_SUM,
.data_len = SL_BT_CONFIG_CONNECTION_DATA_LENGTH
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_CONNECTION_PRESENT

View File

@@ -0,0 +1,41 @@
/***************************************************************************//**
* @file sli_bt_dynamic_gattdb_config.c
* @brief Configuration instance for "dynamic_gattdb"
*******************************************************************************
* # License
* <b> Copyright 2021 Silicon Laboratories Inc.www.silabs.com </b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc.Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement(MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_config_defs.h"
#include "sli_bt_gattdb_def.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_DYNAMIC_GATTDB_PRESENT)
#include "sl_bt_dynamic_gattdb_config.h"
#if SL_BT_GATTDB_ENABLE_GATT_CACHING == 1
#define GATTDB_ENABLE_GATT_CACHING SLI_BT_GATTDB_CONFIG_FLAG_ENABLE_GATT_CACHING
#else
#define GATTDB_ENABLE_GATT_CACHING 0
#endif
#if SL_BT_GATTDB_INCLUDE_STATIC_DATABASE == 1
#define GATTDB_INCLUDE_STATIC SLI_BT_GATTDB_CONFIG_FLAG_INCLUDE_STATIC_DB
#else
#define GATTDB_INCLUDE_STATIC 0
#endif
#else // SL_CATALOG_BLUETOOTH_FEATURE_DYNAMIC_GATTDB_PRESENT
#define GATTDB_ENABLE_GATT_CACHING SLI_BT_GATTDB_CONFIG_FLAG_ENABLE_GATT_CACHING
#define GATTDB_INCLUDE_STATIC SLI_BT_GATTDB_CONFIG_FLAG_INCLUDE_STATIC_DB
#endif // SL_CATALOG_BLUETOOTH_FEATURE_DYNAMIC_GATTDB_PRESENT
SLI_BT_DEFINE_FEATURE_CONFIG(bt, dynamic_gattdb, sli_bt_gattdb_config_t) = {
.flags = (GATTDB_ENABLE_GATT_CACHING | GATTDB_INCLUDE_STATIC)
};

View File

@@ -0,0 +1,278 @@
/***************************************************************************//**
* @brief System adaptation layer used internally by Bluetooth host stack
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sli_bt_host_adaptation.h"
#include "sl_bluetooth_config.h"
#include "sl_bt_host_adaptation_config.h"
#include "sl_bt_api.h"
#include "sl_assert.h"
#include "sl_core.h"
#include "em_device.h"
#include "sl_component_catalog.h"
#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
#include "btl_interface.h"
#endif
#if defined(SL_CATALOG_KERNEL_PRESENT)
#include "sl_bt_rtos_adaptation.h"
// When a kernel is present, the task wakeups are handled by RTOS adaptation
sli_bt_linklayer_wakeup_t *const sli_bt_host_adaptation_linklayer_wakeup = sli_bt_rtos_ll_callback;
sli_bt_host_wakeup_t *const sli_bt_host_adaptation_host_wakeup = sli_bt_rtos_stack_callback;
#else // defined(SL_CATALOG_KERNEL_PRESENT)
// When a kernel is not present, the host task wakeup is not needed, as the
// baremetal main loop will service the host stack. The linklayer task is
// handled as a PendSV interrupt.
/**
* Override @ref PendSV_Handler for the Link Layer task when Bluetooth runs
* in baremetal mode. The override must not exist when Bluetooth runs in an RTOS
* where the link layer task runs in a thread.
*/
void PendSV_Handler()
{
sl_bt_priority_handle();
}
static void sli_bt_trigger_pendsv_interrupt(void)
{
// Trigger the PendSV interrupt
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
sli_bt_linklayer_wakeup_t *const sli_bt_host_adaptation_linklayer_wakeup = sli_bt_trigger_pendsv_interrupt;
sli_bt_host_wakeup_t *const sli_bt_host_adaptation_host_wakeup = NULL;
#endif // defined(SL_CATALOG_KERNEL_PRESENT)
// Initialize the device interrupts in a baremetal app
void sli_bt_host_adaptation_init_interrupts(void)
{
// The Bluetooth host stack system adaptation initializates the interrupt
// configuration only when an RTOS kernel is not present in the application,
// i.e. when the application is a baremetal application. When an RTOS is
// present, the interrupts are configured by the RTOS.
#if !defined(SL_CATALOG_KERNEL_PRESENT)
// Perform a compile-time validity check for the configuration. If BASEPRI is
// used as the method for atomic sections, the atomic level must be higher
// than or equal to the priority of the radio and link layer interrupts to
// ensure proper atomic sections in the Bluetooth stack. A lower number means
// higher priority.
#if (CORE_ATOMIC_METHOD == CORE_ATOMIC_METHOD_BASEPRI)
#if (CORE_ATOMIC_BASE_PRIORITY_LEVEL > SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY)
#error Bluetooth EFR32 HAL: Invalid configuration CORE_ATOMIC_BASE_PRIORITY_LEVEL > SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY
#endif
#if (CORE_ATOMIC_BASE_PRIORITY_LEVEL > SL_BT_HOST_ADAPTATION_LINKLAYER_IRQ_PRIORITY)
#error Bluetooth EFR32 HAL: Invalid configuration CORE_ATOMIC_BASE_PRIORITY_LEVEL > SL_BT_HOST_ADAPTATION_LINKLAYER_IRQ_PRIORITY
#endif
#endif // (CORE_ATOMIC_METHOD == CORE_ATOMIC_METHOD_BASEPRI)
// Set the priorities to the NVIC
NVIC_SetPriority(FRC_PRI_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(FRC_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(MODEM_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(RAC_SEQ_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(RAC_RSM_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(BUFC_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(PROTIMER_IRQn, SL_BT_HOST_ADAPTATION_RADIO_IRQ_PRIORITY);
NVIC_SetPriority(PendSV_IRQn, SL_BT_HOST_ADAPTATION_LINKLAYER_IRQ_PRIORITY);
// Clear the PendSV interrupt
NVIC_ClearPendingIRQ(PendSV_IRQn);
#endif // !defined(SL_CATALOG_KERNEL_PRESENT)
}
// Get the bootloader version information
sl_status_t sli_bt_host_adaptation_get_bootloader_version(uint32_t *bootloader_version)
{
EFM_ASSERT(bootloader_version != NULL);
#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
// Bootloader is available. Query the version from there.
BootloaderInformation_t btl_info;
memset(&btl_info, 0, sizeof(btl_info));
bootloader_getInfo(&btl_info);
*bootloader_version = btl_info.version;
return SL_STATUS_OK;
#else // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT
// Bootloader is not available
*bootloader_version = 0;
return SL_STATUS_NOT_AVAILABLE;
#endif // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT
}
// Reset the chip
void sli_bt_host_adaptation_chip_reset(void)
{
CORE_ResetSystem();
}
#if defined(SL_CATALOG_NVM3_PRESENT)
#include "nvm3_generic.h"
#include "nvm3_default.h"
/**
* @brief NVM3 handle used for NVM3 in the Bluetooth host stack
*/
#define SL_BT_NVM3 (nvm3_defaultHandle)
/**
* @brief NVM3 key for custom Bluetooth address type. Value 1 byte: 0 for public type, 1 for static
*/
#define SLI_BT_NVM3_LOCAL_BD_ADDR_TYPE 0x4003c
/**
* @brief NVM3 key for custom Bluetooth address. Value: 6 bytes in little endian
*/
#define SLI_BT_NVM3_LOCAL_BD_ADDR 0x4002c
/**
* @brief Length of a Bluetooth address
*/
#define SLI_BT_BD_ADDRESS_LEN 6
sl_status_t sli_bt_host_adaptation_write_custom_address(uint8_t address_type,
const uint8_t *address)
{
if ((address_type != sl_bt_gap_public_address)
&& (address_type != sl_bt_gap_static_address)) {
return SL_STATUS_INVALID_PARAMETER;
}
sl_status_t result = nvm3_open(SL_BT_NVM3, nvm3_defaultInit);
if (result != SL_STATUS_OK) {
return result;
}
// 00:00:00:00:00:00 or ff:ff:ff:ff:ff:ff is used to reset the custom address.
// Delete the NVM3 keys and the default address will be used in the next reboot.
uint8_t all_bit_1_address[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
uint8_t all_bit_0_address[SLI_BT_BD_ADDRESS_LEN] = { 0x00 };
if ((memcmp(address, all_bit_1_address, SLI_BT_BD_ADDRESS_LEN) == 0)
|| (memcmp(address, all_bit_0_address, SLI_BT_BD_ADDRESS_LEN) == 0)) {
result = nvm3_deleteObject(SL_BT_NVM3, SLI_BT_NVM3_LOCAL_BD_ADDR_TYPE);
if ((result == SL_STATUS_OK) || (result == SL_STATUS_NOT_FOUND)) {
result = nvm3_deleteObject(SL_BT_NVM3, SLI_BT_NVM3_LOCAL_BD_ADDR);
}
if (result == SL_STATUS_NOT_FOUND) {
result = SL_STATUS_OK;
}
return result;
}
// A static device address needs set two MSB bits to 1
if (address_type == sl_bt_gap_static_address && (address[5] >> 6) != 3) {
return SL_STATUS_INVALID_PARAMETER;
}
if (address_type == sl_bt_gap_public_address) {
result = nvm3_deleteObject(SL_BT_NVM3, SLI_BT_NVM3_LOCAL_BD_ADDR_TYPE);
if (result == SL_STATUS_NOT_FOUND) {
result = SL_STATUS_OK;
}
} else {
result = nvm3_writeData(SL_BT_NVM3,
SLI_BT_NVM3_LOCAL_BD_ADDR_TYPE,
(void*) &address_type,
sizeof(address_type));
}
if (result == SL_STATUS_OK) {
result = nvm3_writeData(SL_BT_NVM3,
SLI_BT_NVM3_LOCAL_BD_ADDR,
(void*) address,
SLI_BT_BD_ADDRESS_LEN);
}
return result;
}
#else
sl_status_t sli_bt_host_adaptation_write_custom_address(uint8_t address_type,
const uint8_t *address)
{
(void) address_type;
(void) address;
// The user application does not use NVM3
return SL_STATUS_NOT_AVAILABLE;
}
#endif // SL_CATALOG_NVM3_PRESENT
// Load custom Bluetooth identity address from NVM3
sl_status_t sli_bt_host_adaptation_read_custom_address(uint8_t *address_type,
uint8_t *address)
{
#if (SL_BT_CONFIG_SET_CUSTOM_ADDRESS_FROM_NVM3 == 1) && defined(SL_CATALOG_NVM3_PRESENT)
if (!address_type || !address) {
return SL_STATUS_INVALID_PARAMETER;
}
sl_status_t result = nvm3_open(SL_BT_NVM3, nvm3_defaultInit);
if (result == SL_STATUS_OK) {
// Read the address in NVM3
result = nvm3_readData(SL_BT_NVM3, SLI_BT_NVM3_LOCAL_BD_ADDR, address, SLI_BT_BD_ADDRESS_LEN);
}
if (result == SL_STATUS_OK) {
// Read the address type in NVM3. Treat the address as public device address if error
sl_status_t read_type_result = nvm3_readData(SL_BT_NVM3, SLI_BT_NVM3_LOCAL_BD_ADDR_TYPE, address_type, sizeof(*address_type));
if (read_type_result != SL_STATUS_OK) {
*address_type = 0;
}
}
return result;
#else
// The user application does not use custom address, or NVM3 does not present
(void) address_type;
(void) address;
return SL_STATUS_NOT_FOUND;
#endif // (SL_BT_CONFIG_SET_CUSTOM_ADDRESS_FROM_NVM3 == 1) && defined(SL_CATALOG_NVM3_PRESENT)
}
#if (SL_BT_CONFIG_SET_CTUNE_FROM_NVM3 == 1) && defined(SL_CATALOG_NVM3_PRESENT)
#include "em_cmu.h"
/**
* @brief NVM3 key for custom CTUNE in Bluetooth NVM3 space. Value 2 bytes
*/
#define SLI_BT_NVM3_CTUNE 0x40032
// Set HFXO CTUNE using the value stored in the Bluetooth space of NVM3.
void sli_bt_host_adaptation_read_and_set_ctune()
{
uint16_t ctune;
sl_status_t err = nvm3_open(SL_BT_NVM3, nvm3_defaultInit);
if (err == SL_STATUS_OK) {
err = nvm3_readData(SL_BT_NVM3, SLI_BT_NVM3_CTUNE, &ctune, sizeof(ctune));
}
if (err == SL_STATUS_OK) {
// Setting CTUNE could fail and we do it with best effort. Please find CTUNE and
// its calibration related details in the platform.
err = CMU_HFXOCTuneSet(ctune);
(void) err;
}
}
#else
void sli_bt_host_adaptation_read_and_set_ctune()
{
// Feature is disabled. Do nothing.
}
#endif // #if (SL_BT_CONFIG_SET_CTUNE_FROM_NVM3 == 1) && defined(SL_CATALOG_NVM3_PRESENT)

View File

@@ -0,0 +1,35 @@
/***************************************************************************//**
* @file sli_bt_l2cap_config.c
* @brief Configuration instance for "l2cap"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_l2cap_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_L2CAP_PRESENT)
#include "sl_bluetooth_l2cap_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_EATT)
// Each Enhanced ATT bearer requires an L2CAP COC channel
#include "sl_bt_eatt_config.h"
#define SL_BT_CONFIG_MAX_L2CAP_CHANNELS (SL_BT_CONFIG_USER_L2CAP_COC_CHANNELS + SL_BT_CONFIG_USER_EATT_BEARERS)
#else
#define SL_BT_CONFIG_MAX_L2CAP_CHANNELS SL_BT_CONFIG_USER_L2CAP_COC_CHANNELS
#endif
SLI_BT_DEFINE_FEATURE_CONFIG(bt, l2cap, sli_bt_l2cap_config_t) = {
.max_l2cap_coc_channels = SL_BT_CONFIG_MAX_L2CAP_CHANNELS
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_L2CAP_PRESENT

View File

@@ -0,0 +1,28 @@
/***************************************************************************//**
* @file sli_bt_pawr_advertiser_config.c
* @brief Configuration instance for "pawr_advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_pawr_advertiser_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PAWR_ADVERTISER_PRESENT)
#include "sl_bt_pawr_advertiser_config.h"
SLI_BT_DEFINE_FEATURE_CONFIG(bt, pawr_advertiser, sli_bt_pawr_advertiser_config_t) = {
.max_pawr_advertisers = SL_BT_CONFIG_MAX_PAWR_ADVERTISERS
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_PAWR_ADVERTISER_PRESENT

View File

@@ -0,0 +1,28 @@
/***************************************************************************//**
* @file sli_bt_periodic_advertiser_config.c
* @brief Configuration instance for "periodic_advertiser"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_periodic_advertiser_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_ADVERTISER_PRESENT)
#include "sl_bt_periodic_advertiser_config.h"
SLI_BT_DEFINE_FEATURE_CONFIG(bt, periodic_advertiser, sli_bt_periodic_advertiser_config_t) = {
.max_periodic_advertisers = SL_BT_CONFIG_MAX_PERIODIC_ADVERTISERS
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_PERIODIC_ADVERTISER_PRESENT

View File

@@ -0,0 +1,28 @@
/***************************************************************************//**
* @file sli_bt_sync_config.c
* @brief Configuration instance for "sync"
*******************************************************************************
* # License
* <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "sl_component_catalog.h"
#include "sli_bt_sync_config.h"
#if defined(SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PRESENT)
#include "sl_bluetooth_periodic_sync_config.h"
SLI_BT_DEFINE_FEATURE_CONFIG(bt, sync, sli_bt_sync_config_t) = {
.max_periodic_syncs = SL_BT_CONFIG_MAX_PERIODIC_ADVERTISING_SYNC
};
#endif // SL_CATALOG_BLUETOOTH_FEATURE_SYNC_PRESENT

View File

@@ -0,0 +1,64 @@
/*******************************************************************************
* @file
* @brief Provides definitions required to support CLI in both SoC and RCP
* builds
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 <openthread/cli.h>
extern otCliCommand sl_ot_custom_commands[];
extern const uint8_t sl_ot_custom_commands_count;
/**
* Iterates over list of commands in @p aCommands to match the name
* of the command referred to in @p aArgs and execute the handler
* function if found.
*
* @param[in] *aContext Pointer to openthread instance
* @param[in] aArgsLength Number of arguments in @p aArgs
* @param[in] *aArgs[] Array of arguments to pass to handler
* @param[in] aCommandsLength Number of subcommands in @p aCommands
* @param[in] aCommands[] List of subcommands registered by cli module
*
* @returns The result of the executed handler, or OT_ERROR_INVALID_ARGS if command was not found.
*/
otError processCommand(void *aContext,
uint8_t aArgsLength,
char *aArgs[],
uint8_t aCommandsLength,
const otCliCommand aCommands[]);
/**
* Print all commands in @p commands
*
* @param[in] commands list of commands
* @param[in] commandCount number of commands in @p commands
*
*/
void printCommands(otCliCommand commands[], size_t commandCount);

View File

@@ -0,0 +1,580 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for the alarm.
*
*/
#include <assert.h>
#include <openthread-core-config.h>
#include <openthread-system.h>
#include <stdbool.h>
#include <stdint.h>
#include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include "common/debug.hpp"
#include "common/logging.hpp"
#include "alarm.h"
#include "platform-efr32.h"
#include "utils/code_utils.h"
#include "rail.h"
#include "sl_core.h"
#include "sl_multipan.h"
#include "sl_sleeptimer.h"
#ifndef TESTING
#define STATIC static
#else
#define STATIC
#endif
// timer data for handling wrapping
typedef struct wrap_timer_data wrap_timer_data_t;
struct wrap_timer_data
{
uint16_t overflow_counter;
uint16_t overflow_max;
};
// millisecond timer (sleeptimer)
static sl_sleeptimer_timer_handle_t sl_handle[OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM];
// microsecond timer (RAIL timer)
static RAIL_MultiTimer_t rail_timer[OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM];
// forward declare generic alarm handle
struct AlarmHandle;
// function pointers for timer operations
typedef void (*timerStartFunc)(struct AlarmHandle *, uint32_t);
typedef uint32_t (*timerMaxFunc)(void);
typedef uint32_t (*timerGetTimeFunc)(void);
typedef void (*timerStopFunc)(struct AlarmHandle *);
// alarm handle structure
typedef struct AlarmHandle AlarmHandle;
struct AlarmHandle
{
otInstance *mThreadInstance;
void *mTimerHandle;
timerStartFunc mTimerStart;
timerMaxFunc mTimerGetMax;
timerGetTimeFunc mTimerGetNow;
timerStopFunc mTimerStop;
wrap_timer_data_t mWrapData;
volatile bool mIsRunning;
volatile int mFiredCount;
};
// callback function for the stack
typedef void (*StackAlarmCallback)(otInstance *);
// alarm handle instances
static AlarmHandle sMsAlarmHandles[OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM];
static AlarmHandle sUsAlarmHandles[OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM];
static uint64_t sPendingTimeMs[OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM];
// millisecond-alarm callback
STATIC void msAlarmCallback(sl_sleeptimer_timer_handle_t *aHandle, void *aData);
// microsecond-alarm callback
STATIC void usAlarmCallback(struct RAIL_MultiTimer *tmr, RAIL_Time_t expectedTimeOfEvent, void *cbArg);
// timer specific operations
static void msTimerStart(AlarmHandle *aMsAlarm, uint32_t aAlarmDuration);
static uint32_t msTimerGetMaxTime(void);
static uint32_t msTimerGetNow(void);
static void msTimerStop(AlarmHandle *aMsAlarm);
static void usTimerStart(AlarmHandle *aUsAlarm, uint32_t aAlarmDuration);
static uint32_t usTimerGetMaxTime(void);
static uint32_t usTimerGetNow(void);
static void usTimerStop(AlarmHandle *aUsAlarm);
// overflow utility functions
static inline bool isAlarmOverflowInProgress(AlarmHandle *aAlarm);
// common timer operations
static void FireAlarm(AlarmHandle *aAlarm);
static void StartAlarmAt(AlarmHandle *aAlarm, uint32_t aT0, uint32_t aDt);
static void StopActiveAlarm(AlarmHandle *aAlarm);
static void AlarmCallback(AlarmHandle *aAlarm);
// pending time utility functions
static inline uint64_t GetPendingTime(otInstance *aInstance);
static inline void SetPendingTime(otInstance *aInstance, uint64_t aPendingTime);
// alarm handle utility functions
static inline AlarmHandle *GetAlarmHandle(AlarmHandle *aHandleList, otInstance *aInstance);
static AlarmHandle *GetFirstFiredAlarm(AlarmHandle *aAlarm);
static AlarmHandle *GetNextFiredAlarm(AlarmHandle *aAlarm, const AlarmHandle *aAlarmEnd);
static inline bool HasAnyAlarmFired(void);
static inline uint32_t SetAlarmWrappedDuration(AlarmHandle *aAlarm, uint64_t aRemainingTime);
static void msTimerStart(AlarmHandle *aMsAlarm, uint32_t aAlarmDuration)
{
OT_ASSERT(aMsAlarm != NULL);
OT_ASSERT(aMsAlarm->mIsRunning == false);
sl_status_t status = sl_sleeptimer_start_timer_ms(aMsAlarm->mTimerHandle,
aAlarmDuration,
msAlarmCallback,
(void *)aMsAlarm,
0,
SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG);
#if OPENTHREAD_CONFIG_ASSERT_ENABLE
OT_ASSERT(status == SL_STATUS_OK);
#else
OT_UNUSED_VARIABLE(status);
#endif
}
static uint32_t msTimerGetMaxTime(void)
{
return sl_sleeptimer_get_max_ms32_conversion();
}
static uint32_t msTimerGetNow(void)
{
uint64_t ticks;
uint64_t now;
sl_status_t status;
ticks = sl_sleeptimer_get_tick_count64();
status = sl_sleeptimer_tick64_to_ms(ticks, &now);
#if OPENTHREAD_CONFIG_ASSERT_ENABLE
OT_ASSERT(status == SL_STATUS_OK);
#else
OT_UNUSED_VARIABLE(status);
#endif
return (uint32_t)now;
}
static void msTimerStop(AlarmHandle *aMsAlarm)
{
OT_ASSERT(aMsAlarm != NULL);
sl_sleeptimer_stop_timer((sl_sleeptimer_timer_handle_t *)aMsAlarm->mTimerHandle);
}
static void usTimerStart(AlarmHandle *aUsAlarm, uint32_t aAlarmDuration)
{
OT_ASSERT(aUsAlarm != NULL);
OT_ASSERT(aUsAlarm->mIsRunning == false);
RAIL_Status_t status =
RAIL_SetMultiTimer(aUsAlarm->mTimerHandle, aAlarmDuration, RAIL_TIME_DELAY, usAlarmCallback, (void *)aUsAlarm);
#if OPENTHREAD_CONFIG_ASSERT_ENABLE
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
#else
OT_UNUSED_VARIABLE(status);
#endif
}
static uint32_t usTimerGetMaxTime(void)
{
return UINT32_MAX;
}
static uint32_t usTimerGetNow(void)
{
return RAIL_GetTime();
}
static void usTimerStop(AlarmHandle *aUsAlarm)
{
OT_ASSERT(aUsAlarm != NULL);
RAIL_CancelMultiTimer((struct RAIL_MultiTimer *)aUsAlarm->mTimerHandle);
}
static inline bool isAlarmOverflowInProgress(AlarmHandle *aAlarm)
{
OT_ASSERT(aAlarm != NULL);
return aAlarm->mWrapData.overflow_counter < aAlarm->mWrapData.overflow_max;
}
static void FireAlarm(AlarmHandle *aAlarm)
{
OT_ASSERT(aAlarm != NULL);
aAlarm->mFiredCount++;
StopActiveAlarm(aAlarm);
otSysEventSignalPending();
}
static void ProcessAlarm(AlarmHandle *aAlarm, StackAlarmCallback aCallback)
{
OT_ASSERT(aAlarm != NULL);
otInstance *instance = aAlarm->mThreadInstance;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_ATOMIC();
int numCallbacks = aAlarm->mFiredCount;
aAlarm->mFiredCount = 0;
CORE_EXIT_ATOMIC();
while (numCallbacks > 0)
{
numCallbacks--;
aCallback(instance);
}
}
static inline uint32_t SetAlarmWrappedDuration(AlarmHandle *aAlarm, uint64_t aRemainingTime)
{
OT_ASSERT(aAlarm != NULL);
uint64_t initial_wrap_time = aRemainingTime;
wrap_timer_data_t wrapData = {0};
if (initial_wrap_time > aAlarm->mTimerGetMax())
{
initial_wrap_time %= aAlarm->mTimerGetMax();
wrapData.overflow_max = (uint16_t)(aRemainingTime / aAlarm->mTimerGetMax());
wrapData.overflow_counter = 0;
}
aAlarm->mWrapData = wrapData;
return (uint32_t)initial_wrap_time;
}
static void StartAlarmAt(AlarmHandle *aAlarm, uint32_t aT0, uint32_t aDt)
{
OT_ASSERT(aAlarm != NULL);
otEXPECT(sl_ot_rtos_task_can_access_pal());
StopActiveAlarm(aAlarm);
uint64_t requested_time = (uint64_t)aT0 + (uint64_t)aDt;
int64_t remaining = (int64_t)requested_time - (int64_t)aAlarm->mTimerGetNow();
if (remaining <= 0)
{
FireAlarm(aAlarm);
}
else
{
aAlarm->mTimerStart(aAlarm, SetAlarmWrappedDuration(aAlarm, (uint64_t)remaining));
aAlarm->mIsRunning = true;
}
exit:
return;
}
static void StopActiveAlarm(AlarmHandle *aAlarm)
{
OT_ASSERT(aAlarm != NULL);
otEXPECT(aAlarm->mIsRunning);
otEXPECT(sl_ot_rtos_task_can_access_pal());
aAlarm->mTimerStop(aAlarm);
aAlarm->mIsRunning = false;
exit:
return;
}
static void AlarmCallback(AlarmHandle *aAlarm)
{
OT_ASSERT(aAlarm != NULL);
if (isAlarmOverflowInProgress(aAlarm))
{
aAlarm->mIsRunning = false;
aAlarm->mWrapData.overflow_counter++;
aAlarm->mTimerStart(aAlarm, aAlarm->mTimerGetMax());
}
else
{
FireAlarm(aAlarm);
}
}
static inline uint64_t GetPendingTime(otInstance *aInstance)
{
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
efr32Iid_t currentIid = (efr32Iid_t)efr32GetIidFromInstance(aInstance);
OT_ASSERT(currentIid <= OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM);
return sPendingTimeMs[currentIid - 1];
#else
OT_UNUSED_VARIABLE(aInstance);
return sPendingTimeMs[0];
#endif
}
static inline void SetPendingTime(otInstance *aInstance, uint64_t aPendingTime)
{
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
efr32Iid_t currentIid = (efr32Iid_t)efr32GetIidFromInstance(aInstance);
OT_ASSERT(currentIid <= OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM);
sPendingTimeMs[currentIid - 1] = aPendingTime;
#else
OT_UNUSED_VARIABLE(aInstance);
sPendingTimeMs[0] = aPendingTime;
#endif
}
static inline AlarmHandle *GetAlarmHandle(AlarmHandle *aHandleList, otInstance *aInstance)
{
AlarmHandle *alarmHandle = aHandleList;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
efr32Iid_t currentIid = (efr32Iid_t)efr32GetIidFromInstance(aInstance);
OT_ASSERT(currentIid <= OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM);
alarmHandle = aHandleList + ((uint8_t)(currentIid - 1));
#else
OT_UNUSED_VARIABLE(aInstance);
#endif
return alarmHandle;
}
static AlarmHandle *GetFirstFiredAlarm(AlarmHandle *aHandleList)
{
return GetNextFiredAlarm(aHandleList, aHandleList + OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM);
}
static AlarmHandle *GetNextFiredAlarm(AlarmHandle *aAlarm, const AlarmHandle *aAlarmEnd)
{
AlarmHandle *nextAlarm = aAlarm;
while (nextAlarm && nextAlarm->mFiredCount == 0 && nextAlarm < aAlarmEnd)
{
nextAlarm++;
}
if (nextAlarm >= aAlarmEnd)
{
nextAlarm = NULL;
}
return nextAlarm;
}
static inline bool HasAnyAlarmFired(void)
{
return (GetFirstFiredAlarm(sMsAlarmHandles) != NULL) || (GetFirstFiredAlarm(sUsAlarmHandles) != NULL);
}
// millisecond-alarm callback
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_OT_PLATFORM_ABSTRACTION, SL_CODE_CLASS_TIME_CRITICAL)
STATIC void msAlarmCallback(sl_sleeptimer_timer_handle_t *aHandle, void *aData)
{
OT_UNUSED_VARIABLE(aHandle);
AlarmCallback((AlarmHandle *)aData);
}
// microsecond-alarm callback
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_OT_PLATFORM_ABSTRACTION, SL_CODE_CLASS_TIME_CRITICAL)
STATIC void usAlarmCallback(struct RAIL_MultiTimer *tmr, RAIL_Time_t expectedTimeOfEvent, void *cbArg)
{
OT_UNUSED_VARIABLE(tmr);
OT_UNUSED_VARIABLE(expectedTimeOfEvent);
AlarmCallback((AlarmHandle *)cbArg);
}
void efr32AlarmInit(void)
{
memset(&sl_handle, 0, sizeof sl_handle);
memset(&rail_timer, 0, sizeof rail_timer);
for (uint8_t i = 0; i < OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM; i++)
{
sPendingTimeMs[i] = 0;
sMsAlarmHandles[i].mThreadInstance = NULL;
sMsAlarmHandles[i].mTimerHandle = &sl_handle[i];
sMsAlarmHandles[i].mTimerStart = msTimerStart;
sMsAlarmHandles[i].mTimerGetMax = msTimerGetMaxTime;
sMsAlarmHandles[i].mTimerGetNow = msTimerGetNow;
sMsAlarmHandles[i].mTimerStop = msTimerStop;
sMsAlarmHandles[i].mIsRunning = false;
sMsAlarmHandles[i].mFiredCount = 0;
memset(&sMsAlarmHandles[i].mWrapData, 0, sizeof(wrap_timer_data_t));
sUsAlarmHandles[i].mThreadInstance = NULL;
sUsAlarmHandles[i].mTimerHandle = &rail_timer[i];
sUsAlarmHandles[i].mTimerStart = usTimerStart;
sUsAlarmHandles[i].mTimerGetMax = usTimerGetMaxTime;
sUsAlarmHandles[i].mTimerGetNow = usTimerGetNow;
sUsAlarmHandles[i].mTimerStop = usTimerStop;
sUsAlarmHandles[i].mIsRunning = false;
sUsAlarmHandles[i].mFiredCount = 0;
memset(&sUsAlarmHandles[i].mWrapData, 0, sizeof(wrap_timer_data_t));
}
}
void efr32AlarmProcess(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
otEXPECT(HasAnyAlarmFired());
AlarmHandle *msAlarm = GetFirstFiredAlarm(sMsAlarmHandles);
const AlarmHandle *msAlarmEnd = sMsAlarmHandles + OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM;
StackAlarmCallback alarmCb;
while (msAlarm != NULL)
{
#if OPENTHREAD_CONFIG_DIAG_ENABLE
if (otPlatDiagModeGet())
{
alarmCb = otPlatDiagAlarmFired;
}
else
#endif
{
alarmCb = otPlatAlarmMilliFired;
}
ProcessAlarm(msAlarm, alarmCb);
msAlarm = GetNextFiredAlarm(msAlarm, msAlarmEnd);
}
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
AlarmHandle *usAlarm = GetFirstFiredAlarm(sUsAlarmHandles);
const AlarmHandle *usAlarmEnd = sUsAlarmHandles + OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM;
while (usAlarm != NULL)
{
alarmCb = otPlatAlarmMicroFired;
ProcessAlarm(usAlarm, alarmCb);
usAlarm = GetNextFiredAlarm(usAlarm, usAlarmEnd);
}
#endif
exit:
return;
}
uint64_t efr32AlarmPendingTime(otInstance *aInstance)
{
uint64_t remaining = GetPendingTime(aInstance);
uint32_t now = otPlatAlarmMilliGetNow();
otEXPECT_ACTION(GetAlarmHandle(sMsAlarmHandles, aInstance)->mIsRunning, remaining = 0);
if (remaining > now)
{
remaining -= (uint64_t)now;
}
exit:
return remaining;
}
bool efr32AlarmIsRunning(otInstance *aInstance)
{
return (otInstanceIsInitialized(aInstance) ? GetAlarmHandle(sMsAlarmHandles, aInstance)->mIsRunning : false);
}
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
// Callback to determine if the system can sleep after an interrupt has fired
bool efr32AlarmIsReady(void)
{
return HasAnyAlarmFired();
}
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
uint32_t otPlatAlarmMilliGetNow(void)
{
return sMsAlarmHandles[0].mTimerGetNow();
}
uint16_t otPlatTimeGetXtalAccuracy(void)
{
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
// For sleepies, we need to account for the low-frequency crystal
// accuracy when they go to sleep. Accounting for that as well,
// for the worst case.
if (efr32AllowSleepCallback())
{
return SL_OPENTHREAD_HFXO_ACCURACY + SL_OPENTHREAD_LFXO_ACCURACY;
}
#endif
return SL_OPENTHREAD_HFXO_ACCURACY;
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
AlarmHandle *alarm = GetAlarmHandle(sMsAlarmHandles, aInstance);
if (alarm->mThreadInstance == NULL)
{
alarm->mThreadInstance = aInstance;
}
SetPendingTime(aInstance, (uint64_t)aT0 + (uint64_t)aDt);
CORE_ATOMIC_SECTION(StartAlarmAt(alarm, aT0, aDt);)
}
void otPlatAlarmMilliStop(otInstance *aInstance)
{
CORE_ATOMIC_SECTION(StopActiveAlarm(GetAlarmHandle(sMsAlarmHandles, aInstance));)
}
uint32_t otPlatAlarmMicroGetNow(void)
{
return sUsAlarmHandles[0].mTimerGetNow();
}
// Note: This function should be called at least once per wrap
// period for the wrap-around logic to work below
uint64_t otPlatTimeGet(void)
{
static uint32_t timerWraps = 0U;
static uint32_t prev32TimeUs = 0U;
uint32_t now32TimeUs;
uint64_t now64TimeUs;
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
now32TimeUs = RAIL_GetTime();
if (now32TimeUs < prev32TimeUs)
{
timerWraps += 1U;
}
prev32TimeUs = now32TimeUs;
now64TimeUs = ((uint64_t)timerWraps << 32) + now32TimeUs;
CORE_EXIT_CRITICAL();
return now64TimeUs;
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
AlarmHandle *alarm = GetAlarmHandle(sUsAlarmHandles, aInstance);
if (alarm->mThreadInstance == NULL)
{
alarm->mThreadInstance = aInstance;
}
CORE_ATOMIC_SECTION(StartAlarmAt(alarm, aT0, aDt);)
}
void otPlatAlarmMicroStop(otInstance *aInstance)
{
CORE_ATOMIC_SECTION(StopActiveAlarm(GetAlarmHandle(sUsAlarmHandles, aInstance));)
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file defines platform specific alarm methods.
*
*/
#ifndef _ALARM_H
#define _ALARM_H
#include <stdbool.h>
#include <stdint.h>
#include "openthread/instance.h"
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
/**
* This function determines whether the device should sleep after an alarm triggers.
*/
bool efr32AlarmIsReady(void);
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
/**
* This function initializes the alarm service used by OpenThread.
*
*/
void efr32AlarmInit(void);
/**
* This function provides the remaining time (in milliseconds) on an alarm service.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
uint64_t efr32AlarmPendingTime(otInstance *aInstance);
/**
* This function checks if the alarm service is running.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
bool efr32AlarmIsRunning(otInstance *aInstance);
/**
* This function performs alarm driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void efr32AlarmProcess(otInstance *aInstance);
#endif // _ALARM_H

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes compile-time configuration constants for efr32.
*
*/
#ifndef __BOARD_CONFIG_H__
#define __BOARD_CONFIG_H__
#if (!defined(RADIO_CONFIG_SUBGHZ_SUPPORT) || !RADIO_CONFIG_SUBGHZ_SUPPORT)
#define RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT 1 /// Enable OQPSK modulation in 2.4GHz band
#define RADIO_CONFIG_915MHZ_OQPSK_SUPPORT 0 /// Dev board doesn't support OQPSK modulation in 915MHz band.
#endif
#ifndef RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
#define RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT 0 /// Set to 1 to enable debug counters in radio.c
#endif
#ifndef RADIO_CONFIG_ENABLE_CUSTOM_EUI_SUPPORT
#define RADIO_CONFIG_ENABLE_CUSTOM_EUI_SUPPORT 1 /// Set to 1 to enable custom EUI support (enabled by default)
#endif
#ifndef RADIO_CONFIG_DMP_SUPPORT
#define RADIO_CONFIG_DMP_SUPPORT 0 /// Set to 1 to enable Dynamic Multi-Protocol support in radio.c
#endif
#endif // __BOARD_CONFIG_H__

View File

@@ -0,0 +1,796 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for PSA.
*
*/
#include <openthread-core-config.h>
#include <openthread/error.h>
#include <openthread/platform/crypto.h>
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
#include "security_manager.h"
#include "common/debug.hpp"
#include "utils/code_utils.h"
#include "em_device.h"
#include <mbedtls/ecdsa.h>
#include <mbedtls/md.h>
#include <mbedtls/pk.h>
#include "mbedtls/psa_util.h"
#if defined(_SILICON_LABS_32B_SERIES_2)
#include "em_system.h"
#else
#include "sl_hal_system.h"
#endif
#include "sl_psa_crypto.h"
#if defined(_SILICON_LABS_32B_SERIES_2)
#define GET_SECURITY_CAPABILITY SYSTEM_GetSecurityCapability
#define VAULT_ENABLED securityCapabilityVault
#else
#define GET_SECURITY_CAPABILITY sl_hal_system_get_security_capability
#define VAULT_ENABLED SL_SYSTEM_SECURITY_CAPABILITY_VAULT
#endif
#define PERSISTENCE_KEY_ID_USED_MAX (7)
#define MAX_HMAC_KEY_SIZE (32)
// Helper function to convert otCryptoKeyType to psa_key_type_t
static psa_key_type_t getPsaKeyType(otCryptoKeyType aKeyType)
{
psa_key_type_t aPsaKeyType = 0;
switch (aKeyType)
{
case OT_CRYPTO_KEY_TYPE_RAW:
aPsaKeyType = PSA_KEY_TYPE_RAW_DATA;
break;
case OT_CRYPTO_KEY_TYPE_AES:
aPsaKeyType = PSA_KEY_TYPE_AES;
break;
case OT_CRYPTO_KEY_TYPE_HMAC:
aPsaKeyType = PSA_KEY_TYPE_HMAC;
break;
case OT_CRYPTO_KEY_TYPE_ECDSA:
aPsaKeyType = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
break;
}
return aPsaKeyType;
}
// Helper function to convert aKeyAlgorithm to psa_algorithm_t
static psa_algorithm_t getPsaAlgorithm(otCryptoKeyAlgorithm aKeyAlgorithm)
{
psa_algorithm_t aPsaKeyAlgorithm = 0;
switch (aKeyAlgorithm)
{
case OT_CRYPTO_KEY_ALG_VENDOR:
aPsaKeyAlgorithm = PSA_ALG_VENDOR_FLAG;
break;
case OT_CRYPTO_KEY_ALG_AES_ECB:
aPsaKeyAlgorithm = PSA_ALG_ECB_NO_PADDING;
break;
case OT_CRYPTO_KEY_ALG_HMAC_SHA_256:
aPsaKeyAlgorithm = PSA_ALG_HMAC(PSA_ALG_SHA_256);
break;
case OT_CRYPTO_KEY_ALG_ECDSA:
aPsaKeyAlgorithm = PSA_ALG_ECDSA(PSA_ALG_ANY_HASH);
break;
}
return aPsaKeyAlgorithm;
}
// Helper function to convert aKeyUsage to psa_key_usage_t
static psa_key_usage_t getPsaKeyUsage(int aKeyUsage)
{
psa_key_usage_t aPsaKeyUsage = 0;
if (aKeyUsage & OT_CRYPTO_KEY_USAGE_EXPORT)
{
aPsaKeyUsage |= PSA_KEY_USAGE_EXPORT;
}
if (aKeyUsage & OT_CRYPTO_KEY_USAGE_ENCRYPT)
{
aPsaKeyUsage |= PSA_KEY_USAGE_ENCRYPT;
}
if (aKeyUsage & OT_CRYPTO_KEY_USAGE_DECRYPT)
{
aPsaKeyUsage |= PSA_KEY_USAGE_DECRYPT;
}
if (aKeyUsage & OT_CRYPTO_KEY_USAGE_SIGN_HASH)
{
aPsaKeyUsage |= PSA_KEY_USAGE_SIGN_HASH;
}
if (aKeyUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH)
{
aPsaKeyUsage |= PSA_KEY_USAGE_VERIFY_HASH;
}
return aPsaKeyUsage;
}
// Helper function to convert otCryptoKeyStorage to psa_key_persistence_t
static psa_key_persistence_t getPsaKeyPersistence(otCryptoKeyStorage aKeyPersistence)
{
psa_key_persistence_t aPsaKeyPersistence = 0;
switch (aKeyPersistence)
{
case OT_CRYPTO_KEY_STORAGE_VOLATILE:
aPsaKeyPersistence = PSA_KEY_PERSISTENCE_VOLATILE;
break;
case OT_CRYPTO_KEY_STORAGE_PERSISTENT:
aPsaKeyPersistence = PSA_KEY_PERSISTENCE_DEFAULT;
break;
}
return aPsaKeyPersistence;
}
#if defined(SEMAILBOX_PRESENT) && !defined(SL_TRUSTZONE_NONSECURE)
static bool shouldWrap(psa_key_attributes_t *key_attr)
{
psa_key_location_t keyLocation = PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(key_attr));
psa_key_type_t keyType = psa_get_key_type(key_attr);
return ((keyLocation != SL_PSA_KEY_LOCATION_WRAPPED) && (keyType != PSA_KEY_TYPE_HMAC));
}
static void checkAndWrapKeys(void)
{
for (int index = 1; index <= PERSISTENCE_KEY_ID_USED_MAX; index++)
{
otCryptoKeyRef key_ref = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + index;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
// If there is a key present in the location..
if (sl_sec_man_get_key_attributes(key_ref, &key_attr) == PSA_SUCCESS)
{
if (shouldWrap(&key_attr))
{
// Wrap the key..
otCryptoKeyRef dst_key_ref = key_ref;
psa_key_lifetime_t key_lifetime =
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(PSA_KEY_PERSISTENCE_DEFAULT,
SL_PSA_KEY_LOCATION_WRAPPED);
psa_set_key_lifetime(&key_attr, key_lifetime);
sl_sec_man_copy_key(key_ref, &key_attr, &dst_key_ref);
}
}
}
}
#endif // SEMAILBOX_PRESENT && !SL_TRUSTZONE_NONSECURE
void otPlatCryptoInit(void)
{
#if defined(SEMAILBOX_PRESENT) && !defined(SL_TRUSTZONE_NONSECURE)
if (GET_SECURITY_CAPABILITY() == VAULT_ENABLED)
{
checkAndWrapKeys();
}
#endif
}
static otError extractPrivateKeyFromDer(uint8_t *aPrivateKey, const uint8_t *aDer, uint8_t aDerLen)
{
otError error = OT_ERROR_NONE;
mbedtls_pk_context pk;
mbedtls_ecp_keypair *keyPair;
mbedtls_pk_init(&pk);
otEXPECT_ACTION(mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)) == 0, error = OT_ERROR_FAILED);
#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
otEXPECT_ACTION(mbedtls_pk_parse_key(&pk, aDer, aDerLen, NULL, 0, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE)
== 0,
error = OT_ERROR_PARSE);
#else
otEXPECT_ACTION(mbedtls_pk_parse_key(&pk, aDer, aDerLen, NULL, 0) == 0, error = OT_ERROR_PARSE);
#endif
keyPair = mbedtls_pk_ec(pk);
mbedtls_mpi_write_binary(&keyPair->MBEDTLS_PRIVATE(d), aPrivateKey, SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE);
exit:
return error;
}
otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyId,
otCryptoKeyType aKeyType,
otCryptoKeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
otCryptoKeyStorage aKeyPersistence,
const uint8_t *aKey,
size_t aKeyLen)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
uint8_t aPrivateKey[SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE];
const uint8_t *keyToImport = aKey;
size_t keySize = aKeyLen;
if (aKeyType == OT_CRYPTO_KEY_TYPE_ECDSA)
{
error = extractPrivateKeyFromDer(aPrivateKey, aKey, aKeyLen);
keyToImport = aPrivateKey;
keySize = SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE;
}
status = sl_sec_man_import_key(aKeyId,
getPsaKeyType(aKeyType),
getPsaAlgorithm(aKeyAlgorithm),
getPsaKeyUsage(aKeyUsage),
getPsaKeyPersistence(aKeyPersistence),
keyToImport,
keySize);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoExportKey(otCryptoKeyRef aKeyId, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
status = sl_sec_man_export_key(aKeyId, aBuffer, aBufferLen, aKeyLen);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyId)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
status = sl_sec_man_destroy_key(aKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
{
psa_key_attributes_t aAttr = PSA_KEY_ATTRIBUTES_INIT;
return (sl_sec_man_get_key_attributes(aKeyRef, &aAttr) == PSA_SUCCESS);
}
// AES Implementation
otError otPlatCryptoAesInit(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
(void)aContext;
return error;
}
otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey)
{
otError error = OT_ERROR_NONE;
otCryptoKeyRef *mKeyRef = NULL;
otEXPECT_ACTION((aContext != NULL) && (aContext->mContext != NULL), error = OT_ERROR_INVALID_ARGS);
mKeyRef = (otCryptoKeyRef *)aContext->mContext;
*mKeyRef = aKey->mKeyRef;
exit:
return error;
}
otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
otCryptoKeyRef *mKeyRef = NULL;
otEXPECT_ACTION(((aContext != NULL) && (aContext->mContext != NULL) && (aOutput != NULL) && (aInput != NULL)),
error = OT_ERROR_INVALID_ARGS);
mKeyRef = (otCryptoKeyRef *)aContext->mContext;
status = sl_sec_man_aes_encrypt(*mKeyRef, PSA_ALG_ECB_NO_PADDING, aInput, aOutput);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoAesFree(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
(void)aContext;
return error;
}
// HMAC implementations
otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
psa_mac_operation_t *mMacOperation = (psa_mac_operation_t *)aContext->mContext;
*mMacOperation = psa_mac_operation_init();
return error;
}
otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
psa_mac_operation_t *mMacOperation = (psa_mac_operation_t *)aContext->mContext;
psa_status_t status;
status = sl_sec_man_hmac_deinit(mMacOperation);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
static psa_status_t reImportUnwrapped(const otCryptoKey *aKey, otCryptoKeyRef *aHmacKeyRef)
{
psa_status_t status = PSA_SUCCESS;
#if defined(SEMAILBOX_PRESENT)
uint8_t hmacKeyBytes[MAX_HMAC_KEY_SIZE];
size_t key_size;
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
status = sl_sec_man_get_key_attributes(aKey->mKeyRef, &key_attr);
otEXPECT(status == PSA_SUCCESS);
status = sl_sec_man_export_key(aKey->mKeyRef, hmacKeyBytes, sizeof(hmacKeyBytes), &key_size);
otEXPECT(status == PSA_SUCCESS);
status = sl_sec_man_import_key(aHmacKeyRef,
psa_get_key_type(&key_attr),
psa_get_key_algorithm(&key_attr),
psa_get_key_usage_flags(&key_attr),
PSA_KEY_PERSISTENCE_VOLATILE,
hmacKeyBytes,
key_size);
memset(hmacKeyBytes, 0, sizeof(hmacKeyBytes));
otEXPECT(status == PSA_SUCCESS);
exit:
#else
*aHmacKeyRef = aKey->mKeyRef;
#endif
return status;
}
otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey)
{
otError error = OT_ERROR_NONE;
psa_mac_operation_t *mMacOperation = (psa_mac_operation_t *)aContext->mContext;
psa_status_t status;
otCryptoKeyRef hmacKeyRef;
status = reImportUnwrapped(aKey, &hmacKeyRef);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
status = sl_sec_man_hmac_start(mMacOperation, hmacKeyRef);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
#if defined(SEMAILBOX_PRESENT)
sl_sec_man_destroy_key(hmacKeyRef);
#else
hmacKeyRef = 0;
#endif
exit:
return error;
}
otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
{
otError error = OT_ERROR_NONE;
psa_mac_operation_t *mMacOperation = (psa_mac_operation_t *)aContext->mContext;
psa_status_t status;
status = sl_sec_man_hmac_update(mMacOperation, (const uint8_t *)aBuf, (size_t)aBufLength);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength)
{
otError error = OT_ERROR_NONE;
psa_mac_operation_t *mMacOperation = (psa_mac_operation_t *)aContext->mContext;
psa_status_t status;
status = sl_sec_man_hmac_finish(mMacOperation, aBuf, aBufLength);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
// HKDF platform implementations
// As the HKDF does not actually use mbedTLS APIs but uses HMAC module, this feature is not implemented.
otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
const uint8_t *aInfo,
uint16_t aInfoLength,
uint8_t *aOutputKey,
uint16_t aOutputKeyLength)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
otEXPECT_ACTION(((aContext != NULL) && (aContext->mContext != NULL) && (aInfo != NULL) && (aOutputKey != NULL)),
error = OT_ERROR_INVALID_ARGS);
status = sl_sec_man_key_derivation_expand(aContext->mContext, aInfo, aInfoLength, aOutputKey, aOutputKeyLength);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoHkdfExtract(otCryptoContext *aContext,
const uint8_t *aSalt,
uint16_t aSaltLength,
const otCryptoKey *aKey)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
otEXPECT_ACTION(
((aContext != NULL) && (aContext->mContext != NULL) && (aKey != NULL) && (aSalt != NULL) && (aSaltLength != 0)),
error = OT_ERROR_INVALID_ARGS);
status = sl_sec_man_key_derivation_extract(aContext->mContext, PSA_ALG_SHA_256, aKey->mKeyRef, aSalt, aSaltLength);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
// SHA256 platform implementations
otError otPlatCryptoSha256Init(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION((aContext != NULL), error = OT_ERROR_INVALID_ARGS);
psa_hash_operation_t *ctx = (psa_hash_operation_t *)aContext->mContext;
otEXPECT_ACTION((ctx != NULL), error = OT_ERROR_INVALID_ARGS);
*ctx = sl_sec_man_hash_init();
exit:
return error;
}
otError otPlatCryptoSha256Deinit(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION((aContext != NULL), error = OT_ERROR_INVALID_ARGS);
psa_hash_operation_t *ctx = (psa_hash_operation_t *)aContext->mContext;
otEXPECT_ACTION((ctx != NULL), error = OT_ERROR_INVALID_ARGS);
otEXPECT_ACTION((sl_sec_man_hash_deinit(ctx) == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoSha256Start(otCryptoContext *aContext)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION((aContext != NULL), error = OT_ERROR_INVALID_ARGS);
psa_hash_operation_t *ctx = (psa_hash_operation_t *)aContext->mContext;
otEXPECT_ACTION((ctx != NULL), error = OT_ERROR_INVALID_ARGS);
otEXPECT_ACTION((sl_sec_man_hash_start(ctx, PSA_ALG_SHA_256) == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION((aContext != NULL), error = OT_ERROR_INVALID_ARGS);
psa_hash_operation_t *ctx = (psa_hash_operation_t *)aContext->mContext;
otEXPECT_ACTION(((ctx != NULL) && (aBuf != NULL)), error = OT_ERROR_INVALID_ARGS);
otEXPECT_ACTION((sl_sec_man_hash_update(ctx, (uint8_t *)aBuf, aBufLength) == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize)
{
otError error = OT_ERROR_NONE;
size_t aHashLength = 0;
otEXPECT_ACTION((aContext != NULL), error = OT_ERROR_INVALID_ARGS);
psa_hash_operation_t *ctx = (psa_hash_operation_t *)aContext->mContext;
otEXPECT_ACTION(((ctx != NULL) && (aHash != NULL)), error = OT_ERROR_INVALID_ARGS);
otEXPECT_ACTION((sl_sec_man_hash_finish(ctx, aHash, aHashSize, &aHashLength) == PSA_SUCCESS),
error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
{
otError error = OT_ERROR_NONE;
size_t aKeyLength = 256;
psa_status_t status;
status = sl_sec_man_generate_key(&aKeyRef,
PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1),
PSA_ALG_ECDSA(PSA_ALG_ANY_HASH),
(PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH),
PSA_KEY_LIFETIME_PERSISTENT,
aKeyLength);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey)
{
otError error = OT_ERROR_NONE;
size_t aKeyLength;
psa_status_t status;
uint8_t aByteArray[OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE + 1];
otEXPECT_ACTION((aPublicKey != NULL), error = OT_ERROR_INVALID_ARGS);
// Use byte array to get the public key because PSA adds a encoding header at the beginning of the array.
// It is easier to export it to a byte array and copy only the public key to output array.
status = sl_sec_man_export_public_key(aKeyRef, aByteArray, sizeof(aByteArray), &aKeyLength);
memcpy(aPublicKey->m8, &aByteArray[1], OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
const otPlatCryptoSha256Hash *aHash,
otPlatCryptoEcdsaSignature *aSignature)
{
otError error = OT_ERROR_NONE;
size_t aSignatureLength;
psa_status_t status;
bool aIsHash = true;
otEXPECT_ACTION(((aHash != NULL) && (aSignature != NULL)), error = OT_ERROR_INVALID_ARGS);
status = sl_sec_man_sign(aKeyRef,
PSA_ALG_ECDSA(PSA_ALG_SHA_256),
aHash->m8,
sizeof(aHash->m8),
aSignature->m8,
sizeof(aSignature->m8),
&aSignatureLength,
aIsHash);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
const otPlatCryptoSha256Hash *aHash,
const otPlatCryptoEcdsaSignature *aSignature)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
bool aIsHash = true;
otEXPECT_ACTION(((aHash != NULL) && (aSignature != NULL)), error = OT_ERROR_INVALID_ARGS);
// Verify the signature.
status = sl_sec_man_verify(aKeyRef,
PSA_ALG_ECDSA(PSA_ALG_SHA_256),
aHash->m8,
sizeof(aHash->m8),
aSignature->m8,
sizeof(aSignature->m8),
aIsHash);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
uint16_t aPasswordLen,
const uint8_t *aSalt,
uint16_t aSaltLen,
uint32_t aIterationCounter,
uint16_t aKeyLen,
uint8_t *aKey)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
size_t outSize;
psa_key_id_t passwordKeyId = 0;
psa_key_id_t saltKeyId = 0;
psa_key_id_t keyId = 0;
// Algorithm is PBKDF2-AES-CMAC-PRF-128
psa_algorithm_t algo = PSA_ALG_PBKDF2_AES_CMAC_PRF_128;
// Initialize key derivation
psa_key_derivation_operation_t operation = psa_key_derivation_operation_init();
status = psa_key_derivation_setup(&operation, algo);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Set capacity
status = psa_key_derivation_set_capacity(&operation, aKeyLen);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Set iteration count as cost
status = psa_key_derivation_input_integer(&operation, PSA_KEY_DERIVATION_INPUT_COST, aIterationCounter);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Create salt as a key
psa_key_attributes_t saltKeyAttr = psa_key_attributes_init();
psa_set_key_usage_flags(&saltKeyAttr, PSA_KEY_USAGE_DERIVE);
psa_set_key_type(&saltKeyAttr, PSA_KEY_TYPE_RAW_DATA);
psa_set_key_algorithm(&saltKeyAttr, algo);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
status = psa_import_key(&saltKeyAttr, aSalt, aSaltLen, &saltKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Provide salt
status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_SALT, saltKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Create key for password (key)
psa_key_attributes_t passwordKeyAttr = psa_key_attributes_init();
psa_set_key_usage_flags(&passwordKeyAttr, PSA_KEY_USAGE_DERIVE);
psa_set_key_type(&passwordKeyAttr, PSA_KEY_TYPE_PASSWORD);
psa_set_key_algorithm(&passwordKeyAttr, algo);
status = psa_import_key(&passwordKeyAttr, aPassword, aPasswordLen, &passwordKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Provide password (key)
status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_PASSWORD, passwordKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Configure output as a key
psa_key_attributes_t keyAttrResult = psa_key_attributes_init();
psa_set_key_bits(&keyAttrResult, (8 * aKeyLen));
psa_set_key_usage_flags(&keyAttrResult, PSA_KEY_USAGE_EXPORT);
psa_set_key_type(&keyAttrResult, PSA_KEY_TYPE_RAW_DATA);
psa_set_key_algorithm(&keyAttrResult, PSA_ALG_CTR);
status = psa_key_derivation_output_key(&keyAttrResult, &operation, &keyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Export output key
status = psa_export_key(keyId, aKey, aKeyLen, &outSize);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
// Release keys used
psa_destroy_key(keyId);
psa_destroy_key(saltKeyId);
psa_destroy_key(passwordKeyId);
exit:
return error;
}
otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
const otPlatCryptoSha256Hash *aHash,
const otPlatCryptoEcdsaSignature *aSignature)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
bool aIsHash = true;
uint8_t aByteArray[OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE + 1];
otCryptoKeyRef aKeyId;
otEXPECT_ACTION(((aPublicKey != NULL) && (aHash != NULL) && (aSignature != NULL)), error = OT_ERROR_INVALID_ARGS);
// Public key needs a extra byt of encoding header, which has a value of 0x04, to be included for PSA to validate
// and process the publc key. Copy the key into a new temp array and append the encoding header to it.
aByteArray[0] = 0x04;
memcpy(&aByteArray[1], aPublicKey, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
// Import the public key into a temp slot.
status = sl_sec_man_import_key(&aKeyId,
PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1),
PSA_ALG_ECDSA(PSA_ALG_ANY_HASH),
PSA_KEY_USAGE_VERIFY_HASH,
PSA_KEY_PERSISTENCE_VOLATILE,
aByteArray,
OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE + 1); // To account for the padded byte.
// If key import fails, assert, as we cannot proceed
OT_ASSERT(status == PSA_SUCCESS);
// Verify the signature.
status = sl_sec_man_verify(aKeyId,
PSA_ALG_ECDSA(PSA_ALG_SHA_256),
aHash->m8,
sizeof(aHash->m8),
aSignature->m8,
sizeof(aSignature->m8),
aIsHash);
// Destroy the temp key.
sl_sec_man_destroy_key(aKeyId);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA

View File

@@ -0,0 +1,473 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for the diagnostics.
*
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <sys/time.h>
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#include <openthread-core-config.h>
#include <utils/code_utils.h>
#include <openthread/cli.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/radio.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/logging.hpp"
#include "diag.h"
#include "sl_gpio.h"
#include "sl_hal_gpio.h"
#include "platform-band.h"
#include "platform-efr32.h"
#include "rail_ieee802154.h"
#include "sl_status.h"
#if OPENTHREAD_CONFIG_DIAG_ENABLE
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
#include "sl_rail_util_ant_div.h"
#endif
#define GPIO_PIN_BITMASK 0xFFFFUL
#define GPIO_PORT_BITMASK (0xFFFFUL << 16)
#define GET_GPIO_PIN(x) (x & GPIO_PIN_BITMASK)
#define GET_GPIO_PORT(x) ((x & GPIO_PORT_BITMASK) >> 16)
// To cache the transmit power, so that we don't override it while loading the
// channel config or setting the channel.
static int8_t sTxPower = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
struct PlatformDiagCommand
{
const char *mName;
otError (*mCommand)(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);
};
// Diagnostics mode variables.
static bool sDiagMode = false;
static otPlatDiagOutputCallback sDiagOutputCallback = NULL;
static void *sDiagCallbackContext = NULL;
static void diagOutput(const char *aFormat, ...)
{
va_list args;
va_start(args, aFormat);
if (sDiagOutputCallback != NULL)
{
sDiagOutputCallback(aFormat, args, sDiagCallbackContext);
}
va_end(args);
}
static void appendErrorResult(otError aError)
{
if (aError != OT_ERROR_NONE)
{
diagOutput("failed\r\nstatus %#x\r\n", aError);
}
}
// *****************************************************************************
// CLI functions
// *****************************************************************************
static otError processAddressMatch(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_INVALID_ARGS;
VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
if (strcmp(aArgs[0], "enable") == 0)
{
error = otPlatDiagRadioAddressMatch(true);
}
else if (strcmp(aArgs[0], "disable") == 0)
{
error = otPlatDiagRadioAddressMatch(false);
}
exit:
appendErrorResult(error);
return error;
}
static otError processAutoAck(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_INVALID_ARGS;
VerifyOrExit(otPlatDiagModeGet(), error = OT_ERROR_INVALID_STATE);
VerifyOrExit(aArgsLength > 0, error = OT_ERROR_INVALID_ARGS);
if (strcmp(aArgs[0], "enable") == 0)
{
error = otPlatDiagRadioAutoAck(true);
}
else if (strcmp(aArgs[0], "disable") == 0)
{
error = otPlatDiagRadioAutoAck(false);
}
exit:
appendErrorResult(error);
return error;
}
// *****************************************************************************
// Add more platform specific diagnostic's CLI features here.
// *****************************************************************************
const struct PlatformDiagCommand sCommands[] = {
{"addr-match", &processAddressMatch},
{"auto-ack", &processAutoAck},
};
otError otPlatDiagProcess(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_INVALID_COMMAND;
size_t i;
for (i = 0; i < otARRAY_LENGTH(sCommands); i++)
{
if (strcmp(aArgs[0], sCommands[i].mName) == 0)
{
error = sCommands[i].mCommand(aInstance, aArgsLength - 1, aArgsLength > 1 ? &aArgs[1] : NULL);
break;
}
}
return error;
}
// *****************************************************************************
// Implement platform specific diagnostic's APIs.
// *****************************************************************************
void otPlatDiagSetOutputCallback(otInstance *aInstance, otPlatDiagOutputCallback aCallback, void *aContext)
{
OT_UNUSED_VARIABLE(aInstance);
sDiagOutputCallback = aCallback;
sDiagCallbackContext = aContext;
}
void otPlatDiagModeSet(bool aMode)
{
sDiagMode = aMode;
}
bool otPlatDiagModeGet()
{
return sDiagMode;
}
static RAIL_Status_t startTxStream(RAIL_StreamMode_t aMode)
{
uint16_t txChannel;
RAIL_Status_t status;
SuccessOrExit(status = RAIL_GetChannel(gRailHandle, &txChannel));
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
RAIL_TxOptions_t txOptions = RAIL_TX_OPTIONS_DEFAULT;
// Translate Tx antenna diversity mode into RAIL Tx Antenna options:
// If enabled, use the currently-selected antenna, otherwise leave
// both options 0 so Tx antenna tracks Rx antenna.
if (sl_rail_util_ant_div_get_tx_antenna_mode() != SL_RAIL_UTIL_ANTENNA_MODE_DISABLED)
{
txOptions |= ((sl_rail_util_ant_div_get_tx_antenna_selected() == SL_RAIL_UTIL_ANTENNA_SELECT_ANTENNA1)
? RAIL_TX_OPTION_ANTENNA0
: RAIL_TX_OPTION_ANTENNA1);
}
status = RAIL_StartTxStreamAlt(gRailHandle, txChannel, aMode, txOptions);
#else // !SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
status = RAIL_StartTxStream(gRailHandle, txChannel, aMode);
#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
exit:
return status;
}
static RAIL_Status_t stopTxStream(void)
{
RAIL_Status_t status;
uint16_t currentChannel;
RAIL_SchedulerInfo_t rxSchedulerInfo = {
.priority = SL_802154_RADIO_PRIO_BACKGROUND_RX_VALUE,
};
SuccessOrExit(status = RAIL_StopTxStream(gRailHandle));
// Since start transmit stream turn off the radio state,
// call the RAIL_StartRx to turn on radio
IgnoreError(RAIL_GetChannel(gRailHandle, &currentChannel));
status = RAIL_StartRx(gRailHandle, currentChannel, &rxSchedulerInfo);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
exit:
return status;
}
otError otPlatDiagRadioTransmitCarrier(otInstance *aInstance, bool aEnable)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
if (aEnable)
{
otLogInfoPlat("Diag CARRIER-WAVE/Tone start");
status = startTxStream(RAIL_STREAM_CARRIER_WAVE);
}
else
{
otLogInfoPlat("Diag CARRIER-WAVE/Tone stop");
status = stopTxStream();
}
return (status != RAIL_STATUS_NO_ERROR ? OT_ERROR_FAILED : OT_ERROR_NONE);
}
otError otPlatDiagRadioTransmitStream(otInstance *aInstance, bool aEnable)
{
OT_UNUSED_VARIABLE(aInstance);
RAIL_Status_t status;
if (aEnable)
{
otLogInfoPlat("Diag Stream PN9 start");
status = startTxStream(RAIL_STREAM_PN9_STREAM);
}
else
{
otLogInfoPlat("Diag Stream stop");
status = stopTxStream();
}
return (status != RAIL_STATUS_NO_ERROR ? OT_ERROR_FAILED : OT_ERROR_NONE);
}
otError otPlatDiagRadioAddressMatch(bool aEnable)
{
RAIL_Status_t status;
otLogInfoPlat("Diag address-match %s", aEnable ? "enable" : "disable");
status = RAIL_IEEE802154_SetPromiscuousMode(gRailHandle, !aEnable);
return (status != RAIL_STATUS_NO_ERROR ? OT_ERROR_FAILED : OT_ERROR_NONE);
}
otError otPlatDiagRadioAutoAck(bool aAutoAckEnabled)
{
otLogInfoPlat("Diag auto-ack %s", aAutoAckEnabled ? "enable" : "disable");
RAIL_PauseRxAutoAck(gRailHandle, !aAutoAckEnabled);
return OT_ERROR_NONE;
}
void otPlatDiagChannelSet(uint8_t aChannel)
{
otError error = OT_ERROR_NONE;
RAIL_Status_t status;
RAIL_SchedulerInfo_t bgRxSchedulerInfo = {
.priority = SL_802154_RADIO_PRIO_BACKGROUND_RX_VALUE,
// sliptime/transaction time is not used for bg rx
};
error = efr32RadioLoadChannelConfig(aChannel, sTxPower);
OT_ASSERT(error == OT_ERROR_NONE);
status = RAIL_StartRx(gRailHandle, aChannel, &bgRxSchedulerInfo);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}
void otPlatDiagTxPowerSet(int8_t aTxPower)
{
RAIL_Status_t status;
// RAIL_SetTxPowerDbm() takes power in units of deci-dBm (0.1dBm)
// Multiply by 10 because aPower is supposed be in units dBm
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)aTxPower) * 10);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
sTxPower = aTxPower;
}
void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aFrame);
OT_UNUSED_VARIABLE(aError);
}
void otPlatDiagAlarmCallback(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
}
static otError getGpioPortAndPin(uint32_t aGpio, uint16_t *aPort, uint16_t *aPin)
{
otError error = OT_ERROR_NONE;
*aPort = GET_GPIO_PORT(aGpio);
*aPin = GET_GPIO_PIN(aGpio);
#if defined(SL_CATALOG_GPIO_PRESENT)
if (*aPort > SL_HAL_GPIO_PORT_MAX || *aPin > SL_HAL_GPIO_PIN_MAX)
#else
if (*aPort > GPIO_PORT_MAX || *aPin > GPIO_PIN_MAX)
#endif
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
exit:
return error;
}
otError otPlatDiagGpioSet(uint32_t aGpio, bool aValue)
{
otError error = OT_ERROR_NONE;
uint16_t port;
uint16_t pin;
SuccessOrExit(error = getGpioPortAndPin(aGpio, &port, &pin));
sl_gpio_t gpio;
gpio.port = (uint8_t)port;
gpio.pin = (uint8_t)pin;
if (aValue)
{
VerifyOrExit(sl_gpio_set_pin(&gpio) == SL_STATUS_OK, error = OT_ERROR_INVALID_ARGS);
}
else
{
VerifyOrExit(sl_gpio_clear_pin(&gpio) == SL_STATUS_OK, error = OT_ERROR_INVALID_ARGS);
}
exit:
return error;
}
otError otPlatDiagGpioGet(uint32_t aGpio, bool *aValue)
{
otError error = OT_ERROR_NONE;
uint16_t port;
uint16_t pin;
SuccessOrExit(error = getGpioPortAndPin(aGpio, &port, &pin));
sl_gpio_t gpio;
gpio.port = (uint8_t)port;
gpio.pin = (uint8_t)pin;
VerifyOrExit(sl_gpio_get_pin_input(&gpio, aValue) == SL_STATUS_OK, error = OT_ERROR_INVALID_ARGS);
exit:
return error;
}
otError otPlatDiagGpioSetMode(uint32_t aGpio, otGpioMode aMode)
{
otError error = OT_ERROR_NONE;
uint16_t port;
uint16_t pin;
sl_gpio_mode_t mode;
SuccessOrExit(error = getGpioPortAndPin(aGpio, &port, &pin));
mode = (aMode == OT_GPIO_MODE_INPUT) ? SL_GPIO_MODE_INPUT : SL_GPIO_MODE_PUSH_PULL;
sl_gpio_t gpio;
gpio.port = (uint8_t)port;
gpio.pin = (uint8_t)pin;
error = sl_gpio_set_pin_mode(&gpio, mode, 0 /*out*/);
// Convert to otError.
VerifyOrExit(error == SL_STATUS_OK,
error = (error == SL_STATUS_INVALID_STATE ? OT_ERROR_INVALID_STATE : OT_ERROR_INVALID_ARGS));
exit:
return error;
}
otError otPlatDiagGpioGetMode(uint32_t aGpio, otGpioMode *aMode)
{
otError error = OT_ERROR_NONE;
uint16_t port;
uint16_t pin;
sl_gpio_mode_t mode;
SuccessOrExit(error = getGpioPortAndPin(aGpio, &port, &pin));
sl_gpio_t gpio;
sl_gpio_pin_config_t pin_config;
gpio.port = (uint8_t)port;
gpio.pin = (uint8_t)pin;
VerifyOrExit(sl_gpio_get_pin_config(&gpio, &pin_config) == SL_STATUS_OK, error = OT_ERROR_INVALID_ARGS);
mode = pin_config.mode;
*aMode = (mode == SL_GPIO_MODE_INPUT) ? OT_GPIO_MODE_INPUT : OT_GPIO_MODE_OUTPUT;
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_DIAG_ENABLE

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes the platform-specific diagnostic's API declarations.
*
*/
#ifndef DIAG_H_
#define DIAG_H_
/**
* Enable/disable the address match filtering.
*
* @param[in] aEnable TRUE to Enable or FALSE to disable address match filtering.
*
* @retval OT_ERROR_NONE Successfully enabled/disabled, asserts otherwise.
*
*/
otError otPlatDiagRadioAddressMatch(bool aEnable);
/**
* Enable/disable the RX auto-ACK functionality.
*
* @param[in] aAutoAckEnabled TRUE to Enable or FALSE to disable the RX auto-ACK functionality.
*
* @retval OT_ERROR_NONE Successfully enabled/disabled .
*
*/
otError otPlatDiagRadioAutoAck(bool aAutoAckEnabled);
#endif // DIAG_H_

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for random number generator.
*
*/
#include <openthread-core-config.h>
#include <stddef.h>
#include <openthread/platform/entropy.h>
#include "utils/code_utils.h"
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
#include "security_manager.h"
void otPlatCryptoRandomInit(void)
{
}
void otPlatCryptoRandomDeinit(void)
{
// Intentionally left blank, nothing to deinit
}
otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize)
{
otError error = OT_ERROR_NONE;
psa_status_t status;
status = sl_sec_man_get_random(aBuffer, aSize);
otEXPECT_ACTION((status == PSA_SUCCESS), error = OT_ERROR_FAILED);
exit:
return error;
}
#else
// The mbedtls_hardware_poll() function is meant for internal use by Mbed TLS
// and is not declared in any external header files. We will therefore declare
// it as an extern function here.
extern int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen);
otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
{
otError error = OT_ERROR_NONE;
size_t outputLen = 0;
otEXPECT_ACTION(aOutput, error = OT_ERROR_INVALID_ARGS);
for (size_t partialLen = 0; outputLen < aOutputLength; outputLen += partialLen)
{
const uint16_t remaining = aOutputLength - outputLen;
partialLen = 0;
// Non-zero return values for mbedtls_hardware_poll() signify an error has occurred
otEXPECT_ACTION(0 == mbedtls_hardware_poll(NULL, &aOutput[outputLen], remaining, &partialLen),
error = OT_ERROR_FAILED);
}
exit:
return error;
}
#endif

View File

@@ -0,0 +1,438 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for the non-volatile storage.
*/
#include <openthread-core-config.h>
#include "common/debug.hpp"
#include "utils/code_utils.h"
#include "platform-efr32.h"
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE // Use OT NV system
#include "em_msc.h"
#include <string.h>
#include <openthread/instance.h>
#define FLASH_PAGE_NUM 2
#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
#define FLASH_SWAP_PAGE_NUM (FLASH_PAGE_NUM / 2)
#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * FLASH_SWAP_PAGE_NUM)
static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
{
uint32_t address;
address = FLASH_DATA_START_ADDR + aOffset;
if (aSwapIndex)
{
address += FLASH_SWAP_SIZE;
}
return address;
}
void otPlatFlashInit(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
}
uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return FLASH_SWAP_SIZE;
}
void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
{
OT_UNUSED_VARIABLE(aInstance);
uint32_t address = mapAddress(aSwapIndex, 0);
for (uint32_t n = 0; n < FLASH_SWAP_PAGE_NUM; n++, address += FLASH_PAGE_SIZE)
{
MSC_ErasePage((uint32_t *)address);
}
}
void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
{
OT_UNUSED_VARIABLE(aInstance);
MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
}
void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
{
OT_UNUSED_VARIABLE(aInstance);
memcpy(aData, (const uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
}
#elif defined(SL_CATALOG_NVM3_PRESENT) // Defaults to Silabs nvm3 system
#include "nvm3_default.h"
#include "sl_memory_manager.h"
#include <string.h>
#include <openthread/platform/settings.h>
#include "common/code_utils.hpp"
#include "common/logging.hpp"
#define NVM3KEY_DOMAIN_OPENTHREAD 0x20000U
#define NUM_INDEXED_SETTINGS \
OPENTHREAD_CONFIG_MLE_MAX_CHILDREN // Indexed key types are only supported for kKeyChildInfo (=='child table').
#define ENUM_NVM3_KEY_LIST_SIZE 4 // List size used when enumerating nvm3 keys.
static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength);
static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index);
static otError mapNvm3Error(Ecode_t nvm3Res);
static bool nvmOpenedByOT;
void otPlatSettingsInit(otInstance *aInstance, const uint16_t *aSensitiveKeys, uint16_t aSensitiveKeysLength)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aSensitiveKeys);
OT_UNUSED_VARIABLE(aSensitiveKeysLength);
otEXPECT(sl_ot_rtos_task_can_access_pal());
// Only call nmv3_open if it has not been opened yet.
if (nvm3_defaultHandle->hasBeenOpened)
{
nvmOpenedByOT = false; // OT is not allowed to close NVM
}
else
{
if (mapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)) != OT_ERROR_NONE)
{
otLogDebgPlat("Error initializing nvm3 instance");
}
else
{
nvmOpenedByOT = true;
}
}
exit:
return;
}
void otPlatSettingsDeinit(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
otEXPECT(sl_ot_rtos_task_can_access_pal());
if (nvmOpenedByOT && nvm3_defaultHandle->hasBeenOpened)
{
nvm3_close(nvm3_defaultHandle);
nvmOpenedByOT = false;
}
exit:
return;
}
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
{
// Searches through all matching nvm3 keys to find the one with the required
// 'index', then reads the nvm3 data into the destination buffer.
// (Repeatedly enumerates a list of matching keys from the nvm3 until the
// required index is found).
OT_UNUSED_VARIABLE(aInstance);
otError err;
uint16_t valueLength = 0;
otEXPECT_ACTION(sl_ot_rtos_task_can_access_pal(), err = OT_ERROR_REJECTED);
nvm3_ObjectKey_t nvm3Key = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
bool idxFound = false;
int idx = 0;
err = OT_ERROR_NOT_FOUND;
while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
{
// Get the next nvm3 key list.
nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
size_t objCnt = nvm3_enumObjects(nvm3_defaultHandle,
keys,
ENUM_NVM3_KEY_LIST_SIZE,
nvm3Key,
makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
for (size_t i = 0; i < objCnt; ++i)
{
nvm3Key = keys[i];
if (idx == aIndex)
{
uint32_t objType;
size_t objLen;
err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
if (err == OT_ERROR_NONE)
{
valueLength = objLen;
// Only perform read if an input buffer was passed in.
if ((aValue != NULL) && (aValueLength != NULL))
{
sl_status_t status;
// Read all nvm3 obj bytes into a tmp buffer, then copy the required
// number of bytes to the read destination buffer.
uint8_t *buf = NULL;
status = sl_memory_alloc(valueLength, BLOCK_TYPE_LONG_TERM, (void **)&buf);
VerifyOrExit(status == SL_STATUS_OK, err = OT_ERROR_FAILED);
err = mapNvm3Error(nvm3_readData(nvm3_defaultHandle, nvm3Key, buf, valueLength));
if (err == OT_ERROR_NONE)
{
memcpy(aValue, buf, (valueLength < *aValueLength) ? valueLength : *aValueLength);
}
sl_free(buf);
SuccessOrExit(err);
}
}
idxFound = true;
break;
}
++idx;
}
if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
{
// Stop searching (there are no more matching nvm3 objects).
break;
}
++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
}
exit:
if (aValueLength != NULL)
{
*aValueLength = valueLength; // always return actual nvm3 object length.
}
return err;
}
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
OT_UNUSED_VARIABLE(aInstance);
otError err;
otEXPECT_ACTION(sl_ot_rtos_task_can_access_pal(), err = OT_ERROR_REJECTED);
// Delete all nvm3 objects matching the input key (i.e. the 'setting indexes' of the key).
err = otPlatSettingsDelete(aInstance, aKey, -1);
if ((err == OT_ERROR_NONE) || (err == OT_ERROR_NOT_FOUND))
{
// Add new setting object (i.e. 'index0' of the key).
err = addSetting(aKey, aValue, aValueLength);
SuccessOrExit(err);
}
exit:
return err;
}
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(sl_ot_rtos_task_can_access_pal(), error = OT_ERROR_REJECTED);
error = addSetting(aKey, aValue, aValueLength);
exit:
return error;
}
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
{
// Searches through all matching nvm3 keys to find the one with the required
// 'index' (or index = -1 to delete all), then deletes the nvm3 object.
// (Repeatedly enumerates a list of matching keys from the nvm3 until the
// required index is found).
OT_UNUSED_VARIABLE(aInstance);
otError err;
nvm3_ObjectKey_t nvm3Key = makeNvm3ObjKey(aKey, 0); // The base nvm3 key value.
bool idxFound = false;
int idx = 0;
err = OT_ERROR_NOT_FOUND;
otEXPECT_ACTION(sl_ot_rtos_task_can_access_pal(), err = OT_ERROR_REJECTED);
while ((idx <= NUM_INDEXED_SETTINGS) && (!idxFound))
{
// Get the next nvm3 key list.
nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE]; // List holds the next set of nvm3 keys.
size_t objCnt = nvm3_enumObjects(nvm3_defaultHandle,
keys,
ENUM_NVM3_KEY_LIST_SIZE,
nvm3Key,
makeNvm3ObjKey(aKey, NUM_INDEXED_SETTINGS));
for (size_t i = 0; i < objCnt; ++i)
{
nvm3Key = keys[i];
if ((idx == aIndex) || (aIndex == -1))
{
uint32_t objType;
size_t objLen;
err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
if (err == OT_ERROR_NONE)
{
// Delete the nvm3 object.
err = mapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key));
SuccessOrExit(err);
}
if (aIndex != -1)
{
idxFound = true;
break;
}
}
++idx;
}
if (objCnt < ENUM_NVM3_KEY_LIST_SIZE)
{
// Stop searching (there are no more matching nvm3 objects).
break;
}
++nvm3Key; // Inc starting value for next nvm3 key list enumeration.
}
exit:
return err;
}
void otPlatSettingsWipe(otInstance *aInstance)
{
nvm3_ObjectKey_t firstNvm3Key = makeNvm3ObjKey(1, 0);
nvm3_ObjectKey_t LastNvm3Key = makeNvm3ObjKey(0xFF, 0xFF);
nvm3_ObjectKey_t keys[ENUM_NVM3_KEY_LIST_SIZE];
size_t objCnt;
OT_UNUSED_VARIABLE(aInstance);
otEXPECT(sl_ot_rtos_task_can_access_pal());
objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, firstNvm3Key, LastNvm3Key);
while (objCnt > 0)
{
for (size_t i = 0; i < objCnt; ++i)
{
nvm3_deleteObject(nvm3_defaultHandle, keys[i]);
}
objCnt = nvm3_enumObjects(nvm3_defaultHandle, keys, ENUM_NVM3_KEY_LIST_SIZE, firstNvm3Key, LastNvm3Key);
}
exit:
return;
}
// Local functions..
static otError addSetting(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
// Helper function- writes input buffer data to a NEW nvm3 object.
// nvm3 object is created at the first available Key + index.
otError err;
if ((aValueLength == 0) || (aValue == NULL))
{
err = OT_ERROR_INVALID_ARGS;
}
else
{
for (int idx = 0; idx <= NUM_INDEXED_SETTINGS; ++idx)
{
nvm3_ObjectKey_t nvm3Key;
nvm3Key = makeNvm3ObjKey(aKey, idx);
uint32_t objType;
size_t objLen;
err = mapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objType, &objLen));
if (err == OT_ERROR_NOT_FOUND)
{
// Use this index for the new nvm3 object.
// Write the binary data to nvm3 (Creates nvm3 object if required).
err = mapNvm3Error(nvm3_writeData(nvm3_defaultHandle, nvm3Key, aValue, aValueLength));
break;
}
else if (err != OT_ERROR_NONE)
{
break;
}
}
}
return err;
}
static nvm3_ObjectKey_t makeNvm3ObjKey(uint16_t otSettingsKey, int index)
{
return (NVM3KEY_DOMAIN_OPENTHREAD | (otSettingsKey << 8) | (index & 0xFF));
}
static otError mapNvm3Error(Ecode_t nvm3Res)
{
otError err;
switch (nvm3Res)
{
case ECODE_NVM3_OK:
err = OT_ERROR_NONE;
break;
case ECODE_NVM3_ERR_KEY_NOT_FOUND:
err = OT_ERROR_NOT_FOUND;
break;
default:
err = OT_ERROR_FAILED;
break;
}
return err;
}
#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE

View File

@@ -0,0 +1,365 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements utility functions needed for 802.15.4 frame processing
*
*/
#include "ieee802154-packet-utils.hpp"
#include "em_device.h"
#include "sl_core.h"
#include "sl_packet_utils.h"
#if defined(RADIOAES_PRESENT)
#include "sli_protocol_crypto.h"
#else
#include "sli_crypto.h"
#endif
#include <assert.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "crypto/aes_ccm.hpp"
#include "mac/mac_frame.hpp"
using namespace ot;
using namespace Crypto;
#if defined(RADIOAES_PRESENT)
void TxSecurityProcessing::Init(uint32_t aHeaderLength,
uint32_t aPlainTextLength,
uint8_t aTagLength,
const void *aNonce,
uint8_t aNonceLength)
{
const uint8_t *nonceBytes = reinterpret_cast<const uint8_t *>(aNonce);
uint8_t blockLength = 0;
uint32_t len;
uint8_t L;
uint8_t i;
// Tag length must be even and within [kMinTagLength, kMaxTagLength]
OT_ASSERT(((aTagLength & 0x1) == 0) && (Crypto::AesCcm::kMinTagLength <= aTagLength)
&& (aTagLength <= Crypto::AesCcm::kMaxTagLength));
L = 0;
for (len = aPlainTextLength; len; len >>= 8)
{
L++;
}
if (L <= 1)
{
L = 2;
}
if (aNonceLength > 13)
{
aNonceLength = 13;
}
// increase L to match nonce len
if (L < (15 - aNonceLength))
{
L = 15 - aNonceLength;
}
// decrease nonceLength to match L
if (aNonceLength > (15 - L))
{
aNonceLength = 15 - L;
}
// setup initial block
// write flags
mBlock[0] = (static_cast<uint8_t>((aHeaderLength != 0) << 6) | static_cast<uint8_t>(((aTagLength - 2) >> 1) << 3)
| static_cast<uint8_t>(L - 1));
// write nonce
memcpy(&mBlock[1], nonceBytes, aNonceLength);
// write len
len = aPlainTextLength;
for (i = sizeof(mBlock) - 1; i > aNonceLength; i--)
{
mBlock[i] = len & 0xff;
len >>= 8;
}
// encrypt initial block
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mBlock, mBlock);
// process header
if (aHeaderLength > 0)
{
// process length
if (aHeaderLength < (65536U - 256U))
{
mBlock[blockLength++] ^= aHeaderLength >> 8;
mBlock[blockLength++] ^= aHeaderLength >> 0;
}
else
{
mBlock[blockLength++] ^= 0xff;
mBlock[blockLength++] ^= 0xfe;
mBlock[blockLength++] ^= aHeaderLength >> 24;
mBlock[blockLength++] ^= aHeaderLength >> 16;
mBlock[blockLength++] ^= aHeaderLength >> 8;
mBlock[blockLength++] ^= aHeaderLength >> 0;
}
}
// init counter
mCtr[0] = L - 1;
memcpy(&mCtr[1], nonceBytes, aNonceLength);
memset(&mCtr[aNonceLength + 1], 0, sizeof(mCtr) - aNonceLength - 1);
mNonceLength = aNonceLength;
mHeaderLength = aHeaderLength;
mHeaderCur = 0;
mPlainTextLength = aPlainTextLength;
mPlainTextCur = 0;
mBlockLength = blockLength;
mCtrLength = sizeof(mCtrPad);
mTagLength = aTagLength;
}
void TxSecurityProcessing::Header(const void *aHeader, uint32_t aHeaderLength)
{
const uint8_t *headerBytes = reinterpret_cast<const uint8_t *>(aHeader);
OT_ASSERT(mHeaderCur + aHeaderLength <= mHeaderLength);
// process header
for (unsigned i = 0; i < aHeaderLength; i++)
{
if (mBlockLength == sizeof(mBlock))
{
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mBlock, mBlock);
mBlockLength = 0;
}
mBlock[mBlockLength++] ^= headerBytes[i];
}
mHeaderCur += aHeaderLength;
if (mHeaderCur == mHeaderLength)
{
// process remainder
if (mBlockLength != 0)
{
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mBlock, mBlock);
}
mBlockLength = 0;
}
}
void TxSecurityProcessing::Payload(void *aPlainText, void *aCipherText, uint32_t aLength)
{
uint8_t *plaintextBytes = reinterpret_cast<uint8_t *>(aPlainText);
uint8_t *ciphertextBytes = reinterpret_cast<uint8_t *>(aCipherText);
uint8_t byte;
OT_ASSERT(mPlainTextCur + aLength <= mPlainTextLength);
for (unsigned i = 0; i < aLength; i++)
{
if (mCtrLength == 16)
{
for (int j = sizeof(mCtr) - 1; j > mNonceLength; j--)
{
if (++mCtr[j])
{
break;
}
}
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mCtr, mCtrPad);
mCtrLength = 0;
}
byte = plaintextBytes[i];
ciphertextBytes[i] = byte ^ mCtrPad[mCtrLength++];
if (mBlockLength == sizeof(mBlock))
{
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mBlock, mBlock);
mBlockLength = 0;
}
mBlock[mBlockLength++] ^= byte;
}
mPlainTextCur += aLength;
if (mPlainTextCur >= mPlainTextLength)
{
if (mBlockLength != 0)
{
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mBlock, mBlock);
}
// reset counter
memset(&mCtr[mNonceLength + 1], 0, sizeof(mCtr) - mNonceLength - 1);
}
}
void TxSecurityProcessing::Finalize(void *aTag)
{
uint8_t *tagBytes = reinterpret_cast<uint8_t *>(aTag);
OT_ASSERT(mPlainTextCur == mPlainTextLength);
sli_aes_crypt_ecb_radio(true, mKey, kKeyBits, mCtr, mCtrPad);
for (int i = 0; i < mTagLength; i++)
{
tagBytes[i] = mBlock[i] ^ mCtrPad[i];
}
}
#endif
#if defined(LPWAES_PRESENT)
static inline void efr32CreateKeyDesc(const otMacKeyMaterial *key, sli_crypto_descriptor_t *key_desc)
{
key_desc->location = SLI_CRYPTO_KEY_LOCATION_PLAINTEXT;
key_desc->engine = SLI_CRYPTO_LPWAES;
key_desc->key.plaintext_key.buffer.pointer = (uint8_t *)key->mKeyMaterial.mKey.m8;
key_desc->key.plaintext_key.buffer.size = OT_MAC_KEY_SIZE;
key_desc->key.plaintext_key.key_size = OT_MAC_KEY_SIZE;
}
#endif
void efr32PlatProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress)
{
#if (OPENTHREAD_RADIO && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2))
OT_UNUSED_VARIABLE(aFrame);
OT_UNUSED_VARIABLE(aExtAddress);
#else
uint32_t frameCounter = 0;
uint8_t tagLength;
uint8_t securityLevel;
uint8_t nonce[Crypto::AesCcm::kNonceSize];
Mac::TxFrame *aTxFrame = static_cast<Mac::TxFrame *>(aFrame);
VerifyOrExit(aTxFrame->GetSecurityEnabled());
SuccessOrExit(aTxFrame->GetSecurityLevel(securityLevel));
SuccessOrExit(aTxFrame->GetFrameCounter(frameCounter));
Crypto::AesCcm::GenerateNonce(*static_cast<const Mac::ExtAddress *>(aExtAddress),
frameCounter,
securityLevel,
nonce);
tagLength = aTxFrame->GetFooterLength() - aTxFrame->GetFcsSize();
#if defined(RADIOAES_PRESENT)
TxSecurityProcessing packetSecurityHandler;
packetSecurityHandler.SetKey(aFrame->mInfo.mTxInfo.mAesKey->mKeyMaterial.mKey.m8);
packetSecurityHandler.Init(aTxFrame->GetHeaderLength(),
aTxFrame->GetPayloadLength(),
tagLength,
nonce,
sizeof(nonce));
packetSecurityHandler.Header(aTxFrame->GetHeader(), aTxFrame->GetHeaderLength());
packetSecurityHandler.Payload(aTxFrame->GetPayload(), aTxFrame->GetPayload(), aTxFrame->GetPayloadLength());
packetSecurityHandler.Finalize(aTxFrame->GetFooter());
#elif defined(LPWAES_PRESENT)
sli_crypto_descriptor_t key_desc;
sl_status_t ret;
efr32CreateKeyDesc(aFrame->mInfo.mTxInfo.mAesKey, &key_desc);
ret =
sli_crypto_ccm(&key_desc,
true,
((securityLevel >= Mac::Frame::SecurityLevel::kSecurityEnc) ? aTxFrame->GetPayload() : NULL),
((securityLevel >= Mac::Frame::SecurityLevel::kSecurityEnc) ? aTxFrame->GetPayloadLength() : 0),
aTxFrame->GetPayload(),
nonce,
sizeof(nonce),
aTxFrame->GetHeader(),
aTxFrame->GetHeaderLength(),
aTxFrame->GetPayload() + aTxFrame->GetPayloadLength(),
tagLength);
OT_ASSERT(ret == SL_STATUS_OK);
#endif
aTxFrame->SetIsSecurityProcessed(true);
exit:
return;
#endif // OPENTHREAD_RADIO && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2))
}
bool efr32IsFramePending(otRadioFrame *aFrame)
{
return static_cast<Mac::RxFrame *>(aFrame)->GetFramePending();
}
otPanId efr32GetDstPanId(otRadioFrame *aFrame)
{
otPanId aPanId = 0xFFFF;
if (static_cast<Mac::RxFrame *>(aFrame)->IsDstPanIdPresent())
{
static_cast<Mac::RxFrame *>(aFrame)->GetDstPanId(aPanId);
}
return aPanId;
}
uint8_t *efr32GetPayload(otRadioFrame *aFrame)
{
uint8_t *payload = static_cast<Mac::RxFrame *>(aFrame)->GetPayload();
return payload;
}
bool efr32FrameIsPanIdCompressed(otRadioFrame *aFrame)
{
return static_cast<Mac::RxFrame *>(aFrame)->IsPanIdCompressed();
}
uint16_t efr32GetFrameVersion(otRadioFrame *aFrame)
{
return static_cast<Mac::RxFrame *>(aFrame)->GetVersion();
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for 802.15.4 frame processing.
*/
#ifndef IEEE802154_PACKET_UTILS_HPP_
#define IEEE802154_PACKET_UTILS_HPP_
#include "openthread-core-config.h"
#include <openthread/platform/crypto.h>
#include <stdint.h>
#include "common/error.hpp"
#include "crypto/aes_ecb.hpp"
#include "mac/mac_types.hpp"
/**
* This class implements Packet Processing.
*
*/
class TxSecurityProcessing
{
public:
enum
{
kBlockSize = 16, ///< AES-128 block size (bytes).
kKeyBits = 128
};
/**
* This method sets the key.
*
* @param[in] aKey Pointer to the AES Key to use.
*
*/
void SetKey(const uint8_t *aKey) { mKey = aKey; }
/**
* This method initializes the AES CCM computation.
*
* @param[in] aHeaderLength Length of header in bytes.
* @param[in] aPlainTextLength Length of plaintext in bytes.
* @param[in] aTagLength Length of tag in bytes (must be even and in `[kMinTagLength, kMaxTagLength]`).
* @param[in] aNonce A pointer to the nonce.
* @param[in] aNonceLength Length of nonce in bytes.
*
*/
void Init(uint32_t aHeaderLength,
uint32_t aPlainTextLength,
uint8_t aTagLength,
const void *aNonce,
uint8_t aNonceLength);
/**
* This method processes the header.
*
* @param[in] aHeader A pointer to the header.
* @param[in] aHeaderLength Length of header in bytes.
*
*/
void Header(const void *aHeader, uint32_t aHeaderLength);
/**
* This method processes the payload.
*
* @param[inout] aPlainText A pointer to the plaintext.
* @param[inout] aCipherText A pointer to the ciphertext.
* @param[in] aLength Payload length in bytes.
* @param[in] aMode Mode to indicate whether to encrypt (`kEncrypt`) or decrypt (`kDecrypt`).
*
*/
void Payload(void *aPlainText, void *aCipherText, uint32_t aLength);
/**
* This method returns the tag length in bytes.
*
* @returns The tag length in bytes.
*
*/
uint8_t GetTagLength(void) const { return mTagLength; }
/**
* This method generates the tag.
*
* @param[out] aTag A pointer to the tag (must have `GetTagLength()` bytes).
*
*/
void Finalize(void *aTag);
private:
uint8_t mBlock[kBlockSize];
uint8_t mCtr[kBlockSize];
uint8_t mCtrPad[kBlockSize];
const uint8_t *mKey;
uint32_t mHeaderLength;
uint32_t mHeaderCur;
uint32_t mPlainTextLength;
uint32_t mPlainTextCur;
uint16_t mBlockLength;
uint16_t mCtrLength;
uint8_t mNonceLength;
uint8_t mTagLength;
};
/**
* @}
*
*/
#endif // IEEE802154_PACKET_UTILS_HPP_

View File

@@ -0,0 +1,198 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file holds required 802.15.4 definitions
*
*/
#ifndef __IEEE802154IEEE802154_H__
#define __IEEE802154IEEE802154_H__
#define IEEE802154_MIN_LENGTH \
4 // Technically, a version 2 packet / ACK
// can be 4 bytes with seq# suppression
#define IEEE802154_MAX_LENGTH 127
#define IEEE802154_MIN_DATA_LENGTH 5
// FCF + DSN + dest PANID + dest addr + src PANID + src addr (without security header)
#define IEEE802154_MAX_MHR_LENGTH (2 + 1 + 2 + 8 + 2 + 8)
#define IEEE802154_DSN_OFFSET 2
#define IEEE802154_FCF_OFFSET 0
//------------------------------------------------------------------------
// 802.15.4 Frame Control Field definitions for Beacon, Ack, Data, Command
#define IEEE802154_FRAME_TYPE_BEACON ((uint16_t)0x0000U) // Beacon
#define IEEE802154_FRAME_TYPE_DATA ((uint16_t)0x0001U) // Data
#define IEEE802154_FRAME_TYPE_ACK ((uint16_t)0x0002U) // ACK
#define IEEE802154_FRAME_TYPE_COMMAND ((uint16_t)0x0003U) // Command
#define IEEE802154_FRAME_TYPE_CONTROL IEEE802154_FRAME_TYPE_COMMAND // (synonym)
// 802.15.4E-2012 introduced MultiPurpose with different Frame Control Field
// layout described in the MultiPurpose section below.
#define IEEE802154_FRAME_TYPE_MULTIPURPOSE ((uint16_t)0x0005U) // MultiPurpose
#define IEEE802154_FRAME_TYPE_RESERVED_1 ((uint16_t)0x0004U)
#define IEEE802154_FRAME_TYPE_RESERVED_2 ((uint16_t)0x0006U)
#define IEEE802154_FRAME_TYPE_RESERVED_3 ((uint16_t)0x0007U)
#define IEEE802154_FRAME_TYPE_MASK ((uint16_t)0x0007U) // Bits 0..2
// Use a reserved flag internally to check whether outgoing enh-ACK was secure
#define IEEE802154_SECURED_OUTGOING_ENHANCED_ACK IEEE802154_FRAME_TYPE_RESERVED_1
#define IEEE802154_FRAME_FLAG_SECURITY_ENABLED ((uint16_t)0x0008U) // Bit 3
#define IEEE802154_FRAME_FLAG_FRAME_PENDING ((uint16_t)0x0010U) // Bit 4
#define IEEE802154_FRAME_FLAG_ACK_REQUIRED ((uint16_t)0x0020U) // Bit 5
#define IEEE802154_FRAME_FLAG_INTRA_PAN ((uint16_t)0x0040U) // Bit 6
// 802.15.4-2006 renamed the Intra-Pan flag PanId-Compression
#define IEEE802154_FRAME_FLAG_PANID_COMPRESSION IEEE802154_FRAME_FLAG_INTRA_PAN
#define IEEE802154_FRAME_FLAG_RESERVED ((uint16_t)0x0080U) // Bit 7 reserved
// Use the reserved flag internally to check whether frame pending bit was set in outgoing ACK
#define IEEE802154_FRAME_PENDING_SET_IN_OUTGOING_ACK IEEE802154_FRAME_FLAG_RESERVED
// 802.15.4E-2012 introduced these flags for Frame Version 2 frames
// which are reserved bit positions in earlier Frame Version frames:
#define IEEE802154_FRAME_FLAG_SEQ_SUPPRESSION ((uint16_t)0x0100U) // Bit 8
#define IEEE802154_FRAME_FLAG_IE_LIST_PRESENT ((uint16_t)0x0200U) // Bit 9
#define IEEE802154_FRAME_DESTINATION_MODE_MASK ((uint16_t)0x0C00U) // Bits 10..11
#define IEEE802154_FRAME_DESTINATION_MODE_NONE ((uint16_t)0x0000U) // Mode 0
#define IEEE802154_FRAME_DESTINATION_MODE_RESERVED ((uint16_t)0x0400U) // Mode 1
#define IEEE802154_FRAME_DESTINATION_MODE_SHORT ((uint16_t)0x0800U) // Mode 2
#define IEEE802154_FRAME_DESTINATION_MODE_LONG ((uint16_t)0x0C00U) // Mode 3
// 802.15.4e-2012 only (not adopted into 802.15.4-2015)
#define IEEE802154_FRAME_DESTINATION_MODE_BYTE IEEE802154_FRAME_DESTINATION_MODE_RESERVED
#define IEEE802154_FRAME_VERSION_MASK ((uint16_t)0x3000U) // Bits 12..13
#define IEEE802154_FRAME_VERSION_2003 ((uint16_t)0x0000U) // Version 0
#define IEEE802154_FRAME_VERSION_2006 ((uint16_t)0x1000U) // Version 1
// In 802.15.4-2015, Version 2 is just called "IEEE STD 802.15.4"
// which can be rather confusing. It was introduced in 802.15.4E-2012.
#define IEEE802154_FRAME_VERSION_2012 ((uint16_t)0x2000U) // Version 2
#define IEEE802154_FRAME_VERSION_2015 ((uint16_t)0x2000U) // Version 2
#define IEEE802154_FRAME_VERSION_RESERVED ((uint16_t)0x3000U) // Version 3
#define IEEE802154_FRAME_SOURCE_MODE_MASK ((uint16_t)0xC000U) // Bits 14..15
#define IEEE802154_FRAME_SOURCE_MODE_NONE ((uint16_t)0x0000U) // Mode 0
#define IEEE802154_FRAME_SOURCE_MODE_RESERVED ((uint16_t)0x4000U) // Mode 1
#define IEEE802154_FRAME_SOURCE_MODE_SHORT ((uint16_t)0x8000U) // Mode 2
#define IEEE802154_FRAME_SOURCE_MODE_LONG ((uint16_t)0xC000U) // Mode 3
// 802.15.4e-2012 only (not adopted into 802.15.4-2015)
#define IEEE802154_FRAME_SOURCE_MODE_BYTE IEEE802154_FRAME_SOURCE_MODE_RESERVED
//------------------------------------------------------------------------
// 802.15.4E-2012 Frame Control Field definitions for MultiPurpose
#define IEEE802154_MP_FRAME_TYPE_MASK IEEE802154_FRAME_TYPE_MASK // Bits 0..2
#define IEEE802154_MP_FRAME_TYPE_MULTIPURPOSE IEEE802154_FRAME_TYPE_MULTIPURPOSE
#define IEEE802154_MP_FRAME_FLAG_LONG_FCF ((uint16_t)0x0008U) // Bit 3
#define IEEE802154_MP_FRAME_DESTINATION_MODE_MASK ((uint16_t)0x0030U) // Bits 4..5
#define IEEE802154_MP_FRAME_DESTINATION_MODE_NONE ((uint16_t)0x0000U) // Mode 0
#define IEEE802154_MP_FRAME_DESTINATION_MODE_RESERVED ((uint16_t)0x0010U) // Mode 1
#define IEEE802154_MP_FRAME_DESTINATION_MODE_SHORT ((uint16_t)0x0020U) // Mode 2
#define IEEE802154_MP_FRAME_DESTINATION_MODE_LONG ((uint16_t)0x0030U) // Mode 3
// 802.15.4e-2012 only (not adopted into 802.15.4-2015)
#define IEEE802154_MP_FRAME_DESTINATION_MODE_BYTE IEEE802154_MP_FRAME_DESTINATION_MODE_RESERVED
#define IEEE802154_MP_FRAME_SOURCE_MODE_MASK ((uint16_t)0x00C0U) // Bits 6..7
#define IEEE802154_MP_FRAME_SOURCE_MODE_NONE ((uint16_t)0x0000U) // Mode 0
#define IEEE802154_MP_FRAME_SOURCE_MODE_RESERVED ((uint16_t)0x0040U) // Mode 1
#define IEEE802154_MP_FRAME_SOURCE_MODE_SHORT ((uint16_t)0x0080U) // Mode 2
#define IEEE802154_MP_FRAME_SOURCE_MODE_LONG ((uint16_t)0x00C0U) // Mode 3
// 802.15.4e-2012 only (not adopted into 802.15.4-2015)
#define IEEE802154_MP_FRAME_SOURCE_MODE_BYTE IEEE802154_MP_FRAME_SOURCE_MODE_RESERVED
#define IEEE802154_MP_FRAME_FLAG_PANID_PRESENT ((uint16_t)0x0100U) // Bit 8
#define IEEE802154_MP_FRAME_FLAG_SECURITY_ENABLED ((uint16_t)0x0200U) // Bit 9
#define IEEE802154_MP_FRAME_FLAG_SEQ_SUPPRESSION ((uint16_t)0x0400U) // Bit 10
#define IEEE802154_MP_FRAME_FLAG_FRAME_PENDING ((uint16_t)0x0800U) // Bit 11
#define IEEE802154_MP_FRAME_VERSION_MASK IEEE802154_FRAME_VERSION_MASK // Bits 12..13
#define IEEE802154_MP_FRAME_VERSION_2012 ((uint16_t)0x0000U) // Zeroed out
#define IEEE802154_MP_FRAME_VERSION_2015 ((uint16_t)0x0000U) // Zeroed out
// All other MultiPurpose Frame Versions are reserved
#define IEEE802154_MP_FRAME_FLAG_ACK_REQUIRED ((uint16_t)0x4000U) // Bit 14
#define IEEE802154_MP_FRAME_FLAG_IE_LIST_PRESENT ((uint16_t)0x8000U) // Bit 15
//------------------------------------------------------------------------
// Information Elements fields
#define IEEE802154_KEYID_MODE_0 ((uint8_t)0x0000U)
#define IEEE802154_KEYID_MODE_0_SIZE 0
#define IEEE802154_KEYID_MODE_1 ((uint8_t)0x0008U)
#define IEEE802154_KEYID_MODE_1_SIZE 0
#define IEEE802154_KEYID_MODE_2 ((uint8_t)0x0010U)
#define IEEE802154_KEYID_MODE_2_SIZE 4
#define IEEE802154_KEYID_MODE_3 ((uint8_t)0x0018U)
#define IEEE802154_KEYID_MODE_3_SIZE 8
#define IEEE802154_KEYID_MODE_MASK ((uint8_t)0x0018U)
//------------------------------------------------------------------------
// Information Elements fields
// There are Header IEs and Payload IEs. Header IEs are authenticated
// if MAC Security is enabled. Payload IEs are both authenticated and
// encrypted if MAC security is enabled.
// Header and Payload IEs have slightly different formats and different
// contents based on the 802.15.4 spec.
// Both are actually a list of IEs that continues until a termination
// IE is seen.
#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_LENGTH_MASK 0x007F // bits 0-6
#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_ID_MASK 0x7F80 // bits 7-14
#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_TYPE_MASK 0x8000 // bit 15
#define IEEE802154_FRAME_HEADER_INFO_ELEMENT_ID_SHIFT 7
#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_LENGTH_MASK 0x07FF // bits 0 -10
#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_GROUP_ID_MASK 0x7800 // bits 11-14
#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_TYPE_MASK 0x8000 // bit 15
#define IEEE802154_FRAME_PAYLOAD_INFO_ELEMENT_ID_SHIFT 11
// This "type" field indicates header vs. payload IE. However there is
// also a Header IE List terminator which would imply the IE list
// that follows is only payload IEs.
#define IEEE802154_FRAME_INFO_ELEMENT_TYPE_MASK 0x8000
// Header Termination ID 1 is used when there are Payload IEs that follow.
// Header Termination ID 2 is used when there are no Payload IEs and the
// next field is the MAC payload.
#define IEEE802154_FRAME_HEADER_TERMINATION_ID_1 0x7E
#define IEEE802154_FRAME_HEADER_TERMINATION_ID_2 0x7F
#define IEEE802154_FRAME_PAYLOAD_TERMINATION_ID 0x0F
#endif //__IEEE802154IEEE802154_H__

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform-efr32.h"
#include <openthread-core-config.h>
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
#include <openthread/platform/memory.h>
#include "sl_memory_manager.h"
void *otPlatCAlloc(size_t aNum, size_t aSize)
{
return sl_calloc(aNum, aSize);
}
void otPlatFree(void *aPtr)
{
sl_free(aPtr);
}
#endif

View File

@@ -0,0 +1,256 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for miscellaneous behaviors.
*/
#include <openthread-core-config.h>
#include <openthread/platform/misc.h>
#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
#include "btl_interface.h"
#endif
#if defined(SL_CATALOG_EMLIB_RMU_PRESENT)
#include "em_rmu.h"
#else
#include "sl_hal_emu.h"
#endif
#include "platform-efr32.h"
#if SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO
#include "sl_gpio.h"
#include "sl_sleeptimer.h"
static sl_sleeptimer_timer_handle_t wake_timer;
extern sl_gpio_t host_wakeup_gpio;
#endif
static uint32_t sResetCause;
void efr32MiscInit(void)
{
#if defined(_SILICON_LABS_32B_SERIES_2)
// Read the cause of last reset.
sResetCause = RMU_ResetCauseGet();
// Clear the register, as the causes cumulate over resets.
RMU_ResetCauseClear();
#else
// Read the cause of last reset.
sResetCause = sl_hal_emu_get_reset_cause();
// Clear the register, as the causes cumulate over resets.
sl_hal_emu_clear_reset_cause();
#endif
}
void otPlatReset(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
NVIC_SystemReset();
}
OT_TOOL_WEAK void bootloader_rebootAndInstall(void)
{
// Weak stub function
// This should be discarded in favor of the function definition in bootloader_interface code, when that component is
// used
}
otError otPlatResetToBootloader(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
bootloader_rebootAndInstall();
// This should only be reached if the bootloader_interface component is not present.
// When it is present, the stubbed bootloader_rebootAndInstall above is not used.
// Instead, the non-weak definition of the function in the component is used, causing
// the device to reset.
return OT_ERROR_NOT_CAPABLE;
}
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
otPlatResetReason reason = OT_PLAT_RESET_REASON_UNKNOWN;
#if defined(_EMU_RSTCAUSE_MASK)
if (sResetCause & EMU_RSTCAUSE_POR)
{
reason = OT_PLAT_RESET_REASON_POWER_ON;
}
else if (sResetCause & EMU_RSTCAUSE_SYSREQ)
{
reason = OT_PLAT_RESET_REASON_SOFTWARE;
}
else if ((sResetCause & EMU_RSTCAUSE_WDOG0) || (sResetCause & EMU_RSTCAUSE_WDOG1))
{
reason = OT_PLAT_RESET_REASON_WATCHDOG;
}
else if (sResetCause & EMU_RSTCAUSE_PIN)
{
reason = OT_PLAT_RESET_REASON_EXTERNAL;
}
else if (sResetCause & EMU_RSTCAUSE_LOCKUP)
{
reason = OT_PLAT_RESET_REASON_FAULT;
}
/* clang-format off */
else if ((sResetCause & EMU_RSTCAUSE_AVDDBOD)
|| (sResetCause & EMU_RSTCAUSE_DECBOD)
|| (sResetCause & EMU_RSTCAUSE_DVDDBOD)
|| (sResetCause & EMU_RSTCAUSE_DVDDLEBOD)
|| (sResetCause & EMU_RSTCAUSE_EM4))
/* clang-format on */
{
reason = OT_PLAT_RESET_REASON_OTHER;
}
#endif
#if defined(_RMU_RSTCAUSE_MASK)
if (sResetCause & RMU_RSTCAUSE_PORST)
{
reason = OT_PLAT_RESET_REASON_POWER_ON;
}
else if (sResetCause & RMU_RSTCAUSE_SYSREQRST)
{
reason = OT_PLAT_RESET_REASON_SOFTWARE;
}
else if (sResetCause & RMU_RSTCAUSE_WDOGRST)
{
reason = OT_PLAT_RESET_REASON_WATCHDOG;
}
else if (sResetCause & RMU_RSTCAUSE_EXTRST)
{
reason = OT_PLAT_RESET_REASON_EXTERNAL;
}
else if (sResetCause & RMU_RSTCAUSE_LOCKUPRST)
{
reason = OT_PLAT_RESET_REASON_FAULT;
}
/* clang-format off */
else if ((sResetCause & RMU_RSTCAUSE_AVDDBOD)
|| (sResetCause & RMU_RSTCAUSE_DECBOD)
|| (sResetCause & RMU_RSTCAUSE_DVDDBOD)
|| (sResetCause & RMU_RSTCAUSE_EM4RST))
/* clang-format on */
{
reason = OT_PLAT_RESET_REASON_OTHER;
}
#endif
return reason;
}
// Timer callback function to clear the GPIO pin
#if SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO
static void clearWakeHostPin(sl_sleeptimer_timer_handle_t *handle, void *data)
{
(void)handle;
(void)data;
// Clear the GPIO pin
sl_gpio_clear_pin(&host_wakeup_gpio);
}
#endif
OT_TOOL_WEAK void otPlatEfrWakeHost(void)
{
// Set the GPIO pin to wake up the host
#if SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO
sl_gpio_set_pin(&host_wakeup_gpio);
// Start a timer to clear the GPIO pin after the timeout
sl_sleeptimer_start_timer_ms(&wake_timer, SL_OPENTHREAD_HOST_CLEAR_PIN_TIMEOUT_MS, clearWakeHostPin, NULL, 0, 0);
#endif
}
void otPlatWakeHost(void)
{
otPlatEfrWakeHost();
}
OT_TOOL_WEAK void otCliOutputFormat(const char *aFmt, ...)
{
OT_UNUSED_VARIABLE(aFmt);
// do nothing
}
OT_TOOL_WEAK void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list aArgs)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
OT_UNUSED_VARIABLE(aFormat);
OT_UNUSED_VARIABLE(aArgs);
// do nothing
}
OT_TOOL_WEAK void efr32UartProcess(void)
{
// do nothing
}
otError railStatusToOtError(RAIL_Status_t status)
{
switch (status)
{
case RAIL_STATUS_NO_ERROR:
return OT_ERROR_NONE;
case RAIL_STATUS_INVALID_PARAMETER:
return OT_ERROR_INVALID_ARGS;
case RAIL_STATUS_INVALID_STATE:
return OT_ERROR_INVALID_STATE;
case RAIL_STATUS_INVALID_CALL:
case RAIL_STATUS_SUSPENDED:
case RAIL_STATUS_SCHED_ERROR:
default:
return OT_ERROR_FAILED;
}
}
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
otError otPlatLogCrashDump(void)
{
otError error = OT_ERROR_NONE;
#if defined(SL_CATALOG_OT_CRASH_HANDLER_PRESENT)
efr32PrintResetInfo();
#else
error = OT_ERROR_NOT_CAPABLE;
#endif
return error;
}
#endif

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_
#define OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_
#include "board_config.h"
#ifndef RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
#if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
#error "Platform not configured to support configuration option: OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT"
#endif
#endif
#ifndef RADIO_CONFIG_915MHZ_2GFSK_SUPPORT
#if OPENTHREAD_CONFIG_RADIO_915MHZ_2GFSK_SUPPORT
#error "Platform not configured to support configuration option: OPENTHREAD_CONFIG_RADIO_915MHZ_2GFSK_SUPPORT"
#endif
#endif
#if !defined(RADIO_CONFIG_915MHZ_OQPSK_SUPPORT) && !defined(RADIO_CONFIG_SUBGHZ_SUPPORT) \
&& !defined(RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT)
#error \
"One of the following must be defined: RADIO_CONFIG_915MHZ_OQPSK_SUPPORT, RADIO_CONFIG_SUBGHZ_SUPPORT or RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT"
#endif
#if defined(_SILICON_LABS_32B_SERIES_1)
#error "EFR32 Series 1 parts are not supported."
#endif
#endif /* OPENTHREAD_CORE_EFR32_CONFIG_CHECK_H_ */

View File

@@ -0,0 +1,625 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes all compile-time configuration constants used by
* efr32 applications for OpenThread.
*/
#ifndef OPENTHREAD_CORE_EFR32_CONFIG_H_
#define OPENTHREAD_CORE_EFR32_CONFIG_H_
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif
#ifdef SL_CATALOG_CLOCK_MANAGER_PRESENT
#include "sl_clock_manager_oscillator_config.h"
#else
#include "sl_device_init_hfxo.h"
#include "sl_device_init_hfxo_config.h"
#endif
#if defined(HARDWARE_BOARD_HAS_LFXO) && !defined(SL_CATALOG_CLOCK_MANAGER_PRESENT)
#include "sl_device_init_lfxo.h"
#include "sl_device_init_lfxo_config.h"
#endif
// Use (user defined) application config file to define OpenThread configurations
#ifdef SL_OPENTHREAD_APPLICATION_CONFIG_FILE
#include SL_OPENTHREAD_APPLICATION_CONFIG_FILE
#endif
// Use (pre-defined) stack features config file available for applications built
// with Simplicity Studio
#ifdef SL_OPENTHREAD_STACK_FEATURES_CONFIG_FILE
#include SL_OPENTHREAD_STACK_FEATURES_CONFIG_FILE
#endif
#include "board_config.h"
#include "em_device.h"
/**
* @def OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
*
* Allow triggering a platform reset to bootloader mode, if supported.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
#if defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
#define OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE 1
#else
#define OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE 0
#endif
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE
*
* Calling crypto functions in interrupt context when another operation is running
* causes issues in Series-2 devices. To safeguard enhanced ACK encryption, it is
* better to use RADIOAES and not rely on SE. For series-2 devices, this means we
* make MAC keys exportable and copy the literal keys in radio.c (instead of using
* key references)
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE 1
/*
* @def OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
*
* Define to 1 if you want to enable physical layer to support OQPSK modulation in 915MHz band.
* (currently not supported).
*
*/
#if RADIO_CONFIG_915MHZ_OQPSK_SUPPORT
#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 1
#else
#define OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT 0
#endif
/*
* @def OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
*
* Define to 1 if you want to enable physical layer to support OQPSK modulation in 2.4GHz band.
*
*/
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 1
#else
#define OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT 0
#endif
/*
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
*
* Define to 1 if you want to enable physical layer to support proprietary radio configurations.
*
* This configuration option is used by the Sub-GHz feature to specify proprietary radio parameters,
* currently not defined by the Thread spec.
*/
#if RADIO_CONFIG_SUBGHZ_SUPPORT
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT 1
#else
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT 0
#endif
#if RADIO_CONFIG_SUBGHZ_SUPPORT
/**
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE
*
* Channel Page value for (proprietary) Sub-GHz PHY using 2GFSK modulation in 915MHz band.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE 23
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN
*
* Minimum Channel number supported with (proprietary) Sub-GHz PHY using 2GFSK modulation in 915MHz band.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN 0
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX
*
* Maximum Channel number supported with (proprietary) Sub-GHz PHY using 2GFSK modulation in 915MHz band.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX 24
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK
*
* Default Channel Mask for (proprietary) Sub-GHz PHY using 2GFSK modulation in 915MHz band.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK 0x1ffffff
#endif
/**
* @def OPENTHREAD_CONFIG_DEFAULT_CHANNEL
*
* Default channel to use when working with proprietary radio configurations.
*
*/
#ifndef OPENTHREAD_CONFIG_DEFAULT_CHANNEL
#define OPENTHREAD_CONFIG_DEFAULT_CHANNEL OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN
#endif
#endif // RADIO_CONFIG_SUBGHZ_SUPPORT
/**
* @def OPENTHREAD_CONFIG_PLATFORM_INFO
*
* The platform-specific string to insert into the OpenThread version string.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_INFO
#define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32"
#endif
/**
* @def OPENTHREAD_CONFIG_UPTIME_ENABLE
*
* (For FTDs only) Define to 1 to enable tracking the uptime of OpenThread instance.
*
*/
#ifndef OPENTHREAD_CONFIG_UPTIME_ENABLE
#define OPENTHREAD_CONFIG_UPTIME_ENABLE OPENTHREAD_FTD
#endif
/**
* @def OPENTHREAD_CONFIG_CHILD_SUPERVISION_CHECK_TIMEOUT
*
* The default supervision check timeout interval (in seconds) used by a device in child state. Set to zero to disable
* the supervision check process on the child.
*
* The check timeout interval can be changed using `otChildSupervisionSetCheckTimeout()`.
*
* If the sleepy child does not hear from its parent within the specified timeout interval, it initiates the re-attach
* process (MLE Child Update Request/Response exchange with its parent).
*
* Setting to zero by default as this is an optional feature that can lead to unexpected detach behavior.
*
*/
#ifndef OPENTHREAD_CONFIG_CHILD_SUPERVISION_CHECK_TIMEOUT
#define OPENTHREAD_CONFIG_CHILD_SUPERVISION_CHECK_TIMEOUT 0
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US
*
* Define how many microseconds ahead should MAC deliver CSL frame to SubMac.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US
#if defined(_SILICON_LABS_32B_SERIES_3)
#define OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US 15000
#else
#define OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US 2000
#endif
#endif
/**
* @def OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD
*
* Reception scheduling and ramp up time needed for the CSL receiver to be ready, in units of microseconds.
*
*/
#ifndef OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD
#define OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD 600
#endif
/**
* @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD
*
* The minimum time (in microseconds) before the MHR start that the radio should be in receive state and ready to
* properly receive in order to properly receive any IEEE 802.15.4 frame. Defaults to the duration of SHR + PHR.
*
* 802.15.4 2.4GHz OQPSK:
* SHR: 4 bytes of preamble, 1 byte of sync word
* PHR: 1 byte
* Total (6 * 32) = 192 us.
*
* Proprietary SubGhz (2GFSK in 915MHz):
* SHR: 4 bytes preamble, 2 bytes SFD = 6 bytes
* PHR: 2 bytes
* Total (8 * 32) = 256 us.
*
*/
#ifndef OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD
#if RADIO_CONFIG_SUBGHZ_SUPPORT
#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD 256
#else
#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD 192
#endif
#endif
/**
* @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER
*
* The minimum time (in microseconds) after the MHR start that the radio should be in receive state in order
* to properly receive any IEEE 802.15.4 frame. Defaults to the duration of a maximum size frame, plus AIFS,
* plus the duration of maximum enh-ack frame. Platforms are encouraged to improve this value for energy
* efficiency purposes.
*
* In theory, RAIL should automatically extend the duration of the receive window once the SHR has been
* detected, so we should be able to set this to zero.
*
*/
#ifndef OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER
#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER 0
#endif
/*
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
*
* Define to 1 if you want to enable software retransmission logic.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE OPENTHREAD_RADIO
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
*
* Define to 1 if you want to enable software CSMA-CA backoff logic.
* RCPs only.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
*
* Define to 1 if you want to enable software transmission security logic.
* RCPs only.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE \
(OPENTHREAD_RADIO && (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2))
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE
*
* Define to 1 to enable software transmission target time logic.
* RCPs only.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RX_TIMING_ENABLE
*
* Define to 1 to enable software reception target time logic.
* RCPs only.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RX_TIMING_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RX_TIMING_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
*
* Define to 1 if you want to enable software energy scanning logic.
* RCPs only.
*
*/
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
*
* Define to 1 if you want to support microsecond timer in platform.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
#define OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
*
* Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
*
* When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_TCP_ENABLE
*
* Define as 1 to enable OpenThread TCP API
*
*/
#ifndef OPENTHREAD_CONFIG_TCP_ENABLE
#define OPENTHREAD_CONFIG_TCP_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_NCP_HDLC_ENABLE
*
* Define to 1 to enable the NCP HDLC interface.
*
*/
#ifndef OPENTHREAD_CONFIG_NCP_HDLC_ENABLE
#define OPENTHREAD_CONFIG_NCP_HDLC_ENABLE 1
#endif
/**
* @def OPENTHREAD_CONFIG_NCP_CPC_ENABLE
*
* Define to 1 to enable NCP CPC support.
*
*/
#ifndef OPENTHREAD_CONFIG_NCP_CPC_ENABLE
#define OPENTHREAD_CONFIG_NCP_CPC_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_NCP_SPI_ENABLE
*
* Define to 1 to enable NCP SPI support.
*
*/
#ifndef OPENTHREAD_CONFIG_NCP_SPI_ENABLE
#define OPENTHREAD_CONFIG_NCP_SPI_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS
*
* Minimum duration in ms below which the platform will not
* enter a deep sleep (EM2) mode.
*
*/
#ifndef OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS
#define OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS 5
#endif
/**
* @def OPENTHREAD_CONFIG_EFR32_UART_TX_FLUSH_TIMEOUT_MS
*
* Maximum time to wait for a flush to complete in otPlatUartFlush().
*
* Value is in milliseconds
*
*/
#ifndef OPENTHREAD_CONFIG_EFR32_UART_TX_FLUSH_TIMEOUT_MS
#define OPENTHREAD_CONFIG_EFR32_UART_TX_FLUSH_TIMEOUT_MS 500
#endif
/**
* @def OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET
*
* This is the offset in ITS where the persistent keys are stored.
* For Silabs OT applications, this needs to be in the range of
* 0x20000 to 0x2ffff.
*
*/
#define OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET 0x20000
/**
* @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
*
* This config enables key references to be used in Openthread stack instead of
* literal keys.
*
* Platform needs to support PSA Crypto to enable this option.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
#if OPENTHREAD_RADIO
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 0
#else
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1
#endif
#endif
/**
* @def OPENTHREAD_CONFIG_CRYPTO_LIB
*
* Selects the crypto backend library for OpenThread.
*
* There are several options available, but we enable PSA if key references are
* available. Otherwise, mbedTLS is used as default (see src/core/config/crypto.h)
*
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM
*
*/
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
#endif
/**
* @def SL_OPENTHREAD_CSL_TX_UNCERTAINTY
*
* Uncertainty of scheduling a CSL transmission, in ±10 us units.
*
* Note: This value was carefully configured to meet Thread certification
* requirements for Silicon Labs devices.
*
*/
#ifndef SL_OPENTHREAD_CSL_TX_UNCERTAINTY
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
#define SL_OPENTHREAD_CSL_TX_UNCERTAINTY 175
#elif OPENTHREAD_FTD
// Approx. ~128 us. for single CCA + some additional tx uncertainty in testing
#define SL_OPENTHREAD_CSL_TX_UNCERTAINTY 20
#else
// Approx. ~128 us. for single CCA
//
// Note: Our SSEDs "schedule" transmissions to their parent in order to know
// exactly when in the future the data packets go out so they can calculate
// the accurate CSL phase to send to their parent.
//
// The receive windows on the SSEDs scale with this value, so increasing this
// uncertainty to account for full CCA/CSMA with 0..7 backoffs
// (see RAIL_CSMA_CONFIG_802_15_4_2003_2p4_GHz_OQPSK_CSMA) will mean that the
// receive windows can get very long (~ 5ms.)
//
// We have updated SSEDs to use a single CCA (RAIL_CSMA_CONFIG_SINGLE_CCA)
// instead. If they are in very busy channels, CSL won't be reliable anyway.
#define SL_OPENTHREAD_CSL_TX_UNCERTAINTY 12
#endif
#endif
/**
* @def SL_OPENTHREAD_HFXO_ACCURACY
*
* Worst case XTAL accuracy in units of ± ppm. Also used for calculations during CSL operations.
*
* @note Platforms may optimize this value based on operational conditions (i.e.: temperature).
*
*/
#ifndef SL_OPENTHREAD_HFXO_ACCURACY
#ifdef SL_CATALOG_CLOCK_MANAGER_PRESENT
#define SL_OPENTHREAD_HFXO_ACCURACY SL_CLOCK_MANAGER_HFXO_PRECISION
#else
#define SL_OPENTHREAD_HFXO_ACCURACY SL_DEVICE_INIT_HFXO_PRECISION
#endif
#endif
/**
* @def SL_OPENTHREAD_LFXO_ACCURACY
*
* Worst case XTAL accuracy in units of ± ppm. Also used for calculations during CSL operations.
*
* @note Platforms may optimize this value based on operational conditions (i.e.: temperature).
*/
#ifndef SL_OPENTHREAD_LFXO_ACCURACY
#if defined(HARDWARE_BOARD_HAS_LFXO)
#if SL_CATALOG_CLOCK_MANAGER_PRESENT
#define SL_OPENTHREAD_LFXO_ACCURACY SL_CLOCK_MANAGER_LFXO_PRECISION
#else
#define SL_OPENTHREAD_LFXO_ACCURACY SL_DEVICE_INIT_LFXO_PRECISION
#endif // SL_CATALOG_CLOCK_MANAGER_PRESENT
#else
#define SL_OPENTHREAD_LFXO_ACCURACY 0
#endif // HARDWARE_BOARD_HAS_LFXO
#endif
/**
* @def SL_OPENTHREAD_RADIO_CCA_MODE
*
* Defines the CCA mode to be used by the platform.
*
*/
#ifndef SL_OPENTHREAD_RADIO_CCA_MODE
#define SL_OPENTHREAD_RADIO_CCA_MODE RAIL_IEEE802154_CCA_MODE_RSSI
#endif
/**
* @def SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE
*
* Max Private key size supported by ECDSA Crypto handler.
*
*/
#ifndef SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE
#define SL_OPENTHREAD_ECDSA_PRIVATE_KEY_SIZE 32
#endif
/**
* @def SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO
*
* Define to 1 to enable the host wakeup GPIO functionality.
* This feature allows the platform to wake up the host using a GPIO pin.
*
* Default value is 0 (disabled).
*/
#ifndef SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO
#define SL_OPENTHREAD_ENABLE_HOST_WAKE_GPIO 0
#endif
/**
* @def SL_OPENTHREAD_HOST_WAKEUP_GPIO_PORT
*
* Defines the GPIO port for host wakeup.
*
*/
#ifndef SL_OPENTHREAD_HOST_WAKEUP_GPIO_PORT
#define SL_OPENTHREAD_HOST_WAKEUP_GPIO_PORT SL_GPIO_PORT_C
#endif
/**
* @def SL_OPENTHREAD_HOST_WAKEUP_GPIO_PIN
*
* Defines the GPIO pin for host wakeup.
*
*/
#ifndef SL_OPENTHREAD_HOST_WAKEUP_GPIO_PIN
#define SL_OPENTHREAD_HOST_WAKEUP_GPIO_PIN 0
#endif
/**
* @def SL_OPENTHREAD_HOST_CLEAR_PIN_TIMEOUT_MS
*
* Defines the timeout duration (in milliseconds) for clearing the host wakeup GPIO pin.
*
* This value specifies the amount of time the system will wait before clearing the host wakeup GPIO pin.
*
*/
#ifndef SL_OPENTHREAD_HOST_CLEAR_PIN_TIMEOUT_MS
#define SL_OPENTHREAD_HOST_CLEAR_PIN_TIMEOUT_MS 10
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
*
* Power Calibration (SPINEL) Module (Host and RCP configuration)
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
#endif // OPENTHREAD_CORE_EFR32_CONFIG_H_

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file defines the frequency band configuration structure for efr32.
*
*/
#ifndef PLATFORM_BAND_H_
#define PLATFORM_BAND_H_
#include <openthread/platform/radio.h>
#include "radio_counters.h"
#include "rail.h"
#include "rail_config.h"
#include "rail_ieee802154.h"
#include "sl_802154_radio_priority_config.h"
#define RAIL_TX_FIFO_SIZE (OT_RADIO_FRAME_MAX_SIZE + 1)
#define RADIO_SCHEDULER_CHANNEL_SLIP_TIME 500000UL
#define RADIO_TIMING_CSMA_OVERHEAD_US 500
#define RADIO_TIMING_DEFAULT_BYTETIME_US 32 // only used if RAIL_GetBitRate returns 0
#define RADIO_TIMING_DEFAULT_SYMBOLTIME_US 16 // only used if RAIL_GetSymbolRate returns 0
typedef struct efr32CommonConfig
{
RAIL_Config_t mRailConfig;
#if RADIO_CONFIG_DMP_SUPPORT
RAILSched_Config_t mRailSchedState;
#endif
union
{
// Used to align this buffer as needed
RAIL_FIFO_ALIGNMENT_TYPE align[RAIL_TX_FIFO_SIZE / RAIL_FIFO_ALIGNMENT];
uint8_t fifo[RAIL_TX_FIFO_SIZE]; // must be 2 power between 64 and 4096, and bigger than OT_RADIO_FRAME_MAX_SIZE
} mRailTxFifo;
} efr32CommonConfig;
typedef struct efr32BandConfig
{
const RAIL_ChannelConfig_t *mChannelConfig;
uint8_t mChannelMin;
uint8_t mChannelMax;
} efr32BandConfig;
#endif // PLATFORM_BAND_H_

View File

@@ -0,0 +1,194 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes the platform-specific initializers.
*
*/
#ifndef PLATFORM_EFR32_H_
#define PLATFORM_EFR32_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <openthread/instance.h>
#include "em_device.h"
#if defined(_SILICON_LABS_32B_SERIES_2)
#include "em_system.h"
#else
#include "sl_hal_system.h"
#endif
#include "rail.h"
#include "alarm.h"
#include "uart.h"
// Global OpenThread instance structure
extern otInstance *sInstance;
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#ifndef SL_CATALOG_KERNEL_PRESENT
#define sl_ot_rtos_task_can_access_pal() (true)
#else
#include "sl_ot_rtos_adaptation.h"
#endif
// Global reference to rail handle
#ifndef SL_CATALOG_RAIL_MULTIPLEXER_PRESENT
#define gRailHandle emPhyRailHandle // use gRailHandle in the OpenThread PAL.
#endif
extern RAIL_Handle_t gRailHandle; // coex needs the emPhyRailHandle symbol.
/**
* This function performs all platform-specific initialization of
* OpenThread's drivers.
*
*/
void sl_ot_sys_init(void);
/**
* This function initializes the radio service used by OpenThead.
*
*/
void efr32RadioInit(void);
/**
* This function deinitializes the radio service used by OpenThead.
*
*/
void efr32RadioDeinit(void);
/**
* This function performs radio driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void efr32RadioProcess(otInstance *aInstance);
/**
* This function performs CPC driver processing.
*
*/
void efr32CpcProcess(void);
/**
* This function performs SPI driver processing.
*
*/
void efr32SpiProcess(void);
/**
* Initialization of Misc module.
*
*/
void efr32MiscInit(void);
/**
* Initialization of ADC module for random number generator.
*
*/
void efr32RandomInit(void);
/**
* Initialization of Logger driver.
*
*/
void efr32LogInit(void);
/**
* Deinitialization of Logger driver.
*
*/
void efr32LogDeinit(void);
/**
* Print reset info.
*
*/
void efr32PrintResetInfo(void);
/**
* Set 802.15.4 CCA mode
*
* A call to this function should be made after RAIL has been
* initialized and a valid handle is available. On platforms that
* don't support different CCA modes, a call to this function with
* non-Default CCA mode (i.e. with any value except
* RAIL_IEEE802154_CCA_MODE_RSSI) will return a failure.
*
* @param[in] aMode Mode of CCA operation.
* @return RAIL Status code indicating success of the function call.
*/
RAIL_Status_t efr32RadioSetCcaMode(uint8_t aMode);
/**
* This callback is used to check if is safe to put the EFR32 into a
* low energy sleep mode.
*
* The callback should return true if it is ok to enter sleep mode.
* Note that the callback must add an EM1 requirement if it intends
* to idle (EM1) instead of entering a deep sleep (EM2) mode.
*/
bool efr32AllowSleepCallback(void);
/**
* Load the channel configurations.
*
* @param[in] aChannel The radio channel.
* @param[in] aTxPower The radio transmit power in dBm.
*
* @retval OT_ERROR_NONE Successfully enabled/disabled .
* @retval OT_ERROR_INVALID_ARGS Invalid channel.
*
*/
otError efr32RadioLoadChannelConfig(uint8_t aChannel, int8_t aTxPower);
otError railStatusToOtError(RAIL_Status_t status);
/**
* This function performs Serial processing.
*
*/
void efr32SerialProcess(void);
#ifdef __cplusplus
}
#endif
#endif // PLATFORM_EFR32_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,192 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for radio coex metrics
* collection.
*
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "radio_coex.h"
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
static sl_ot_coex_counter_t sl_coex_counter;
#define SL_INCREMENT_IF_NO_OVERFLOW(var, val, incr) \
do \
{ \
uint32_t temp = val + incr; \
otEXPECT_ACTION(temp >= var, sl_coex_counter.metrics.mStopped = true); \
var = temp; \
} while (0)
void sl_rail_util_coex_ot_events(sl_rail_util_coex_ot_event_t event)
{
bool isTxEvent = (event & SL_RAIL_UTIL_COEX_OT_TX_REQUEST);
sl_rail_util_coex_ot_event_t coexEvent =
(event & ~(SL_RAIL_UTIL_COEX_OT_TX_REQUEST | SL_RAIL_UTIL_COEX_OT_RX_REQUEST));
uint32_t *metrics = (isTxEvent) ? &sl_coex_counter.metrics.mNumTxRequest : &sl_coex_counter.metrics.mNumRxRequest;
uint64_t *totalReqToGrantDuration =
(isTxEvent) ? &sl_coex_counter.totalTxReqToGrantDuration : &sl_coex_counter.totalRxReqToGrantDuration;
/* clang-format off */
// uint32_t mNumGrantGlitch; ///< Not available.
// mNumTxRequest = mNumTxGrantImmediate + mNumTxGrantWait
// mNumTxGrantWait = mNumTxGrantWaitActivated + mNumTxGrantWaitTimeout
// Same applies for Rx counters.
/* Tx Events*/
// uint32_t mNumTxRequest; ///< Number of Tx Requested = mNumTxGrantImmediate + mNumTxGrantWait.
// uint32_t mNumTxGrantImmediate; ///< Not Available.
// uint32_t mNumTxGrantWait; ///< Number of tx requests while grant was inactive.
// uint32_t mNumTxGrantWaitActivated; ///< Number of tx requests while grant was inactive that were ultimately granted.
// uint32_t mNumTxGrantWaitTimeout; ///< Number of tx requests while grant was inactive that timed out.
// uint32_t mNumTxGrantDeactivatedDuringRequest; ///< Number of tx that were in progress when grant was deactivated.
// uint32_t mNumTxDelayedGrant; ///< Number of tx requests that were not granted within 50us.
// uint32_t mAvgTxRequestToGrantTime; ///< Average time in usec from tx request to grant.
/* Rx Events*/
// uint32_t mNumRxRequest; ///< Number of rx requests.
// uint32_t mNumRxGrantImmediate; ///< Number of rx requests while grant was active.
// uint32_t mNumRxGrantWait; ///< Number of rx requests while grant was inactive.
// uint32_t mNumRxGrantWaitActivated; ///< Number of rx requests while grant was inactive that were ultimately granted.
// uint32_t mNumRxGrantWaitTimeout; ///< Number of rx requests while grant was inactive that timed out.
// uint32_t mNumRxGrantDeactivatedDuringRequest; ///< Number of rx that were in progress when grant was deactivated.
// uint32_t mNumRxDelayedGrant; ///< Number of rx requests that were not granted within 50us.
// uint32_t mAvgRxRequestToGrantTime; ///< Average time in usec from rx request to grant.
// uint32_t mNumRxGrantNone; ///< Number of rx requests that completed without receiving grant.
// bool mStopped;
/* clang-format on */
otEXPECT(sl_coex_counter.metrics.mStopped == false);
switch (coexEvent)
{
case SL_RAIL_UTIL_COEX_OT_EVENT_GRANTED_IMMEDIATE:
{
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_GRANT_IMMEDIATE_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_IMMEDIATE_COUNT],
1);
}
break;
case SL_RAIL_UTIL_COEX_OT_EVENT_REQUESTED:
{
sl_coex_counter.timestamp = otPlatAlarmMicroGetNow();
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_REQUEST_COUNT],
metrics[SL_OT_COEX_EVENT_REQUEST_COUNT],
1);
}
break;
case SL_RAIL_UTIL_COEX_OT_EVENT_GRANTED:
{
uint32_t reqToGrantDuration = otPlatAlarmMicroGetNow() - sl_coex_counter.timestamp;
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_GRANT_WAIT_ACTIVATED_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_WAIT_ACTIVATED_COUNT],
1);
if (reqToGrantDuration > 50)
{
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_DELAYED_GRANT_COUNT],
metrics[SL_OT_COEX_EVENT_DELAYED_GRANT_COUNT],
1);
}
*totalReqToGrantDuration += reqToGrantDuration;
}
break;
case SL_RAIL_UTIL_COEX_OT_EVENT_DENIED:
{
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_GRANT_WAIT_TIMEOUT_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_WAIT_TIMEOUT_COUNT],
1);
}
break;
case SL_RAIL_UTIL_COEX_OT_EVENT_GRANT_ABORTED:
{
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_GRANT_DEACTIVATED_DURING_REQUEST_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_DEACTIVATED_DURING_REQUEST_COUNT],
1);
}
break;
default:
break;
}
SL_INCREMENT_IF_NO_OVERFLOW(metrics[SL_OT_COEX_EVENT_GRANT_WAIT_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_WAIT_TIMEOUT_COUNT],
metrics[SL_OT_COEX_EVENT_GRANT_WAIT_ACTIVATED_COUNT]);
metrics[SL_OT_COEX_EVENT_AVG_REQUEST_TO_GRANT_TIME] =
*totalReqToGrantDuration / metrics[SL_OT_COEX_EVENT_REQUEST_COUNT];
exit:
return;
}
otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS);
memcpy(aCoexMetrics, &sl_coex_counter.metrics, sizeof(otRadioCoexMetrics));
exit:
return error;
}
void sli_radio_coex_reset(void)
{
memset(&sl_coex_counter, 0, sizeof(sl_coex_counter));
}
#else
otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aCoexMetrics);
return OT_ERROR_NOT_IMPLEMENTED;
}
#endif // OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE

View File

@@ -0,0 +1,523 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for vendor additions to radio communication.
*
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "radio_extension.h"
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#ifndef SL_CATALOG_OT_SIMULATION_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
#include "coexistence-802154.h"
#include "coexistence.h"
#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
#include "sl_rail_util_ant_div.h"
#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT
#include "sl_rail_util_ieee802154_phy_select.h"
#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT
#ifdef SL_CATALOG_OPENTHREAD_TEST_CLI_PRESENT
#include "rail_ieee802154.h"
#endif // SL_CATALOG_OPENTHREAD_TEST_CLI_PRESENT
#else // SL_CATALOG_OT_SIMULATION_PRESENT
#include "rail_util_simulation.h"
#endif // SL_CATALOG_OT_SIMULATION_PRESENT
#include "common/code_utils.hpp"
#ifdef SL_CATALOG_OPENTHREAD_ANT_DIV_PRESENT
otError otPlatRadioExtensionGetTxAntennaMode(uint8_t *aMode)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
VerifyOrExit(aMode != NULL, error = OT_ERROR_INVALID_ARGS);
*aMode = (uint8_t)sl_rail_util_ant_div_get_tx_antenna_mode();
#else
OT_UNUSED_VARIABLE(aMode);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetTxAntennaMode(uint8_t aMode)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
sl_status_t status = sl_rail_util_ant_div_set_tx_antenna_mode(aMode);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aMode);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetRxAntennaMode(uint8_t *aMode)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
VerifyOrExit(aMode != NULL, error = OT_ERROR_INVALID_ARGS);
*aMode = (uint8_t)sl_rail_util_ant_div_get_rx_antenna_mode();
#else
OT_UNUSED_VARIABLE(aMode);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetRxAntennaMode(uint8_t aMode)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
sl_status_t status = sl_rail_util_ant_div_set_rx_antenna_mode(aMode);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aMode);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetActivePhy(uint8_t *aActivePhy)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
VerifyOrExit(aActivePhy != NULL, error = OT_ERROR_INVALID_ARGS);
*aActivePhy = (uint8_t)sl_rail_util_ieee802154_get_active_radio_config();
#else
OT_UNUSED_VARIABLE(aActivePhy);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
#endif // SL_CATALOG_OPENTHREAD_ANT_DIV_PRESENT
#ifdef SL_CATALOG_OPENTHREAD_COEX_PRESENT
otError otPlatRadioExtensionGetDpState(uint8_t *aDpPulse)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aDpPulse != NULL, error = OT_ERROR_INVALID_ARGS);
*aDpPulse = (uint8_t)sl_rail_util_coex_get_directional_priority_pulse_width();
#else
OT_UNUSED_VARIABLE(aDpPulse);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetDpState(uint8_t aDpPulse)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_directional_priority_pulse_width(aDpPulse);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aDpPulse);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetGpioInputOverride(uint8_t aGpioIndex, bool *aEnabled)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit((COEX_GpioIndex_t)aGpioIndex < COEX_GPIO_INDEX_COUNT, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aEnabled != NULL, error = OT_ERROR_INVALID_ARGS);
*aEnabled = sl_rail_util_coex_get_gpio_input_override(aGpioIndex);
#else
OT_UNUSED_VARIABLE(aGpioIndex);
OT_UNUSED_VARIABLE(aEnabled);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetGpioInputOverride(uint8_t aGpioIndex, bool aEnabled)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status;
VerifyOrExit((COEX_GpioIndex_t)aGpioIndex < COEX_GPIO_INDEX_COUNT, error = OT_ERROR_INVALID_ARGS);
status = sl_rail_util_coex_set_gpio_input_override((COEX_GpioIndex_t)aGpioIndex, aEnabled);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aGpioIndex);
OT_UNUSED_VARIABLE(aEnabled);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetActiveRadio(uint8_t *aActivePhy)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aActivePhy != NULL, error = OT_ERROR_INVALID_ARGS);
*aActivePhy = (uint8_t)sl_rail_util_ieee802154_get_active_radio_config();
#else
OT_UNUSED_VARIABLE(aActivePhy);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetPhySelectTimeout(uint8_t *aTimeout)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aTimeout != NULL, error = OT_ERROR_INVALID_ARGS);
*aTimeout = sl_rail_util_coex_get_phy_select_timeout();
#else
OT_UNUSED_VARIABLE(aTimeout);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetPhySelectTimeout(uint8_t aTimeout)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_phy_select_timeout(aTimeout);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aTimeout);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetCoexOptions(uint32_t *aPtaOptions)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aPtaOptions != NULL, error = OT_ERROR_INVALID_ARGS);
*aPtaOptions = (uint32_t)sl_rail_util_coex_get_options();
#else
OT_UNUSED_VARIABLE(aPtaOptions);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetCoexOptions(uint32_t aPtaOptions)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_options(aPtaOptions);
VerifyOrExit(status != SL_STATUS_INVALID_PARAMETER, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aPtaOptions);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetCoexConstantOptions(uint32_t *aPtaOptions)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aPtaOptions != NULL, error = OT_ERROR_INVALID_ARGS);
*aPtaOptions = (uint32_t)sl_rail_util_coex_get_constant_options();
#else
OT_UNUSED_VARIABLE(aPtaOptions);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionIsCoexEnabled(bool *aPtaState)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
VerifyOrExit(aPtaState != NULL, error = OT_ERROR_INVALID_ARGS);
*aPtaState = sl_rail_util_coex_is_enabled();
#else
OT_UNUSED_VARIABLE(aPtaState);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetCoexEnable(bool aPtaState)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_enable(aPtaState);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aPtaState);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionGetRequestPwmArgs(uint8_t *aPwmReq, uint8_t *aPwmDutyCycle, uint8_t *aPwmPeriodHalfMs)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
const sl_rail_util_coex_pwm_args_t *p;
VerifyOrExit(aPwmReq != NULL, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aPwmDutyCycle != NULL, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aPwmPeriodHalfMs != NULL, error = OT_ERROR_INVALID_ARGS);
p = sl_rail_util_coex_get_request_pwm_args();
VerifyOrExit(p != NULL, error = OT_ERROR_FAILED);
*aPwmReq = p->req;
*aPwmDutyCycle = p->dutyCycle;
*aPwmPeriodHalfMs = p->periodHalfMs;
#else
OT_UNUSED_VARIABLE(aPwmReq);
OT_UNUSED_VARIABLE(aPwmDutyCycle);
OT_UNUSED_VARIABLE(aPwmPeriodHalfMs);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetRequestPwmArgs(uint8_t aPwmReq, uint8_t aPwmDutyCycle, uint8_t aPwmPeriodHalfMs)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_request_pwm(aPwmReq, NULL, aPwmDutyCycle, aPwmPeriodHalfMs);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aPwmReq);
OT_UNUSED_VARIABLE(aPwmDutyCycle);
OT_UNUSED_VARIABLE(aPwmPeriodHalfMs);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT) && SL_OPENTHREAD_COEX_COUNTER_ENABLE
extern uint32_t efr32RadioCoexCounters[SL_RAIL_UTIL_COEX_EVENT_COUNT];
extern void efr32RadioClearCoexCounters(void);
#endif
otError otPlatRadioExtensionClearCoexCounters(void)
{
otError error = OT_ERROR_NONE;
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT) && SL_OPENTHREAD_COEX_COUNTER_ENABLE
efr32RadioClearCoexCounters();
#else
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
return error;
}
otError otPlatRadioExtensionGetCoexCounters(uint8_t aNumEntries, uint32_t aCoexCounters[])
{
otError error = OT_ERROR_NONE;
#if defined(SL_CATALOG_RAIL_UTIL_COEX_PRESENT) && SL_OPENTHREAD_COEX_COUNTER_ENABLE
VerifyOrExit(aNumEntries == OT_PLAT_RADIO_EXTENSION_COEX_EVENT_COUNT, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(aCoexCounters != NULL, error = OT_ERROR_INVALID_ARGS);
_Static_assert((uint8_t)OT_PLAT_RADIO_EXTENSION_COEX_EVENT_COUNT == (uint8_t)SL_RAIL_UTIL_COEX_EVENT_COUNT,
"Coex counter mismatch. OT_PLAT_RADIO_EXTENSION_COEX_EVENT_COUNT != SL_RAIL_UTIL_COEX_EVENT_COUNT");
#define COPY_COEX_COUNTER(counter) \
aCoexCounters[OT_PLAT_RADIO_EXTENSION_COEX_EVENT_##counter] = \
efr32RadioCoexCounters[SL_RAIL_UTIL_COEX_EVENT_##counter]
COPY_COEX_COUNTER(LO_PRI_REQUESTED);
COPY_COEX_COUNTER(HI_PRI_REQUESTED);
COPY_COEX_COUNTER(LO_PRI_DENIED);
COPY_COEX_COUNTER(HI_PRI_DENIED);
COPY_COEX_COUNTER(LO_PRI_TX_ABORTED);
COPY_COEX_COUNTER(HI_PRI_TX_ABORTED);
#else
OT_UNUSED_VARIABLE(aNumEntries);
OT_UNUSED_VARIABLE(aCoexCounters);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionSetRadioHoldoff(bool aEnabled)
{
otError error = OT_ERROR_NONE;
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
sl_status_t status = sl_rail_util_coex_set_radio_holdoff(aEnabled);
VerifyOrExit(status == SL_STATUS_OK, error = OT_ERROR_FAILED);
#else
OT_UNUSED_VARIABLE(aEnabled);
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
#endif // SL_CATALOG_OPENTHREAD_COEX_PRESENT
#ifdef SL_CATALOG_OPENTHREAD_TEST_CLI_PRESENT
extern RAIL_IEEE802154_PtiRadioConfig_t efr32GetPtiRadioConfig(void);
extern RAIL_Status_t efr32RadioSetCcaMode(uint8_t aMode);
otError otPlatRadioExtensionGetPtiRadioConfig(uint16_t *radioConfig)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(radioConfig != NULL, error = OT_ERROR_INVALID_ARGS);
*radioConfig = (uint16_t)efr32GetPtiRadioConfig();
exit:
return error;
}
otError otPlatRadioExtensionSetCcaMode(uint8_t aMode)
{
otError error = OT_ERROR_NONE;
RAIL_Status_t status = efr32RadioSetCcaMode(aMode);
VerifyOrExit(status != RAIL_STATUS_INVALID_PARAMETER, error = OT_ERROR_INVALID_ARGS);
VerifyOrExit(status == RAIL_STATUS_NO_ERROR, error = OT_ERROR_FAILED);
exit:
return error;
}
#endif // SL_CATALOG_OPENTHREAD_TEST_CLI_PRESENT
#ifdef SL_CATALOG_OPENTHREAD_EFR32_EXT_PRESENT
extern otError efr32GetRadioCounters(efr32RadioCounters *aRadioCounters);
extern otError efr32ClearRadioCounters(void);
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
extern efr32RadioCounters railDebugCounters;
#endif
otError otPlatRadioExtensionGetRadioCounters(efr32RadioCounters *aRadioCounters)
{
otError error = OT_ERROR_NONE;
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
VerifyOrExit(aRadioCounters != NULL, error = OT_ERROR_INVALID_ARGS);
*aRadioCounters = railDebugCounters;
#else
ExitNow(error = OT_ERROR_NOT_IMPLEMENTED);
#endif
exit:
return error;
}
otError otPlatRadioExtensionClearRadioCounters(void)
{
otError error = OT_ERROR_NONE;
#if RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT
efr32ClearRadioCounters();
#else
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
return error;
}
#endif // SL_CATALOG_OPENTHREAD_EFR32_EXT_PRESENT

View File

@@ -0,0 +1,290 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for radio communication.
*
*/
#include <openthread-core-config.h>
#include "pa_conversions_efr32.h"
#include "platform-band.h"
#include "platform-efr32.h"
#include "radio_multi_channel.h"
#include "radio_power_manager.h"
#include "rail_config.h"
#include "rail_ieee802154.h"
#include "sl_multipan.h"
#ifdef SL_CATALOG_RAIL_MULTIPLEXER_PRESENT
#include "sl_rail_mux_rename.h"
#endif // SL_CATALOG_RAIL_MULTIPLEXER_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_PRESENT
#include "sl_rail_util_ieee802154_fast_channel_switching_config.h"
#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_PRESENT
#if !OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
static int8_t sli_max_channel_power[RADIO_INTERFACE_COUNT][SL_MAX_CHANNELS_SUPPORTED];
static int8_t sli_default_tx_power[RADIO_INTERFACE_COUNT];
/**
* This function gets the lowest value for the max_tx_power for a channel, from the max_tx_powerTable set
* across all interfaces. It also gets the highest default_tx_power set across all interfaces.
*
* @param[out] default_tx_power A pointer to update the derived default_tx_power across all IIDs.
* @param[out] tx_power_from_table A pointer to update the Tx Power derived from the MaxChannelPowerTable.
* @param[in] channel Channel of interest
*
*/
static void sli_get_default_and_max_powers_across_iids(int8_t *default_tx_power,
int8_t *tx_power_from_table,
uint16_t channel)
{
OT_ASSERT(tx_power_from_table != NULL);
OT_ASSERT(default_tx_power != NULL);
for (uint8_t iid = 0U; iid < RADIO_INTERFACE_COUNT; iid++)
{
// Obtain the minimum Tx power set by different iids, for `channel`
// If there is an interface using lower Tx power than the one we have
// in tx_power_from_table..
// Update tx_power_from_table.
*tx_power_from_table = SL_MIN(*tx_power_from_table, sli_max_channel_power[iid][channel - SL_CHANNEL_MIN]);
// If the default Tx Power set is not invalid..
if (sli_default_tx_power[iid] != SL_INVALID_TX_POWER)
{
// Obtain the Max value between local default_tx_power and sli_default_tx_power.
// If selected default Tx Power is Invalid, initialise it to sli_default_tx_power.
// We have already validated that sli_default_tx_power holds a valid value.
*default_tx_power = (*default_tx_power == SL_INVALID_TX_POWER)
? sli_default_tx_power[iid]
: SL_MAX(*default_tx_power, sli_default_tx_power[iid]);
}
}
}
/**
* This function returns the tx power to be used based on the default and max tx power table, for a given channel.
*
* @param[in] channel Channel of interest
*
* @returns The radio Tx Power for the given channel, in dBm.
*
*/
static int8_t sli_get_max_tx_power_across_iids(uint16_t channel)
{
int8_t max_channel_tx_power = SL_INVALID_TX_POWER;
int8_t max_default_tx_power = SL_INVALID_TX_POWER;
int8_t selected_tx_power = SL_INVALID_TX_POWER;
#if FAST_CHANNEL_SWITCHING_SUPPORT && OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
if (sl_is_multi_channel_enabled())
{
RAIL_IEEE802154_RxChannelSwitchingCfg_t channel_switching_cfg;
// Get switching config
sl_get_channel_switching_cfg(&channel_switching_cfg);
// Find the max_channel_tx_power, to be minimum of Max channel power for the
// channels infast channel config, accross all iids. This is because, if a iid_1
// sets the max tx power of the channel to be less than the max tx power set by
// iid_2, we will need to work with the lower tx power to be compliant on both
// interfaces.
// Find the max_default_tx_power, to be maximum of the default Tx power accross all
// the interfaces.
for (uint8_t i = 0U; i < RAIL_IEEE802154_RX_CHANNEL_SWITCHING_NUM_CHANNELS; i++)
{
channel = channel_switching_cfg.channels[i];
sli_get_default_and_max_powers_across_iids(&max_default_tx_power, &max_channel_tx_power, channel);
}
}
else
#endif
{
sli_get_default_and_max_powers_across_iids(&max_default_tx_power, &max_channel_tx_power, channel);
}
// Return the minimum of max_channel_tx_power and max_default_tx_power.
selected_tx_power = SL_MIN(max_channel_tx_power, max_default_tx_power);
return (selected_tx_power == SL_INVALID_TX_POWER) ? OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER : selected_tx_power;
}
#endif //! OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
void sli_set_tx_power_in_rail(int8_t power_in_dbm)
{
RAIL_Status_t status;
// RAIL_SetTxPowerDbm() takes power in units of deci-dBm (0.1dBm)
// Multiply by 10 because power_in_dbm is supposed be in units dBm
status = RAIL_SetTxPowerDbm(gRailHandle, ((RAIL_TxPower_t)power_in_dbm) * 10);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}
void sli_init_power_manager(void)
{
#if !OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
memset(sli_max_channel_power, SL_INVALID_TX_POWER, sizeof(sli_max_channel_power));
memset(sli_default_tx_power, SL_INVALID_TX_POWER, sizeof(sli_default_tx_power));
#endif //! OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
}
void sli_update_tx_power_after_config_update(const RAIL_TxPowerConfig_t *tx_pwr_config, int8_t tx_power)
{
RAIL_Status_t status;
RAIL_TxPowerLevel_t tx_power_lvl;
RAIL_TxPower_t tx_power_dbm = tx_power * 10;
tx_power_lvl = RAIL_GetTxPower(gRailHandle);
// Always need to call RAIL_SetTxPowerDbm after RAIL_ConfigTxPower
// First need to get existing power setting and reassert value after config
if (tx_power_lvl != RAIL_TX_POWER_LEVEL_INVALID)
{
tx_power_dbm = RAIL_GetTxPowerDbm(gRailHandle);
}
status = RAIL_ConfigTxPower(gRailHandle, tx_pwr_config);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
status = RAIL_SetTxPowerDbm(gRailHandle, tx_power_dbm);
OT_ASSERT(status == RAIL_STATUS_NO_ERROR);
}
otError sli_set_channel_max_tx_power(otInstance *instance, uint8_t channel, int8_t max_power)
{
otError error = OT_ERROR_NONE;
#if !OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
int8_t tx_power;
uint8_t iid = efr32GetIidFromInstance(instance);
otEXPECT_ACTION(channel >= SL_CHANNEL_MIN && channel <= SL_CHANNEL_MAX, error = OT_ERROR_INVALID_ARGS);
sli_max_channel_power[iid][channel - SL_CHANNEL_MIN] = max_power;
tx_power = sl_get_tx_power_for_current_channel(instance);
sli_set_tx_power_in_rail(tx_power);
exit:
#else
OT_UNUSED_VARIABLE(instance);
OT_UNUSED_VARIABLE(channel);
OT_UNUSED_VARIABLE(max_power);
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
return error;
}
otError sli_set_default_tx_power(otInstance *instance, int8_t tx_power)
{
otError error = OT_ERROR_NONE;
#if !OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
int8_t max_tx_power;
uint8_t iid = efr32GetIidFromInstance(instance);
sli_default_tx_power[iid] = tx_power;
max_tx_power = sl_get_tx_power_for_current_channel(instance);
sli_set_tx_power_in_rail(max_tx_power);
#else
OT_UNUSED_VARIABLE(instance);
OT_UNUSED_VARIABLE(tx_power);
error = OT_ERROR_NOT_IMPLEMENTED;
#endif
return error;
}
int8_t sl_get_tx_power_for_current_channel(otInstance *instance)
{
int8_t tx_power;
uint16_t channel;
RAIL_GetChannel(gRailHandle, &channel);
#if OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
uint8_t raw_power_calibration[SL_OPENTHREAD_RAW_POWER_CALIBRATION_LENGTH];
uint8_t fem_setting[SL_OPENTHREAD_FEM_SETTING_LENGTH];
uint16_t raw_calibration_length = SL_OPENTHREAD_RAW_POWER_CALIBRATION_LENGTH;
uint16_t fem_setting_length = SL_OPENTHREAD_FEM_SETTING_LENGTH;
otError error;
error = otPlatRadioGetRawPowerSetting(instance, channel, raw_power_calibration, &raw_calibration_length);
error = sl_parse_raw_power_calibration_cb(raw_power_calibration,
raw_calibration_length,
&tx_power,
fem_setting,
&fem_setting_length);
OT_ASSERT(error == OT_ERROR_NONE);
sl_configure_fem_cb(fem_setting, fem_setting_length);
#else
OT_UNUSED_VARIABLE(instance);
tx_power = sli_get_max_tx_power_across_iids(channel);
#endif
return tx_power;
}
#if OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE
SL_WEAK otError sl_parse_raw_power_calibration_cb(uint8_t *raw_power_calibration,
uint16_t raw_setting_length,
int8_t *radio_power,
uint8_t *fem_setting,
uint16_t *fem_setting_length)
{
OT_ASSERT(raw_power_calibration != NULL);
OT_ASSERT(radio_power != NULL);
OT_UNUSED_VARIABLE(raw_setting_length);
OT_UNUSED_VARIABLE(fem_setting);
OT_UNUSED_VARIABLE(fem_setting_length);
*radio_power = raw_power_calibration[0];
return OT_ERROR_NONE;
}
SL_WEAK void sl_configure_fem_cb(uint8_t *fem_setting, uint16_t fem_setting_length)
{
OT_UNUSED_VARIABLE(fem_setting);
OT_UNUSED_VARIABLE(fem_setting_length);
}
#endif // OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RAIL_CONFIG_H__
#define __RAIL_CONFIG_H__
#include "board_config.h"
#include "rail_types.h"
#include <stdint.h>
#if RADIO_CONFIG_SUBGHZ_SUPPORT
extern const RAIL_ChannelConfig_t *channelConfigs[];
#endif
#endif // __RAIL_CONFIG_H__

View File

@@ -0,0 +1,339 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*******************************************************************************
* @file
* @brief This file implements Green Power interface.
******************************************************************************/
#include "sl_gp_interface.h"
#include "ieee802154mac.h"
#include "rail_ieee802154.h"
#include "sl_gp_interface_config.h"
#include "sl_packet_utils.h"
#include "sl_status.h"
#include <assert.h>
#include <string.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/time.h>
#include "common/debug.hpp"
#include "common/logging.hpp"
#include "utils/code_utils.h"
#include "utils/mac_frame.h"
// This implements mechanism to buffer outgoing Channel Configuration (0xF3) and
// Commissioning Reply (0xF0) GPDF commands on the RCP to sent out on request
// from GPD with bidirectional capability with in a certain time window, i.e.
// between 20 and 25 msec.
// The mechanism works following way -
// The zigbeed submits the outgoing GPDF command, this code on rcp intercepts the
// packet from transmit API and buffers the packet, does not send it out.
// The GPD sends request indicating its RX capability, this again intercept the
// rx message and based on the request, it sends out the above buffered message
// with in a time window of 20-25 msec from the time it received the message.
#define GP_MIN_MAINTENANCE_FRAME_LENGTH 10
#define GP_MIN_DATA_FRAME_LENGTH 14
#define GP_ADDRESSING_MODE_SRC_ID 0
#define GP_ADDRESSING_MODE_EUI64 2
// Check the GP Frame Type field to ensure it is either a maintenance frame (1) or a data frame (0).
#define GP_NWK_PROTOCOL_VERSION_CHECK(nwkFc) ((((nwkFc >> 2) & 0x0F) == 3) && ((nwkFc & 0x3) <= 1))
#define GP_NWK_FRAME_TYPE_MAINTENANCE_WITHOUT_EXTD_FC(nwkFc) ((nwkFc & 0xC3) == 0x01)
#define GP_NWK_FRAME_TYPE_DATA_WITH_EXTD_FC(nwkFc) ((nwkFc & 0xC3) == 0x80)
#define GP_NWK_UNSECURED_RX_DATA_FRAME(nwkExntdFc) ((nwkExntdFc & 0xF8) == 0x40)
#define GP_NWK_UNSECURED_TX_DATA_FRAME(nwkExntdFc) ((nwkExntdFc & 0xF8) == 0x80)
#define GP_NWK_ADDRESSING_APP_ID(nwkExntdFc) ((nwkExntdFc & 0x07))
#define GP_CHANNEL_REQUEST_CMD_ID 0xE3
#define GP_CHANNEL_CONFIGURATION_CMD_ID 0xF3
#define GP_COMMISSIONINGING_CMD_ID 0xE0
#define GP_COMMISSIONING_REPLY_CMD_ID 0xF0
#define GP_EXND_FC_INDEX 1
#define GP_COMMAND_INDEX_FOR_MAINT_FRAME 1
#define GP_SRC_ID_INDEX_WITH_APP_MODE_0 2
#define GP_APP_EP_INDEX_WITH_APP_MODE_1 2
#define GP_COMMAND_INDEX_WITH_APP_MODE_1 3
#define GP_COMMAND_INDEX_WITH_APP_MODE_0 6
#define BUFFERED_PSDU_GP_SRC_ID_INDEX_WITH_APP_MODE_0 9
#define BUFFERED_PSDU_GP_APP_EP_INDEX_WITH_APP_MODE_1 15
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
static volatile sl_gp_state_t gp_state = SL_GP_STATE_INIT;
static volatile uint64_t gpStateTimeOut;
// Needed to retrieve buffered transmit frame present in global memory.
static otInstance *sBufferedTxInstance = NULL;
sl_gp_state_t sl_gp_intf_get_state(void)
{
return gp_state;
}
void efr32GpProcess(void)
{
switch (gp_state)
{
case SL_GP_STATE_INIT:
{
gp_state = SL_GP_STATE_IDLE;
otLogDebgPlat("GP RCP INTF: GP Frame init!!");
}
break;
case SL_GP_STATE_SEND_RESPONSE:
{
if (otPlatTimeGet() >= gpStateTimeOut)
{
OT_ASSERT(sBufferedTxInstance != NULL);
// Get the tx frame and send it without csma.
otRadioFrame *aTxFrame = otPlatRadioGetTransmitBuffer(sBufferedTxInstance);
aTxFrame->mInfo.mTxInfo.mCsmaCaEnabled = false;
aTxFrame->mInfo.mTxInfo.mMaxCsmaBackoffs = 0;
// On successful transmit, this will call the transmit complete callback for the GP packet,
// and go up to the CGP Send Handler and eventually the green power client.
otPlatRadioTransmit(sBufferedTxInstance, aTxFrame);
gp_state = SL_GP_STATE_IDLE;
sBufferedTxInstance = NULL;
otLogDebgPlat("GP RCP INTF: Sending Response!!");
}
}
break;
case SL_GP_STATE_WAITING_FOR_PKT:
{
if (otPlatTimeGet() >= gpStateTimeOut)
{
OT_ASSERT(sBufferedTxInstance != NULL);
// This is a timeout call for the case when the GPD did not poll the response with in 5 seconds.
otPlatRadioTxDone(sBufferedTxInstance,
otPlatRadioGetTransmitBuffer(sBufferedTxInstance),
NULL,
OT_ERROR_ABORT);
gp_state = SL_GP_STATE_IDLE;
sBufferedTxInstance = NULL;
}
}
break;
default:
{
// For all other states don't do anything
}
break;
}
}
void sl_gp_intf_buffer_pkt(otInstance *aInstance)
{
gpStateTimeOut = otPlatTimeGet() + GP_TX_MAX_TIMEOUT_IN_MICRO_SECONDS;
gp_state = SL_GP_STATE_WAITING_FOR_PKT;
OT_ASSERT(aInstance != NULL);
sBufferedTxInstance = aInstance;
otLogDebgPlat("GP RCP INTF: buffered!!");
}
bool sl_gp_intf_should_buffer_pkt(otInstance *aInstance, otRadioFrame *aFrame, bool isRxFrame)
{
bool shouldBufferPacket = false;
#if OPENTHREAD_CONFIG_DIAG_ENABLE
// Exit immediately if diag mode is enabled.
otEXPECT_ACTION(!otPlatDiagModeGet(), shouldBufferPacket = false);
#endif
uint8_t *gpFrameStartIndex = efr32GetPayload(aFrame);
otEXPECT_ACTION(gpFrameStartIndex != NULL, shouldBufferPacket = false);
// A Typical MAC Frame with GP NWK Frame in it
/* clang-format off */
// MAC Frame : [<---------------MAC Header------------->||<------------------------------------NWK Frame----------------------------------->]
// FC(2) | Seq(1) | DstPan(2) | DstAddr(2) || FC(1) | ExtFC(0/1) | SrcId(0/4) | SecFc(0/4) | MIC(0/4) | <------GPDF(1/n)------>
// The Green Power NWK FC and Ext FC are described as :
// FC : ExtFC Present(b7)=1| AC(b6)=0| Protocol Ver(b5-b2)=3 GP frames| Frame Type(b1-b0) = 0
// ExtFC : rxAfteTX (b6) = 1 | AppId(b2-b0) = 0
/* clang-format on */
uint8_t fc = *gpFrameStartIndex;
otLogDebgPlat("GP RCP INTF : (%s) PL Index = %d Channel = %d Length = %d FC = %0X",
isRxFrame ? "Rx" : "Tx",
(gpFrameStartIndex - aFrame->mPsdu),
aFrame->mChannel,
aFrame->mLength,
fc);
// Check if packet is a GP packet
otEXPECT_ACTION(sl_gp_intf_is_gp_pkt(aFrame), shouldBufferPacket = false);
otLogDebgPlat("GP RCP INTF : (%s) Length and Version Matched", isRxFrame ? "Rx" : "Tx");
// For GP Maintenance Frame type without extended FC, the FC is exactly same for both RX and TX directions with
// auto commissioning bit = 0, does not have a ExtFC field, only the command Id (which is the next byte in
// frame) indicates the direction.
if (GP_NWK_FRAME_TYPE_MAINTENANCE_WITHOUT_EXTD_FC(fc))
{
otLogDebgPlat("GP RCP INTF : (%s) Maintenance Frame match", isRxFrame ? "Rx" : "Tx");
uint8_t cmdId = *(gpFrameStartIndex + GP_COMMAND_INDEX_FOR_MAINT_FRAME);
if (cmdId == GP_CHANNEL_REQUEST_CMD_ID && isRxFrame && gp_state == SL_GP_STATE_WAITING_FOR_PKT)
{
// Send out the buffered frame
gp_state = SL_GP_STATE_SEND_RESPONSE;
gpStateTimeOut = aFrame->mInfo.mRxInfo.mTimestamp + GP_RX_OFFSET_IN_MICRO_SECONDS;
otLogDebgPlat("GP RCP INTF : (%s) Received GP_CHANNEL_REQUEST_CMD_ID - Send the Channel configuration",
isRxFrame ? "Rx" : "Tx");
}
else if (cmdId == GP_CHANNEL_CONFIGURATION_CMD_ID && !isRxFrame)
{
// Buffer the frame
shouldBufferPacket = true;
otLogDebgPlat("GP RCP INTF : (%s) Buffer GP_CHANNEL_CONFIGURATION_CMD_ID command", isRxFrame ? "Rx" : "Tx");
}
}
else if (
// Data frame with EXT FC present, extract the App Id, SrcId, direction and command Id
GP_NWK_FRAME_TYPE_DATA_WITH_EXTD_FC(fc) &&
// Minimum Data frame length with extended header and address
aFrame->mLength >= GP_MIN_DATA_FRAME_LENGTH)
{
uint8_t extFc = *(gpFrameStartIndex + GP_EXND_FC_INDEX);
// Process only unsecured commissioning frames for Tx/Rx with correct direction and RxAfterTx fields
// A.3.9.1, step 12: the proxies (also in combos) receiving a Commissioning GPDF (0xE3), Application Description
// GPDF (0xE4), any other GPD command from the GPD CommandID range 0xE5 0xEF, any GPD command from the GPD
// CommandID range 0xB0 0xBF
if ((!isRxFrame && GP_NWK_UNSECURED_TX_DATA_FRAME(extFc))
|| (isRxFrame && GP_NWK_UNSECURED_RX_DATA_FRAME(extFc)))
{
if (GP_NWK_ADDRESSING_APP_ID(extFc) == GP_ADDRESSING_MODE_SRC_ID)
{
uint8_t cmdId = *(gpFrameStartIndex + GP_COMMAND_INDEX_WITH_APP_MODE_0);
if (cmdId == GP_COMMISSIONING_REPLY_CMD_ID && !isRxFrame)
{
// Buffer the frame
shouldBufferPacket = true;
}
else if ((cmdId == GP_COMMISSIONINGING_CMD_ID || (0xE4 <= cmdId && cmdId <= 0xEF)
|| (0xB0 <= cmdId && cmdId <= 0xBF))
&& isRxFrame && gp_state == SL_GP_STATE_WAITING_FOR_PKT)
{
otRadioFrame *aTxFrame = otPlatRadioGetTransmitBuffer(aInstance);
// Match the gpd src Id ?
if (!memcmp((const void *)(gpFrameStartIndex + GP_SRC_ID_INDEX_WITH_APP_MODE_0),
(const void *)((aTxFrame->mPsdu) + BUFFERED_PSDU_GP_SRC_ID_INDEX_WITH_APP_MODE_0),
sizeof(uint32_t)))
{
// Send out the buffered frame
gp_state = SL_GP_STATE_SEND_RESPONSE;
gpStateTimeOut = aFrame->mInfo.mRxInfo.mTimestamp + GP_RX_OFFSET_IN_MICRO_SECONDS;
}
}
}
else if (GP_NWK_ADDRESSING_APP_ID(extFc) == GP_ADDRESSING_MODE_EUI64)
{
uint8_t cmdId = *(gpFrameStartIndex + GP_COMMAND_INDEX_WITH_APP_MODE_1);
if (cmdId == GP_COMMISSIONING_REPLY_CMD_ID && !isRxFrame)
{
// Buffer the frame
shouldBufferPacket = true;
}
else if ((cmdId == GP_COMMISSIONINGING_CMD_ID || (0xE4 <= cmdId && cmdId <= 0xEF)
|| (0xB0 <= cmdId && cmdId <= 0xBF))
&& isRxFrame && gp_state == SL_GP_STATE_WAITING_FOR_PKT)
{
otRadioFrame *aTxFrame = otPlatRadioGetTransmitBuffer(aInstance);
// Check the eui64 and app endpoint to send out the buffer packet.
otMacAddress aSrcAddress;
otMacAddress aDstAddress;
otMacFrameGetDstAddr(aTxFrame, &aDstAddress);
otMacFrameGetSrcAddr(aFrame, &aSrcAddress);
if (!memcmp(&(aDstAddress.mAddress.mExtAddress),
&(aSrcAddress.mAddress.mExtAddress),
sizeof(otExtAddress))
&& (gpFrameStartIndex[GP_APP_EP_INDEX_WITH_APP_MODE_1]
== (aTxFrame->mPsdu)[BUFFERED_PSDU_GP_APP_EP_INDEX_WITH_APP_MODE_1]))
{
gp_state = SL_GP_STATE_SEND_RESPONSE;
gpStateTimeOut = aFrame->mInfo.mRxInfo.mTimestamp + GP_RX_OFFSET_IN_MICRO_SECONDS;
}
}
}
}
}
if (shouldBufferPacket)
{
otLogDebgPlat("GP RCP INTF: GP filter passed!!");
}
exit:
return shouldBufferPacket;
}
#endif // OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
bool sl_gp_intf_is_gp_pkt(otRadioFrame *aFrame)
{
/* clang-format off */
// A Typical MAC Frame with GP NWK Frame in it
// MAC Frame : [<---------------MAC Header------------->||<------------------------------------NWK Frame----------------------------------->]
// FC(2) | Seq(1) | DstPan(2) | DstAddr(2) || FC(1) | ExtFC(0/1) | SrcId(0/4) | SecFc(0/4) | MIC(0/4) | <------GPDF(1/n)------>
/* clang-format on */
bool isGpPkt = false;
uint8_t *gpFrameStartIndex = efr32GetPayload(aFrame);
otEXPECT_ACTION(gpFrameStartIndex != NULL, isGpPkt = false);
uint8_t fc = *gpFrameStartIndex;
// Criteria:
// - The basic Identification of a GPDF Frame : The minimum GPDF length need to be 10 in this case for any
// direction
// - Network layer FC containing the Protocol Version field as 3.
// - The frame version should be 2003.
bool lengthCheck = (aFrame->mLength >= GP_MIN_MAINTENANCE_FRAME_LENGTH);
bool networkVersionCheck = GP_NWK_PROTOCOL_VERSION_CHECK(fc);
bool frameVersionCheck = (efr32GetFrameVersion(aFrame) == IEEE802154_FRAME_VERSION_2003);
isGpPkt = (lengthCheck && networkVersionCheck && frameVersionCheck);
#if 0 // Debugging
if (!isGpPkt)
{
otLogCritPlat("GP RCP INTF checks: Length = %d, NWK Version = %d, PanId Compression = %d, Frame Version = %d",
lengthCheck,
networkVersionCheck,
panIdCompressionCheck,
frameVersionCheck);
}
#endif
exit:
return isGpPkt;
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*******************************************************************************
* @file
* @brief This file implements Green Power interface.
******************************************************************************/
#ifndef SL_GP_INTERFACE_H_
#define SL_GP_INTERFACE_H_
#include <stdbool.h>
#include <openthread/platform/radio.h>
// GP state-machine states
typedef enum
{
SL_GP_STATE_INIT,
SL_GP_STATE_IDLE,
SL_GP_STATE_WAITING_FOR_PKT,
SL_GP_STATE_SEND_RESPONSE,
SL_GP_STATE_MAX
} sl_gp_state_t;
/**
* This function returns current state of GP state machine.
*
* @retval Status of GP state machine.
*/
sl_gp_state_t sl_gp_intf_get_state(void);
/**
* This function performs GP RCP processing.
*
*/
void efr32GpProcess(void);
/**
* This function stores the provided packet in global memory, to be sent as
* a response for specific incoming packet.
*
* @param[in] aInstance A pointer to the OpenThread instance structure.
*/
void sl_gp_intf_buffer_pkt(otInstance *aInstance);
/**
* This function returns if the given frame is a GP frame and should be buffered
*
* @param[in] aInstance A pointer to the OpenThread instance structure.
* @param[in] aFrame A pointer to the MAC frame buffer.
* @param[in] isRxFrame If the give frame is a incoming or outgoing frame.
*
* @retval true Frame should be buffered
* @retval false Frame should not be buffered
*/
bool sl_gp_intf_should_buffer_pkt(otInstance *aInstance, otRadioFrame *aFrame, bool isRxFrame);
/**
* This function returns if the given frame is a GP frame.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @retval true Frame is a GP packet.
* @retval false Frame is not a GP packet.
*/
bool sl_gp_intf_is_gp_pkt(otRadioFrame *aFrame);
#endif

View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* Helper functions for Silicon Labs Multipan implementation.
*/
#ifndef SL_MULTIPAN_H_
#define SL_MULTIPAN_H_
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#include <openthread/platform/multipan.h>
#endif
#include "utils/code_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#define RADIO_INTERFACE_COUNT (OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM + 1)
#else
#define RADIO_INTERFACE_COUNT 1
extern otInstance *sInstance;
#endif
#define INVALID_INTERFACE_INDEX (0xFF)
typedef enum
{
EFR32_IID_BCAST = 0,
EFR32_IID_1 = 1,
EFR32_IID_2 = 2,
EFR32_IID_3 = 3,
EFR32_IID_INVALID = 0xFF
} efr32Iid_t;
/*
* RAIL accepts 3 pan indices 0, 1 or 2. But valid IIDs are 1, 2 and 3 (0 is reserved for bcast).
* This API validates the passed IID and converts it into usable PanIndex.
*/
static inline uint8_t efr32GetPanIndexFromIid(uint8_t iid)
{
uint8_t panIndex = 0;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
otEXPECT_ACTION(((iid < RADIO_INTERFACE_COUNT) && (iid != 0)), panIndex = INVALID_INTERFACE_INDEX);
panIndex = iid - 1;
exit:
#else
panIndex = iid;
#endif
return panIndex;
}
static inline otInstance *efr32GetInstanceFromIid(efr32Iid_t aIid)
{
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
return otPlatMultipanIidToInstance((uint8_t)aIid);
#else
OT_UNUSED_VARIABLE(aIid);
return sInstance;
#endif
}
static inline uint8_t efr32GetIidFromInstance(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
return otPlatMultipanInstanceToIid(aInstance);
#else
return 0;
#endif
}
#ifdef __cplusplus
} // extern "C"
#endif
#endif // SL_MULTIPAN_H_

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes the initializers for supporting Security manager.
*
*/
#ifndef SL_PACKET_HANDLER_H
#define SL_PACKET_HANDLER_H
#include <openthread/platform/radio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* This function performs AES CCM on the frame which is going to be sent.
*
* @param[in] aFrame A pointer to the MAC frame buffer that is going to be sent.
* @param[in] aExtAddress A pointer to the extended address, which will be used to generate nonce
* for AES CCM computation.
*
*/
void efr32PlatProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress);
/**
* This function returns if the Frame Pending bit is set in any given frame.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @retval true Frame Pending is set.
* @retval false Frame Pending is not set.
*/
bool efr32IsFramePending(otRadioFrame *aFrame);
/**
* This function returns the Destination PanId, if present.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @retval DstPanId If present.
* @retval BcastPanId If Dest PanId is compressed.
*/
otPanId efr32GetDstPanId(otRadioFrame *aFrame);
/**
* This function returns the start of payload pointer.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @retval Pointer to start of 802.15.4 payload.
*/
uint8_t *efr32GetPayload(otRadioFrame *aFrame);
/**
* This function checks if the PAN ID Compression bit is set in the given MAC frame.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @return true if the PAN ID Compression bit is set, false otherwise.
*/
bool efr32FrameIsPanIdCompressed(otRadioFrame *aFrame);
/**
* This function returns the frame version.
*
* @param[in] aFrame A pointer to the MAC frame buffer.
*
* @retval Frame version.
*/
uint16_t efr32GetFrameVersion(otRadioFrame *aFrame);
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* SL_PACKET_HANDLER_H */

View File

@@ -0,0 +1,226 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for power (sleep)
* management.
*
*/
#define CURRENT_MODULE_NAME "OPENTHREAD"
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#include "alarm.h"
#include "sl_core.h"
#include "sleep.h"
#include "platform-efr32.h"
#include <assert.h>
#include <openthread-core-config.h>
#include <openthread/tasklet.h>
#include <openthread/platform/toolchain.h>
#include "sl_multipan.h"
#include "utils/code_utils.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
//------------------------------------------------------------------------------
// Forward declarations
#if (defined(SL_CATALOG_POWER_MANAGER_PRESENT))
static void setWakeRequirement(bool aShouldWake);
static bool isPlatformEventPending(void);
static bool shouldStayAwake(void);
static bool instanceShouldInterruptSleep(otInstance *aInstance);
static bool shouldInterruptSleep(void);
//------------------------------------------------------------------------------
// Static variables
static bool sWakeRequirementSet = false;
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
extern otInstance *sInstance;
//------------------------------------------------------------------------------
// Internal APIs and callbacks
void sl_ot_sleep_init(void)
{
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
setWakeRequirement(true);
#else
sWakeRequirementSet = true;
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
}
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_OT_PLATFORM_ABSTRACTION, SL_CODE_CLASS_TIME_CRITICAL)
OT_TOOL_WEAK bool efr32AllowSleepCallback(void)
{
return !sWakeRequirementSet;
}
#if (defined(SL_CATALOG_POWER_MANAGER_PRESENT))
// This is invoked only the bare metal case.
bool sl_ot_is_ok_to_sleep(void)
{
return !(sWakeRequirementSet || shouldInterruptSleep());
}
// This is invoked only the bare metal case.
sl_power_manager_on_isr_exit_t sl_ot_sleep_on_isr_exit(void)
{
return (isPlatformEventPending() ? SL_POWER_MANAGER_WAKEUP : SL_POWER_MANAGER_IGNORE);
}
void sl_ot_sleep_update(void)
{
setWakeRequirement(shouldStayAwake());
}
//------------------------------------------------------------------------------
// Static functions
/**
* @brief Set the wake requirement for the system.
*
* @param[in] aShouldWake True if the system should wake up.
*
*/
static void setWakeRequirement(bool aShouldWake)
{
otEXPECT(aShouldWake != sWakeRequirementSet);
void (*em_operation)(sl_power_manager_em_t) =
aShouldWake ? &sl_power_manager_add_em_requirement : &sl_power_manager_remove_em_requirement;
(*em_operation)(SL_POWER_MANAGER_EM1);
sWakeRequirementSet = aShouldWake;
exit:
return;
}
/**
* @brief Check if there is any platform event pending.
*
* @return True if there is a platform event pending.
*
*/
static bool isPlatformEventPending(void)
{
bool isPending = efr32AlarmIsReady();
#if defined(SL_CATALOG_IOSTREAM_EUSART_PRESENT) || defined(SL_CATALOG_IOSTREAM_USART_PRESENT)
isPending = isPending || efr32UartIsDataReady();
#endif
return isPending;
}
/**
* @brief Check if the system should stay awake.
*
* @return True if the system should stay awake.
*
*/
static bool shouldStayAwake(void)
{
bool shouldWake = (!(efr32AllowSleepCallback()) || isPlatformEventPending());
#if defined SL_CATALOG_KERNEL_PRESENT
shouldWake = shouldWake || shouldInterruptSleep();
#endif
return shouldWake;
}
/**
* @brief Check if individual instance should interrupt sleep.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @return True if the system should interrupt sleep.
*
*/
static bool instanceShouldInterruptSleep(otInstance *aInstance)
{
bool shouldWake = true;
otEXPECT(aInstance != NULL);
shouldWake = otTaskletsArePending(aInstance);
shouldWake = shouldWake
|| (efr32AlarmIsRunning(aInstance)
&& efr32AlarmPendingTime(aInstance) < OPENTHREAD_CONFIG_MIN_SLEEP_DURATION_MS);
exit:
return shouldWake;
}
/**
* @brief Check if the system should interrupt sleep.
*
* @details This function should be used to prevent power manager from entering sleep mode
* based on events that happen after the OpenThread power manager module complete.
*
* @return True if the system should interrupt sleep.
*
*/
static bool shouldInterruptSleep(void)
{
CORE_ATOMIC_IRQ_DISABLE();
otInstance *instance;
bool shouldWake = false;
uint8_t instanceIndex = 0;
while ((!shouldWake) && instanceIndex < OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM)
{
// Use instance offset from multipan index for multipan configuration
// or sInstance for non-multipan configuration
instance = efr32GetInstanceFromIid((efr32Iid_t)(instanceIndex + 1));
shouldWake = instanceShouldInterruptSleep(instance);
instanceIndex++;
}
CORE_ATOMIC_IRQ_ENABLE();
return shouldWake;
}
#endif // SL_CATALOG_POWER_MANAGER_PRESENT

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes the initializers for supporting OpenThread with
* power manager.
*
*/
#ifndef SLEEP_H_
#define SLEEP_H_
#include <stdbool.h>
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif
/**
* This function initializes the sleep interface
* and starts the platform in an active state.
*
*/
void sl_ot_sleep_init(void);
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
/**
* This function notifies the platform to refresh sleep requirements.
*
*/
void sl_ot_sleep_update(void);
/**
* This function notifies power manager whether OpenThread will
* prevent the system from sleeping when sleep is requested.
*
* This function is only used for bare metal applications.
*
* @retval true The OpenThread power manager module will not prevent app from sleeping.
* false The OpenThread power manager module will prevent app from sleeping.
*
*/
bool sl_ot_is_ok_to_sleep(void);
/**
* This function notifies power manager whether OpenThread will
* prevent the system from sleeping when an ISR that interrupt sleep exits.
*
* This function is only used for bare metal applications.
*
* @retval SL_POWER_MANAGER_IGNORE The OpenThread power manager module will not influence
* power manager when deciding to sleep after ISR exit
* SL_POWER_MANAGER_WAKEUP The OpenThread power manager module will prevent
* power manager from entering sleep after ISR exit.
*/
sl_power_manager_on_isr_exit_t sl_ot_sleep_on_isr_exit(void);
#endif
#endif // SLEEP_H_

View File

@@ -0,0 +1,406 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements a software Source Match table, for radios that don't have
* such hardware acceleration. It supports only the single-instance build of
* OpenThread.
*
*/
#include "soft_source_match_table.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <openthread/logging.h>
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#include <openthread/platform/multipan.h>
#endif
#include "sl_multipan.h"
#include "common/debug.hpp"
#include "utils/code_utils.h"
// Print entire source match tables when
#define PRINT_MULTIPAN_SOURCE_MATCH_TABLES 0
#if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
static uint16_t sPanId[RADIO_CONFIG_SRC_MATCH_PANID_NUM] = {0};
#if PRINT_MULTIPAN_SOURCE_MATCH_TABLES
static void printPanIdTable(void)
{
for (uint8_t panIndex = 0; panIndex < RADIO_CONFIG_SRC_MATCH_PANID_NUM; panIndex++)
{
otLogDebgPlat("sPanId[panIndex=%d] = 0x%04x", panIndex, sPanId[panIndex]);
}
}
#else
#define printPanIdTable()
#endif
void utilsSoftSrcMatchSetPanId(uint8_t iid, uint16_t aPanId)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
sPanId[panIndex] = aPanId;
otLogInfoPlat("Setting panIndex=%d to 0x%04x", panIndex, aPanId);
printPanIdTable();
}
#endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
#if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
typedef struct srcMatchShortEntry
{
uint16_t checksum;
bool allocated;
} sSrcMatchShortEntry;
static sSrcMatchShortEntry srcMatchShortEntry[RADIO_CONFIG_SRC_MATCH_PANID_NUM][RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM];
#if PRINT_MULTIPAN_SOURCE_MATCH_TABLES
static void printShortEntryTable(uint8_t iid)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
otLogDebgPlat("================================|============|===========");
otLogDebgPlat("ShortEntry[panIndex][entry] | .allocated | .checksum ");
otLogDebgPlat("================================|============|===========");
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
{
otLogDebgPlat("ShortEntry[panIndex=%d][entry=%d] | %d | 0x%04x",
panIndex,
i,
srcMatchShortEntry[panIndex][i].allocated,
srcMatchShortEntry[panIndex][i].checksum);
}
otLogDebgPlat("================================|============|===========");
}
#else
#define printShortEntryTable(iid)
#endif
int16_t utilsSoftSrcMatchShortFindEntry(uint8_t iid, uint16_t aShortAddress)
{
int16_t entry = -1;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
if (iid == 0)
{
return entry;
}
#endif
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
uint16_t checksum = aShortAddress + sPanId[panIndex];
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
{
if (checksum == srcMatchShortEntry[panIndex][i].checksum && srcMatchShortEntry[panIndex][i].allocated)
{
entry = i;
break;
}
}
return entry;
}
static int16_t findSrcMatchShortAvailEntry(uint8_t iid)
{
int16_t entry = -1;
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
{
if (!srcMatchShortEntry[panIndex][i].allocated)
{
entry = i;
break;
}
}
return entry;
}
static inline void addToSrcMatchShortIndirect(uint8_t iid, uint16_t entry, uint16_t aShortAddress)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
uint16_t checksum = aShortAddress + sPanId[panIndex];
srcMatchShortEntry[panIndex][entry].checksum = checksum;
srcMatchShortEntry[panIndex][entry].allocated = true;
printShortEntryTable(iid);
}
static inline void removeFromSrcMatchShortIndirect(uint8_t iid, uint16_t entry)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
srcMatchShortEntry[panIndex][entry].allocated = false;
srcMatchShortEntry[panIndex][entry].checksum = 0;
printShortEntryTable(iid);
}
otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
int8_t iid = efr32GetIidFromInstance(aInstance);
int16_t entry = -1;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
entry = utilsSoftSrcMatchShortFindEntry(iid, aShortAddress);
// Prevent duplicate entries in multipan use case.
otEXPECT(!(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM));
#endif
entry = findSrcMatchShortAvailEntry(iid);
otLogDebgPlat("Add ShortAddr: iid=%d, entry=%d, addr=0x%04x", iid, entry, aShortAddress);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM, error = OT_ERROR_NO_BUFS);
addToSrcMatchShortIndirect(iid, (uint16_t)entry, aShortAddress);
exit:
return error;
}
otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
int8_t iid = efr32GetIidFromInstance(aInstance);
int16_t entry = utilsSoftSrcMatchShortFindEntry(iid, aShortAddress);
otLogDebgPlat("Clear ShortAddr: iid=%d, entry=%d, addr=0x%04x", iid, entry, aShortAddress);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM, error = OT_ERROR_NO_ADDRESS);
removeFromSrcMatchShortIndirect(iid, (uint16_t)entry);
exit:
return error;
}
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
uint8_t iid = efr32GetIidFromInstance(aInstance);
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
otLogDebgPlat("Clear ShortAddr entries (iid: %d)", iid);
memset(srcMatchShortEntry[panIndex], 0, sizeof(srcMatchShortEntry[panIndex]));
printShortEntryTable(iid);
}
#endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
#if RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
typedef struct srcMatchExtEntry
{
uint16_t checksum;
bool allocated;
} sSrcMatchExtEntry;
static sSrcMatchExtEntry srcMatchExtEntry[RADIO_CONFIG_SRC_MATCH_PANID_NUM][RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM];
#if PRINT_MULTIPAN_SOURCE_MATCH_TABLES
static void printExtEntryTable(uint8_t iid)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
otLogDebgPlat("==============================|============|===========");
otLogDebgPlat("ExtEntry[panIndex][entry] | .allocated | .checksum ");
otLogDebgPlat("==============================|============|===========");
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
{
otLogDebgPlat("ExtEntry[panIndex=%d][entry=%d] | %d | 0x%04x",
panIndex,
i,
srcMatchExtEntry[panIndex][i].allocated,
srcMatchExtEntry[panIndex][i].checksum);
}
otLogDebgPlat("==============================|============|===========");
}
#else
#define printExtEntryTable(iid)
#endif
int16_t utilsSoftSrcMatchExtFindEntry(uint8_t iid, const otExtAddress *aExtAddress)
{
int16_t entry = -1;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
if (iid == 0)
{
return entry;
}
#endif
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
uint16_t checksum = sPanId[panIndex];
checksum += (uint16_t)aExtAddress->m8[0] | (uint16_t)(aExtAddress->m8[1] << 8);
checksum += (uint16_t)aExtAddress->m8[2] | (uint16_t)(aExtAddress->m8[3] << 8);
checksum += (uint16_t)aExtAddress->m8[4] | (uint16_t)(aExtAddress->m8[5] << 8);
checksum += (uint16_t)aExtAddress->m8[6] | (uint16_t)(aExtAddress->m8[7] << 8);
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
{
if (checksum == srcMatchExtEntry[panIndex][i].checksum && srcMatchExtEntry[panIndex][i].allocated)
{
entry = i;
break;
}
}
return entry;
}
static int16_t findSrcMatchExtAvailEntry(uint8_t iid)
{
int16_t entry = -1;
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
{
if (!srcMatchExtEntry[panIndex][i].allocated)
{
entry = i;
break;
}
}
return entry;
}
static inline void addToSrcMatchExtIndirect(uint8_t iid, uint16_t entry, const otExtAddress *aExtAddress)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
uint16_t checksum = sPanId[panIndex];
checksum += (uint16_t)aExtAddress->m8[0] | (uint16_t)(aExtAddress->m8[1] << 8);
checksum += (uint16_t)aExtAddress->m8[2] | (uint16_t)(aExtAddress->m8[3] << 8);
checksum += (uint16_t)aExtAddress->m8[4] | (uint16_t)(aExtAddress->m8[5] << 8);
checksum += (uint16_t)aExtAddress->m8[6] | (uint16_t)(aExtAddress->m8[7] << 8);
srcMatchExtEntry[panIndex][entry].checksum = checksum;
srcMatchExtEntry[panIndex][entry].allocated = true;
printExtEntryTable(iid);
}
static inline void removeFromSrcMatchExtIndirect(uint8_t iid, uint16_t entry)
{
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
srcMatchExtEntry[panIndex][entry].allocated = false;
srcMatchExtEntry[panIndex][entry].checksum = 0;
printExtEntryTable(iid);
}
otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_NONE;
uint8_t iid = efr32GetIidFromInstance(aInstance);
int16_t entry = -1;
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
entry = utilsSoftSrcMatchExtFindEntry(iid, aExtAddress);
// Prevent duplicate entries in multipan use case.
otEXPECT(!(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM));
#endif
entry = findSrcMatchExtAvailEntry(iid);
otLogDebgPlat("Add ExtAddr: iid=%d, entry=%d, addr %p", iid, entry, (void *)aExtAddress->m8);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM, error = OT_ERROR_NO_BUFS);
addToSrcMatchExtIndirect(iid, (uint16_t)entry, aExtAddress);
exit:
return error;
}
otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
otError error = OT_ERROR_NONE;
uint8_t iid = efr32GetIidFromInstance(aInstance);
int16_t entry = utilsSoftSrcMatchExtFindEntry(iid, aExtAddress);
otLogDebgPlat("Clear ExtAddr: iid=%d, entry=%d", iid, entry);
otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM, error = OT_ERROR_NO_ADDRESS);
removeFromSrcMatchExtIndirect(iid, (uint16_t)entry);
exit:
return error;
}
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
uint8_t iid = efr32GetIidFromInstance(aInstance);
otLogDebgPlat("Clear ExtAddr entries (iid: %d)", iid);
const uint8_t panIndex = efr32GetPanIndexFromIid(iid);
memset(srcMatchExtEntry[panIndex], 0, sizeof(srcMatchExtEntry[panIndex]));
printExtEntryTable(iid);
}
#endif // RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
uint8_t utilsSoftSrcMatchFindIidFromPanId(otPanId panId)
{
uint8_t iid = INVALID_INTERFACE_INDEX;
for (uint8_t index = 0; index < RADIO_CONFIG_SRC_MATCH_PANID_NUM; index++)
{
if (sPanId[index] == panId)
{
iid = index + 1;
break;
}
}
return iid;
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file defines the software source match table interfaces used by
* soft_source_match_table.c.
*/
#ifndef SOFT_SOURCE_MATCH_TABLE_H
#define SOFT_SOURCE_MATCH_TABLE_H
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#include "spinel/openthread-spinel-config.h"
#endif
#include <openthread/platform/radio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#define RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM OPENTHREAD_SPINEL_CONFIG_MAX_SRC_MATCH_ENTRIES
#else
#define RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM OPENTHREAD_CONFIG_MLE_MAX_CHILDREN
#endif
#endif
#ifndef RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#define RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM OPENTHREAD_SPINEL_CONFIG_MAX_SRC_MATCH_ENTRIES
#else
#define RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM OPENTHREAD_CONFIG_MLE_MAX_CHILDREN
#endif
#endif
#ifndef RADIO_CONFIG_SRC_MATCH_PANID_NUM
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#define RADIO_CONFIG_SRC_MATCH_PANID_NUM 3
#else
#define RADIO_CONFIG_SRC_MATCH_PANID_NUM 1
#endif
#endif
#if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
void utilsSoftSrcMatchSetPanId(uint8_t iid, uint16_t aPanId);
#endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
#if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
int16_t utilsSoftSrcMatchShortFindEntry(uint8_t iid, uint16_t aShortAddress);
#endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
#if RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
int16_t utilsSoftSrcMatchExtFindEntry(uint8_t iid, const otExtAddress *aExtAddress);
#endif // RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
uint8_t utilsSoftSrcMatchFindIidFromPanId(otPanId panId);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // SOFT_SOURCE_MATCH_TABLE_H

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements gcc-specific startup code for the efr32.
*/
__extension__ typedef int __guard __attribute__((mode(__DI__)));
int __cxa_guard_acquire(__guard *g)
{
return !*(char *)(g);
}
void __cxa_guard_release(__guard *g)
{
*(char *)g = 1;
}
void __cxa_guard_abort(__guard *g)
{
(void)g;
}
void __cxa_pure_virtual(void)
{
while (1)
;
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2023, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes the platform-specific initializers.
*/
#include <assert.h>
#include <string.h>
#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#include <openthread-core-config.h>
#include <openthread-system.h>
#include <openthread/platform/toolchain.h>
#include "utils/uart.h"
#include "rail.h"
#include "common/logging.hpp"
#if defined(SL_CATALOG_MPU_PRESENT)
#include "sl_mpu.h"
#endif
#include "sl_memory_manager.h"
#include "sl_sleeptimer.h"
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#include "sl_gp_interface.h"
#endif
#include "alarm.h"
#include "platform-efr32.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sleep.h"
#endif
#define USE_EFR32_LOG (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
#if defined(SL_CATALOG_OPENTHREAD_CLI_PRESENT) && defined(SL_CATALOG_KERNEL_PRESENT)
#define SERIAL_TASK_ENABLED (SL_OPENTHREAD_ENABLE_SERIAL_TASK)
#else
#define SERIAL_TASK_ENABLED (0)
#endif
otInstance *sInstance;
#if (OPENTHREAD_RADIO)
static void efr32NcpProcess(void);
#else
static void efr32CliProcess(void);
#endif
#ifndef SL_COMPONENT_CATALOG_PRESENT
OT_TOOL_WEAK void sl_openthread_init(void)
{
// Placeholder for enabling Silabs specific features available only through Simplicity Studio
}
#else
void sl_openthread_init(void);
#endif // SL_COMPONENT_CATALOG_PRESENT
void otSysInit(int argc, char *argv[])
{
OT_UNUSED_VARIABLE(argc);
OT_UNUSED_VARIABLE(argv);
sl_ot_sys_init();
}
void sl_ot_sys_init(void)
{
sl_openthread_init();
#if USE_EFR32_LOG
efr32LogInit();
#endif
efr32AlarmInit();
efr32RadioInit();
efr32MiscInit();
}
bool otSysPseudoResetWasRequested(void)
{
return false;
}
void otSysDeinit(void)
{
efr32RadioDeinit();
#if USE_EFR32_LOG
efr32LogDeinit();
#endif
}
void otSysProcessDrivers(otInstance *aInstance)
{
sInstance = aInstance;
// should sleep and wait for interrupts here
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
efr32GpProcess();
#endif
#if (SERIAL_TASK_ENABLED == 0)
// Serial task is not enabled, process serial events here
efr32SerialProcess();
#endif
efr32RadioProcess(aInstance);
// See alarm.c: Wrapped in a critical section
efr32AlarmProcess(aInstance);
#if !defined(SL_CATALOG_KERNEL_PRESENT)
otSysEventSignalPending();
#endif
}
OT_TOOL_WEAK void otSysEventSignalPending(void)
{
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_ot_sleep_update();
#endif
}
/* Serial process helper functions */
void efr32SerialProcess(void)
{
#if (OPENTHREAD_RADIO)
efr32NcpProcess();
#else
efr32CliProcess();
#endif // OPENTHREAD_RADIO
}
#if (OPENTHREAD_RADIO)
static void efr32NcpProcess(void)
{
#if OPENTHREAD_CONFIG_NCP_HDLC_ENABLE
efr32UartProcess();
#elif OPENTHREAD_CONFIG_NCP_CPC_ENABLE
efr32CpcProcess();
#elif OPENTHREAD_CONFIG_NCP_SPI_ENABLE
efr32SpiProcess();
#endif
}
#else
static void efr32CliProcess(void)
{
efr32UartProcess();
}
#endif

View File

@@ -0,0 +1,32 @@
#ifndef _UART_H
#define _UART_H
#include <stdbool.h>
/**
* The size of the receive buffer
*
*/
#define RECEIVE_BUFFER_SIZE 128
/**
* This function initializes the UART interface.
*
*/
void efr32UartInit(void);
/**
* This function performs UART processing.
*
*/
void efr32UartProcess(void);
/**
* This function informs the caller whether UART
* operations are ready to process
*
* @return true if RX or TX data is ready to process.
*/
bool efr32UartIsDataReady(void);
#endif // _UART_H

View File

@@ -0,0 +1,98 @@
/*******************************************************************************
* @file
* @brief This file includes the Radio Coex initializers
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 RADIO_COEX_H_
#define RADIO_COEX_H_
#include <assert.h>
#include <openthread-core-config.h>
#include <openthread-system.h>
#include <openthread/link.h>
#include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#include <openthread/platform/radio.h>
#include <openthread/platform/time.h>
#ifdef SL_COMPONENT_CATALOG_PRESENT
#include "sl_component_catalog.h"
#endif // SL_COMPONENT_CATALOG_PRESENT
#ifndef SL_CATALOG_OT_SIMULATION_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_COEX_PRESENT
#include "coexistence-802154.h"
#include "coexistence-ot.h"
#include "coexistence.h"
#endif // SL_CATALOG_RAIL_UTIL_COEX_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
#include "sl_rail_util_ant_div.h"
#endif // SL_CATALOG_RAIL_UTIL_ANT_DIV_PRESENT
#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT_PRESENT
#include "sl_rail_util_ieee802154_phy_select.h"
#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_PHY_SELECT
#else // SL_CATALOG_OT_SIMULATION_PRESENT
#include "rail_util_simulation.h"
#endif // SL_CATALOG_OT_SIMULATION_PRESENT
#include "common/code_utils.hpp"
#include "utils/code_utils.h"
typedef enum
{
SL_OT_COEX_EVENT_REQUEST_COUNT = 0,
SL_OT_COEX_EVENT_GRANT_IMMEDIATE_COUNT,
SL_OT_COEX_EVENT_GRANT_WAIT_COUNT,
SL_OT_COEX_EVENT_GRANT_WAIT_ACTIVATED_COUNT,
SL_OT_COEX_EVENT_GRANT_WAIT_TIMEOUT_COUNT,
SL_OT_COEX_EVENT_GRANT_DEACTIVATED_DURING_REQUEST_COUNT,
SL_OT_COEX_EVENT_DELAYED_GRANT_COUNT,
SL_OT_COEX_EVENT_AVG_REQUEST_TO_GRANT_TIME
} sl_coex_events;
typedef struct sl_ot_coex_counter
{
otRadioCoexMetrics metrics;
uint64_t timestamp;
uint64_t totalTxReqToGrantDuration;
uint64_t totalRxReqToGrantDuration;
} sl_ot_coex_counter_t;
/**
* Reset the radio coex counters.
*/
void sli_radio_coex_reset(void);
#endif // RADIO_COEX_H_

View File

@@ -0,0 +1,78 @@
/*******************************************************************************
* @file
* @brief This file defines the radio counters updated by the efr32 PAL
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 RADIO_COUNTERS_H_
#define RADIO_COUNTERS_H_
#include <stdint.h>
typedef struct efr32RadioCounters
{
uint32_t mRailPlatTxTriggered;
uint32_t mRailPlatRadioReceiveDoneCbCount;
uint32_t mRailPlatRadioReceiveProcessedCount;
uint32_t mRailPlatRadioEnergyScanDoneCbCount;
uint32_t mRailPlatRadioTxDoneCbCount;
uint32_t mRailTxStarted;
uint32_t mRailTxStartFailed;
uint32_t mRailEventAcksReceived;
uint32_t mRailEventConfigScheduled;
uint32_t mRailEventConfigUnScheduled;
uint32_t mRailEventPacketSent;
uint32_t mRailEventChannelBusy;
uint32_t mRailEventEnergyScanCompleted;
uint32_t mRailEventCalNeeded;
uint32_t mRailEventPacketReceived;
uint32_t mRailEventNoAck;
uint32_t mRailEventTxAbort;
uint32_t mRailEventSchedulerStatusError;
uint32_t mRailEventsSchedulerStatusTransmitBusy;
uint32_t mRailEventsSchedulerStatusLastStatus;
uint32_t mRailEventsEnhAckTxFailed;
uint32_t mRailEventsScheduledTxTriggeredCount;
uint32_t mRailEventsScheduledTxStartedCount;
union
{
// Allow for reuse / overloading of fields for various debugging
uint32_t m32;
uint16_t m16[2];
uint8_t m8[4]; // see defines below for suggested subfield usage
} mRadioDebugData;
} efr32RadioCounters;
// Offsets for use with Radio Debug Data subfields
enum
{
RX_DEBUG_COUNTER0 = 0,
RX_DEBUG_COUNTER1,
TX_DEBUG_COUNTER0,
TX_DEBUG_COUNTER1
};
#endif // RADIO_COUNTERS_H_

View File

@@ -0,0 +1,691 @@
/*******************************************************************************
* @file
* @brief Defines the Silicon Labs extension to the openthread platform radio interface.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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 _RADIO_EXTENSION_H
#define _RADIO_EXTENSION_H
#include <stdint.h>
#include <openthread/error.h>
#include "radio_counters.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup plat-radio
*
* @{
*
*/
/**
* @defgroup radio-extension Radio Extension
*
* @brief
* This module includes the Silicon Labs extension to the openthread
* platform radio interface.
*
* The functions in this modules provide an API that can be called from
* SoC or host based openthread applications.
*
* @note Many of the functions defined in this module are wrappers on
* top of the Silicon Labs RAIL API. For additional information on the
* RAIl API please refer to the `Silicon Labs RAIL API Reference Guide`.
* Those functions that are wrappers to RAIL functions include a
* reference to the underlying RAIL function.
*
* @{
*
*/
/**
* Get the antenna diversity transmit antenna mode.
*
* Requires the `ot_ant_div` component.
*
* @sa RAIL API: **sl_rail_util_ant_div_get_tx_antenna_mode()**
*
* @param[out] aMode A pointer to the location where the current transmit
* antenna mode will be returned. Antenna modes are
* defined by the RAIL `sl_rail_util_antenna_mode_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the transmit antenna mode.
* @retval OT_ERROR_INVALID_ARGS The @p aMode parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Antenna diversity is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetTxAntennaMode(uint8_t *aMode);
/**
* Set the antenna diversity transmit antenna mode.
*
* Requires the `ot_ant_div` component.
*
* @sa RAIL API: **sl_rail_util_ant_div_set_tx_antenna_mode()**
*
* @param[in] aMode The antenna mode to use for transmit. Antenna modes are
* defined by the RAIL `sl_rail_util_antenna_mode_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the transmit antenna mode.
* @retval OT_ERROR_FAILED The specified transmit antenna mode is not supported.
* @retval OT_ERROR_NOT_IMPLEMENTED Antenna diversity is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetTxAntennaMode(uint8_t aMode);
/**
* Get the antenna diversity receive antenna mode.
*
* Requires the `ot_ant_div` component.
*
* @sa RAIL API: **sl_rail_util_ant_div_get_rx_antenna_mode()**
*
* @param[out] aMode A pointer to the location where the current receive
* antenna mode will be returned. Antenna modes are
* defined by the RAIL `sl_rail_util_antenna_mode_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the receive antenna mode.
* @retval OT_ERROR_INVALID_ARGS The @p aMode parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Antenna diversity is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetRxAntennaMode(uint8_t *aMode);
/**
* Set the antenna diversity receive antenna mode.
*
* Requires the `ot_ant_div` component.
*
* @sa RAIL API: **sl_rail_util_ant_div_set_rx_antenna_mode()**
*
* @param[in] aMode The antenna mode to use for receive. Antenna modes are
* defined by the RAIL `sl_rail_util_antenna_mode_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the receive antenna mode.
* @retval OT_ERROR_FAILED The specified receive antenna mode is not supported.
* @retval OT_ERROR_NOT_IMPLEMENTED Antenna diversity is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetRxAntennaMode(uint8_t aMode);
/**
* Get the antenna diversity active phy state.
*
* Requires the `ot_ant_div` component.
*
* @sa RAIL API: **sl_rail_util_ieee802154_get_active_radio_config()**
*
* @param[out] aActivePhy A pointer to the location where the current phy
* state will be returned. Phy states are defined by
* the RAIL `sl_rail_util_ieee802154_radio_config_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the phy state.
* @retval OT_ERROR_INVALID_ARGS The @p aActivePhy parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Antenna diversity is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetActivePhy(uint8_t *aActivePhy);
/**
* Get the coexistence directional priority state and pulse width.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_directional_priority_pulse_width()**
*
* @param[out] aDpPulse A pointer to the location where the current directional
* priority state will be returned. If @p aDpPulse is 0
* then directional priority is disabled. If @p aDpPulse is
* not 0 then directional priority is enabled and the value
* is the pulse width in microseconds.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the directional priority.
* @retval OT_ERROR_INVALID_ARGS The @p aDpPulse parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetDpState(uint8_t *aDpPulse);
/**
* Set the coexistence directional priority state and pulse width.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_directional_priority_pulse_width()**
*
* @param[in] aDpPulse The directional priority state to set. If @p aDpPulse is 0
* then directional priority will be disabled. If @p aDpPulse is
* not 0 then directional priority will be enabled and the value
* will be the pulse width to use in microseconds.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the directional priority.
* @retval OT_ERROR_FAILED The @p aDpPulse is invalid.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetDpState(uint8_t aDpPulse);
/**
* Get the override input value of a GPIO.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_gpio_input_override()**
*
* @param[in] aGpioIndex The GPIO index
* - 0x00 = Radio Holdoff GPIO index
* - 0x01 = Request GPIO index
* - 0x02 = Grant GPIO index
* - 0x03 = PHY Select index
* @param[out] aEnabled A pointer to the location where the boolean override input
* value will be returned. A TRUE value indicating the
* override input value is enabled, FALSE disabled. The return
* is inverted if the selected GPIO is active low.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the override input value.
* @retval OT_ERROR_INVALID_ARGS The @p aGpioIndex parameter is invalid and/or @p aDpPulse parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetGpioInputOverride(uint8_t aGpioIndex, bool *aEnabled);
/**
* Set the override input value of a GPIO.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_gpio_input_override()**
*
* @param[in] aGpioIndex The GPIO index
* - 0x00 = Radio Holdoff GPIO index
* - 0x01 = Request GPIO index
* - 0x02 = Grant GPIO index
* - 0x03 = PHY Select index
* @param[in] aEnabled The boolean override input value. A TRUE value indicating the
* override input value is enabled, FALSE disabled.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the override input value.
* @retval OT_ERROR_INVALID_ARGS The @p aGpioIndex parameter is invalid.
* @retval OT_ERROR_FAILED The override input value of the specified GPIO can not be set.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetGpioInputOverride(uint8_t aGpioIndex, bool aEnabled);
/**
* Get the coexistence active phy state.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_ieee802154_get_active_radio_config()**
*
* @param[out] aActivePhy A pointer to the location where the current phy
* state will be returned. Phy states are defined by
* the RAIL `sl_rail_util_ieee802154_radio_config_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the phy state.
* @retval OT_ERROR_INVALID_ARGS The @p aActivePhy parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetActiveRadio(uint8_t *aActivePhy);
/**
* Get the coexistence phy select state and timeout.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_phy_select_timeout()**
*
* @param[out] aTimeout A pointer to the location where the current phy
* select state will be returned. If @p aTimeout is 0
* then phy select is disabled. If @p aTimeout is
* not 0 then phy select is enabled and the value
* is the timeout in milliseconds.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the phy select state.
* @retval OT_ERROR_INVALID_ARGS The @p aTimeout parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetPhySelectTimeout(uint8_t *aTimeout);
/**
* Set the coexistence phy select state and timeout.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_phy_select_timeout()**
*
* @param[in] aTimeout The phy select state to set. If @p aTimeout is 0
* then phy select will be disabled. If @p aTimeout is
* not 0 then phy select will be enabled and the value
* will be the timeout to use in milliseconds.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the directional priority.
* @retval OT_ERROR_FAILED The @p aTimeout is invalid.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetPhySelectTimeout(uint8_t aTimeout);
/**
* Get the coexistence bitmask of features.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_options()**
*
* @param[out] aPtaOptions A pointer to the location where the coexistence
* feature bitmask will be returned. The feature
* bitmask is defined by the set of macros making up
* the RAIL `sl_rail_util_coex_options_t` type.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the bitmask of features.
* @retval OT_ERROR_INVALID_ARGS The @p aPtaOptions parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetCoexOptions(uint32_t *aPtaOptions);
/**
* Set the coexistence bitmask of features.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_options()**
*
* @param[in] aPtaOptions The coexistence feature bitmask to set. The feature
* bitmask is defined by the set of macros making up
* the RAIL `sl_rail_util_coex_options_t` type.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the bitmask of features.
* @retval OT_ERROR_INVALID_ARGS The @p aPtaOptions is invalid.
* @retval OT_ERROR_FAILED The bitmask of features can not be set.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetCoexOptions(uint32_t aPtaOptions);
/**
* Get the coexistence bitmask of constant PTA features that can not be modified using public APIs.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_constant_options()**
*
* @param[out] aPtaOptions A pointer to the location where the coexistence
* constant PTA feature bitmask will be returned. The feature
* bitmask is defined by the set of macros making up
* the RAIL `sl_rail_util_coex_options_t` type.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the bitmask of of constant PTA features.
* @retval OT_ERROR_INVALID_ARGS The @p aPtaOptions parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetCoexConstantOptions(uint32_t *aPtaOptions);
/**
* Get the coexistence enabled status.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_is_enabled()**
*
* @param[out] aPtaState A pointer to the location where the coexistence
* enabled status will be returned.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the coexistence status.
* @retval OT_ERROR_INVALID_ARGS The @p aPtaState parameter is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionIsCoexEnabled(bool *aPtaState);
/**
* Set the coexistence enabled status.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_enable()**
*
* @param[in] aPtaState The coexistence enabled status.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the coexistence status.
* @retval OT_ERROR_FAILED The coexistence status can not be set.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetCoexEnable(bool aPtaState);
/**
* Get the coexistence PWM configuration.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_get_request_pwm_args()**
*
* @param[out] aPwmReq A pointer to the location where the coexistence
* PWM request is returned. The value is defined
* as a bitmap using shift values from the RAIL
* `COEX_Req_t` enumeration.
* @param[out] aPwmDutyCycle A pointer to the location where the coexistence
* PWM duty cycle value is returned.
* @param[out] aPwmPeriodHalfMs A pointer to the location where the coexistence
* PWM period half MS value is returned.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the PWM configuration.
* @retval OT_ERROR_INVALID_ARGS One or more of the parameters @p aPwmReq,
* @p aPwmDutyCycle, or @p aPwmPeriodHalfMs is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetRequestPwmArgs(uint8_t *aPwmReq, uint8_t *aPwmDutyCycle, uint8_t *aPwmPeriodHalfMs);
/**
* Set the coexistence PWM configuration.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_request_pwm()**
*
* @param[in] aPwmReq The coexistence PWM request. The value is defined
* as a bitmap using shift values from the RAIL
* `COEX_Req_t` enumeration.
* @param[in] aPwmDutyCycle The coexistence PWM duty cycle.
* @param[in] aPwmPeriodHalfMs The coexistencec PWM period half MS.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the PWM configuration.
* @retval OT_ERROR_FAILED The coexistence radio PWM configuration can not be set/\.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetRequestPwmArgs(uint8_t aPwmReq, uint8_t aPwmDutyCycle, uint8_t aPwmPeriodHalfMs);
/**
* Clear the coexistence counters.
*
* Requires the `ot_coex` component.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully cleared the coexistence counters.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented or `SL_OPENTHREAD_COEX_COUNTER_ENABLE`
* is not enabled.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionClearCoexCounters(void);
/**
* Get the coexistence counters.
*
* Requires the `ot_coex` component.
*
* @param[in] aNumEntries The number of entries in @p aCoexCounters
* array where counters will be returned.
* @param[out] aCoexCounters A pointer to an array where the coexistence
* counters will be returned. See @ref
* otPlatRadioExtensionCoexEvent_t which defines
* what coexistence counter each array element stores.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the coexistence counters.
* @retval OT_ERROR_INVALID_ARGS @p aNumEntries is not `OT_PLAT_RADIO_EXTENSION_COEX_EVENT_COUNT`
* or @p aCoexCounters is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented or `SL_OPENTHREAD_COEX_COUNTER_ENABLE`
* is not enabled.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetCoexCounters(uint8_t aNumEntries, uint32_t aCoexCounters[]);
/**
* Set the coexistence radio holdoff status.
*
* Requires the `ot_coex` component.
*
* @sa RAIL API: **sl_rail_util_coex_set_radio_holdoff()**
*
* @param[in] aEnabled The coexistence radio holdoff status.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the coexistence radio holdoff status.
* @retval OT_ERROR_FAILED The coexistence radio holdoff status can not be set.
* @retval OT_ERROR_NOT_IMPLEMENTED Coexistence is not implemented.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetRadioHoldoff(bool aEnabled);
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/**
* Get the PTI (Packet Trace Information) radio config.
*
* Requires the `ot_test_custom_cli` component.
*
* @sa RAIL API: **RAIL_IEEE802154_GetPtiRadioConfig()**
*
* @param[out] aRadioConfig A pointer to the location where the PTI radio
* config will be returned. The value is defined
* by the RAIL `RAIL_IEEE802154_PtiRadioConfig_t`
* enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained the PTI radio config.
* @retval OT_ERROR_INVALID_ARGS The @p aRadioConfig parameter is NULL.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetPtiRadioConfig(uint16_t *aRadioConfig);
/**
* Set the radio CCA mode.
*
* Requires the `ot_test_custom_cli` component.
*
* @sa RAIL API: **RAIL_IEEE802154_ConfigCcaMode()**
*
* @param[in] aMode The CCA mode to set. Modes are defined by the RAIL
* `RAIL_IEEE802154_CcaMode_t` enumeration.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully set the CCA mode.
* @retval OT_ERROR_FAILED The @p aTimeout is invalid.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionSetCcaMode(uint8_t aMode);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
/**
* This enumeration defines the coex event counters and can be used as an
* index into the `aCoexCounters` table returned in a call to
* @ref otPlatRadioExtensionGetCoexCounters.
*
*/
typedef enum
{
/** Low priority request initiated */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_LO_PRI_REQUESTED,
/** High priority request initiated */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_HI_PRI_REQUESTED,
/** Low priority request denied */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_LO_PRI_DENIED,
/** High priority request denied */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_HI_PRI_DENIED,
/** Low priority transmission aborted mid packet */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_LO_PRI_TX_ABORTED,
/** High priority transmission aborted mid packet */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_HI_PRI_TX_ABORTED,
/** Number of coexistence events */
OT_PLAT_RADIO_EXTENSION_COEX_EVENT_COUNT,
} otPlatRadioExtensionCoexEvent_t;
/**
* Get RAIL debug counter values.
*
* Requires the `ot_efr32_custom_cli` component.
*
* @param[out] *aCounters Pointer to struct to store counter values.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully obtained radio counter values.
* @retval OT_ERROR_INVALID_ARGS @p aCounters is NULL.
* @retval OT_ERROR_NOT_IMPLEMENTED RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT is not enabled.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionGetRadioCounters(efr32RadioCounters *aCounters);
/**
* Clear the RAIL debug counters.
*
* Requires the `ot_efr32_custom_cli` component.
*
* @return Error code indicating success of the function call.
*
* @retval OT_ERROR_NONE Successfully cleared radio counter values.
* @retval OT_ERROR_NOT_IMPLEMENTED RADIO_CONFIG_DEBUG_COUNTERS_SUPPORT is not enabled.
* @retval OT_ERROR_NOT_FOUND Returned to host applications when the coprocessor
* is not built with the required component.
*
*/
otError otPlatRadioExtensionClearRadioCounters(void);
/**
* @}
*
*/
/**
* @}
*
*/
#ifdef __cplusplus
}
#endif
#endif // _RADIO_EXTENSION_H

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file defines the APIs required to support multi-channel feature on EFR devices.
*
*/
#ifdef SL_CATALOG_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_PRESENT
#include "sl_rail_util_ieee802154_fast_channel_switching_config.h"
#endif // SL_CATALOG_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_PRESENT
#if SL_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_ENABLED && !defined(SL_CATALOG_RAIL_MULTIPLEXER_PRESENT)
// When RAIL multiplexer is present, we handle fast channel switching in the multiplexer code
// turn off the feature here since OT lower mac is unaware of the goings on in the zigbee stack
#define FAST_CHANNEL_SWITCHING_SUPPORT 1
#else
#define FAST_CHANNEL_SWITCHING_SUPPORT 0
#endif // SL_RAIL_UTIL_IEEE802154_FAST_CHANNEL_SWITCHING_ENABLED && !defined(SL_CATALOG_RAIL_MULTIPLEXER_PRESENT)
/**
* Check if the multi-channel feature is enabled.
*
* @retval true Multi-channel is enabled.
* @retval false Multi-channel is disabled.
*
*/
bool sl_is_multi_channel_enabled(void);
/**
* Get the channel switching configuration.
*
* @param[out] channelSwitchingCfg Pointer to memory to store the switching config into.
*
* @retval OT_ERROR_NONE Channel switching config was copied succesfully.
* @retval OT_ERROR_INVALID_ARGS Argument passed was invalid.
*
*/
otError sl_get_channel_switching_cfg(RAIL_IEEE802154_RxChannelSwitchingCfg_t *channelSwitchingCfg);

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2024, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file defines the APIs required to support multi-channel feature on EFR devices.
*
*/
#include <openthread-system.h>
#include <openthread/link.h>
#include <openthread/platform/radio.h>
#if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
#include <openthread/platform/multipan.h>
#endif
#include "board_config.h"
#include "platform-efr32.h"
#include "sl_common.h"
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/logging.hpp"
#include "utils/code_utils.h"
#define SL_INVALID_TX_POWER (127)
#if RADIO_CONFIG_2P4GHZ_OQPSK_SUPPORT
#define SL_CHANNEL_MAX OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX
#define SL_CHANNEL_MIN OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN
#define SL_MAX_CHANNELS_SUPPORTED ((OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX - OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN) + 1)
#elif RADIO_CONFIG_SUBGHZ_SUPPORT
#define SL_CHANNEL_MAX OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX
#define SL_CHANNEL_MIN OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN
#define SL_MAX_CHANNELS_SUPPORTED \
((OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX \
- OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN) \
+ 1)
#elif RADIO_CONFIG_915MHZ_OQPSK_SUPPORT // Not supported
#define SL_CHANNEL_MAX OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX
#define SL_CHANNEL_MIN OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN
#define SL_MAX_CHANNELS_SUPPORTED ((OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX - OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN) + 1)
#endif
/**
* Set the radio's max tx power for the given channel. THis value is maintained in the device
*
* @note This API is not available when @p OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE is enabled.
*
* @param[in] instance The OpenThread instance structure.
* @param[in] channel Radio channel of interest.
* @param[in] max_power Max Radio Tx power for the given @p channel.
*
* @retval OT_ERROR_NONE Successfully set the max transmit power.
* @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented.
*
*/
otError sli_set_channel_max_tx_power(otInstance *instance, uint8_t channel, int8_t max_power);
/**
* Set the radio tx power in RAIL
*
* @param[in] tx_power Desired tx power in dbm.
*
*/
void sli_set_tx_power_in_rail(int8_t tx_power);
/**
* Update the Tx power following a RAIL config change.
*
* @param[in] tx_power_config Tx power configuration
* @param[in] tx_power Desired tx power in dbm.
*
*/
void sli_update_tx_power_after_config_update(const RAIL_TxPowerConfig_t *tx_power_config, int8_t tx_power);
/**
* Initialize the power manager.
*/
void sli_init_power_manager(void);
/**
* Set Openthreads default power configuration for all the channels.
*
* @note This API is not available when @p OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE is enabled.
*
* @param[in] instance The OpenThread instance structure.
* @param[in] tx_power Desired tx power in dbm.
*
* @retval OT_ERROR_NONE Successfully set the max transmit power.
* @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented.
*
*/
otError sli_set_default_tx_power(otInstance *instance, int8_t tx_power);
/**
* Get the operating Tx power based on all Openthread configurations.
*
* @note When @p OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE is enabled, the device reads the
* calibrated power values from power calibration module in Openthread.
*
* When disabled, the device will look up Max Tx power table and default power configured and select
* the minimum of these values.
*
* In multiprotocol the above operation happens for all IIDs and minimum value of those will be selected.
*
* @param[in] instance The OpenThread instance structure.
*
* @retval The transmit power in dBm.
*
*/
int8_t sl_get_tx_power_for_current_channel(otInstance *instance);
/**
* This is a callback to parse the Raw Power calibration value received from the Openthread stack. A weak
* default implementation is provided in the PAL, which picks the 0th byte of @p raw_power_setting as the
* operating tx power. Application can implement its own parser but the callback is expected to return the
* radio power in dbm and the FEM configuration if any in respective output pointers.
*
* @note This callback is available when @p OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE is enabled.
*
* @param[in] raw_power_calibration Pointer to raw power calibration received from Openthread stack.
* @param[in] raw_setting_length Raw power calibration length.
* @param[out] radio_power Pointer to parsed Radio Power in dbm (for RAIL).
* @param[out] fem_setting Pointer to FEM settings.
* @param[out] fem_setting_length Pointer to length of FEM settings.
*
* @retval OT_ERROR_NONE Successfully set parsed theraw power calibration.
* @retval OT_ERROR_PARSE There was a parsing error.
*
*/
otError sl_parse_raw_power_calibration_cb(uint8_t *raw_power_calibration,
uint16_t raw_setting_length,
int8_t *radio_power,
uint8_t *fem_setting,
uint16_t *fem_setting_length);
/**
* This is a callback to con figure the FEM as required. A weak default implementation is provided in the PAL,
* Application can use its own implementation to configure the FEM based on the values provided.
*
* @note This callback is available when @p OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE is enabled.
*
* @param[in] fem_setting FEM settings.
* @param[in] fem_setting_length Length of FEM settings.
*
*/
void sl_configure_fem_cb(uint8_t *fem_setting, uint16_t fem_setting_length);

View File

@@ -0,0 +1,227 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Backbone Router Ftd APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/backbone_router_ftd.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otBackboneRouterState OT_API_REAL_NAME(otBackboneRouterGetState)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBackboneRouterGetDomainPrefix)(otInstance *aInstance, otBorderRouterConfig *aConfig);
extern otError OT_API_REAL_NAME(otBackboneRouterGetNdProxyInfo)(otInstance *aInstance,
const otIp6Address *aDua,
otBackboneRouterNdProxyInfo *aNdProxyInfo);
extern otError OT_API_REAL_NAME(otBackboneRouterMulticastListenerAdd)(otInstance *aInstance,
const otIp6Address *aAddress,
uint32_t aTimeout);
extern otError OT_API_REAL_NAME(otBackboneRouterMulticastListenerGetNext)(
otInstance *aInstance,
otBackboneRouterMulticastListenerIterator *aIterator,
otBackboneRouterMulticastListenerInfo *aListenerInfo);
extern otError OT_API_REAL_NAME(otBackboneRouterRegister)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBackboneRouterSetConfig)(otInstance *aInstance,
const otBackboneRouterConfig *aConfig);
extern uint8_t OT_API_REAL_NAME(otBackboneRouterGetRegistrationJitter)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBackboneRouterConfigNextDuaRegistrationResponse)(otInstance *aInstance,
const otIp6InterfaceIdentifier *aMlIid,
uint8_t aStatus);
extern void OT_API_REAL_NAME(otBackboneRouterConfigNextMulticastListenerRegistrationResponse)(otInstance *aInstance,
uint8_t aStatus);
extern void OT_API_REAL_NAME(otBackboneRouterGetConfig)(otInstance *aInstance, otBackboneRouterConfig *aConfig);
extern void OT_API_REAL_NAME(otBackboneRouterMulticastListenerClear)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBackboneRouterSetDomainPrefixCallback)(otInstance *aInstance,
otBackboneRouterDomainPrefixCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otBackboneRouterSetEnabled)(otInstance *aInstance, bool aEnable);
extern void OT_API_REAL_NAME(otBackboneRouterSetMulticastListenerCallback)(
otInstance *aInstance,
otBackboneRouterMulticastListenerCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otBackboneRouterSetNdProxyCallback)(otInstance *aInstance,
otBackboneRouterNdProxyCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otBackboneRouterSetRegistrationJitter)(otInstance *aInstance, uint8_t aJitter);
otBackboneRouterState OT_API_WRAPPER_NAME(otBackboneRouterGetState)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otBackboneRouterState ret = OT_API_REAL_NAME(otBackboneRouterGetState)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterGetDomainPrefix)(otInstance *aInstance, otBorderRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterGetDomainPrefix)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterGetNdProxyInfo)(otInstance *aInstance,
const otIp6Address *aDua,
otBackboneRouterNdProxyInfo *aNdProxyInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterGetNdProxyInfo)(aInstance, aDua, aNdProxyInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterMulticastListenerAdd)(otInstance *aInstance,
const otIp6Address *aAddress,
uint32_t aTimeout)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterMulticastListenerAdd)(aInstance, aAddress, aTimeout);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterMulticastListenerGetNext)(
otInstance *aInstance,
otBackboneRouterMulticastListenerIterator *aIterator,
otBackboneRouterMulticastListenerInfo *aListenerInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterMulticastListenerGetNext)(aInstance, aIterator, aListenerInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterRegister)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterRegister)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBackboneRouterSetConfig)(otInstance *aInstance, const otBackboneRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterSetConfig)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint8_t OT_API_WRAPPER_NAME(otBackboneRouterGetRegistrationJitter)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint8_t ret = OT_API_REAL_NAME(otBackboneRouterGetRegistrationJitter)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otBackboneRouterConfigNextDuaRegistrationResponse)(otInstance *aInstance,
const otIp6InterfaceIdentifier *aMlIid,
uint8_t aStatus)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterConfigNextDuaRegistrationResponse)(aInstance, aMlIid, aStatus);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterConfigNextMulticastListenerRegistrationResponse)(otInstance *aInstance,
uint8_t aStatus)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterConfigNextMulticastListenerRegistrationResponse)(aInstance, aStatus);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterGetConfig)(otInstance *aInstance, otBackboneRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterGetConfig)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterMulticastListenerClear)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterMulticastListenerClear)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterSetDomainPrefixCallback)(otInstance *aInstance,
otBackboneRouterDomainPrefixCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterSetDomainPrefixCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterSetEnabled)(otInstance *aInstance, bool aEnable)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterSetEnabled)(aInstance, aEnable);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterSetMulticastListenerCallback)(
otInstance *aInstance,
otBackboneRouterMulticastListenerCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterSetMulticastListenerCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterSetNdProxyCallback)(otInstance *aInstance,
otBackboneRouterNdProxyCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterSetNdProxyCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBackboneRouterSetRegistrationJitter)(otInstance *aInstance, uint8_t aJitter)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBackboneRouterSetRegistrationJitter)(aInstance, aJitter);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,57 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Backbone Router APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/backbone_router.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otError OT_API_REAL_NAME(otBackboneRouterGetPrimary)(otInstance *aInstance, otBackboneRouterConfig *aConfig);
otError OT_API_WRAPPER_NAME(otBackboneRouterGetPrimary)(otInstance *aInstance, otBackboneRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBackboneRouterGetPrimary)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,316 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Ble Secure APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/ble_secure.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otBleSecureGetInstallCodeVerifyStatus)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otBleSecureIsCommandClassAuthorized)(otInstance *aInstance,
otTcatCommandClass aCommandClass);
extern bool OT_API_REAL_NAME(otBleSecureIsConnected)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otBleSecureIsConnectionActive)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otBleSecureIsTcatEnabled)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBleSecureConnect)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBleSecureFlush)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBleSecureGetPeerCertificateBase64)(otInstance *aInstance,
unsigned char *aPeerCert,
size_t *aCertLength);
extern otError OT_API_REAL_NAME(otBleSecureGetPeerSubjectAttributeByOid)(otInstance *aInstance,
const char *aOid,
size_t aOidLength,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength,
int *aAsn1Type);
extern otError OT_API_REAL_NAME(otBleSecureGetThreadAttributeFromOwnCertificate)(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength);
extern otError OT_API_REAL_NAME(otBleSecureGetThreadAttributeFromPeerCertificate)(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength);
extern otError OT_API_REAL_NAME(otBleSecureSend)(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength);
extern otError OT_API_REAL_NAME(otBleSecureSendApplicationTlv)(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength);
extern otError OT_API_REAL_NAME(otBleSecureSendMessage)(otInstance *aInstance, otMessage *aMessage);
extern otError OT_API_REAL_NAME(otBleSecureSetTcatVendorInfo)(otInstance *aInstance,
const otTcatVendorInfo *aVendorInfo);
extern otError OT_API_REAL_NAME(otBleSecureStart)(otInstance *aInstance,
otHandleBleSecureConnect aConnectHandler,
otHandleBleSecureReceive aReceiveHandler,
bool aTlvMode,
void *aContext);
extern otError OT_API_REAL_NAME(otBleSecureTcatStart)(otInstance *aInstance, otHandleTcatJoin aHandler);
extern void OT_API_REAL_NAME(otBleSecureDisconnect)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBleSecureSetCaCertificateChain)(otInstance *aInstance,
const uint8_t *aX509CaCertificateChain,
uint32_t aX509CaCertChainLength);
extern void OT_API_REAL_NAME(otBleSecureSetCertificate)(otInstance *aInstance,
const uint8_t *aX509Cert,
uint32_t aX509Length,
const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength);
extern void OT_API_REAL_NAME(otBleSecureSetPsk)(otInstance *aInstance,
const uint8_t *aPsk,
uint16_t aPskLength,
const uint8_t *aPskIdentity,
uint16_t aPskIdLength);
extern void OT_API_REAL_NAME(otBleSecureSetSslAuthMode)(otInstance *aInstance, bool aVerifyPeerCertificate);
extern void OT_API_REAL_NAME(otBleSecureStop)(otInstance *aInstance);
bool OT_API_WRAPPER_NAME(otBleSecureGetInstallCodeVerifyStatus)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBleSecureGetInstallCodeVerifyStatus)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otBleSecureIsCommandClassAuthorized)(otInstance *aInstance, otTcatCommandClass aCommandClass)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBleSecureIsCommandClassAuthorized)(aInstance, aCommandClass);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otBleSecureIsConnected)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBleSecureIsConnected)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otBleSecureIsConnectionActive)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBleSecureIsConnectionActive)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otBleSecureIsTcatEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBleSecureIsTcatEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureConnect)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureConnect)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureFlush)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureFlush)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureGetPeerCertificateBase64)(otInstance *aInstance,
unsigned char *aPeerCert,
size_t *aCertLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureGetPeerCertificateBase64)(aInstance, aPeerCert, aCertLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureGetPeerSubjectAttributeByOid)(otInstance *aInstance,
const char *aOid,
size_t aOidLength,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength,
int *aAsn1Type)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureGetPeerSubjectAttributeByOid)(aInstance,
aOid,
aOidLength,
aAttributeBuffer,
aAttributeLength,
aAsn1Type);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureGetThreadAttributeFromOwnCertificate)(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureGetThreadAttributeFromOwnCertificate)(aInstance,
aThreadOidDescriptor,
aAttributeBuffer,
aAttributeLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureGetThreadAttributeFromPeerCertificate)(otInstance *aInstance,
int aThreadOidDescriptor,
uint8_t *aAttributeBuffer,
size_t *aAttributeLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureGetThreadAttributeFromPeerCertificate)(aInstance,
aThreadOidDescriptor,
aAttributeBuffer,
aAttributeLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureSend)(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureSend)(aInstance, aBuf, aLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureSendApplicationTlv)(otInstance *aInstance, uint8_t *aBuf, uint16_t aLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureSendApplicationTlv)(aInstance, aBuf, aLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureSendMessage)(otInstance *aInstance, otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureSendMessage)(aInstance, aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureSetTcatVendorInfo)(otInstance *aInstance, const otTcatVendorInfo *aVendorInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureSetTcatVendorInfo)(aInstance, aVendorInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureStart)(otInstance *aInstance,
otHandleBleSecureConnect aConnectHandler,
otHandleBleSecureReceive aReceiveHandler,
bool aTlvMode,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureStart)(aInstance, aConnectHandler, aReceiveHandler, aTlvMode, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBleSecureTcatStart)(otInstance *aInstance, otHandleTcatJoin aHandler)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBleSecureTcatStart)(aInstance, aHandler);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otBleSecureDisconnect)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureDisconnect)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBleSecureSetCaCertificateChain)(otInstance *aInstance,
const uint8_t *aX509CaCertificateChain,
uint32_t aX509CaCertChainLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureSetCaCertificateChain)(aInstance, aX509CaCertificateChain, aX509CaCertChainLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBleSecureSetCertificate)(otInstance *aInstance,
const uint8_t *aX509Cert,
uint32_t aX509Length,
const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureSetCertificate)(aInstance, aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBleSecureSetPsk)(otInstance *aInstance,
const uint8_t *aPsk,
uint16_t aPskLength,
const uint8_t *aPskIdentity,
uint16_t aPskIdLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureSetPsk)(aInstance, aPsk, aPskLength, aPskIdentity, aPskIdLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBleSecureSetSslAuthMode)(otInstance *aInstance, bool aVerifyPeerCertificate)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureSetSslAuthMode)(aInstance, aVerifyPeerCertificate);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBleSecureStop)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBleSecureStop)(aInstance);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,145 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Border Agent APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/border_agent.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otBorderAgentIsEphemeralKeyActive)(otInstance *aInstance);
extern const otBorderAgentCounters *OT_API_REAL_NAME(otBorderAgentGetCounters)(otInstance *aInstance);
extern otBorderAgentState OT_API_REAL_NAME(otBorderAgentGetState)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBorderAgentGetId)(otInstance *aInstance, otBorderAgentId *aId);
extern otError OT_API_REAL_NAME(otBorderAgentSetEphemeralKey)(otInstance *aInstance,
const char *aKeyString,
uint32_t aTimeout,
uint16_t aUdpPort);
extern otError OT_API_REAL_NAME(otBorderAgentSetId)(otInstance *aInstance, const otBorderAgentId *aId);
extern uint16_t OT_API_REAL_NAME(otBorderAgentGetUdpPort)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBorderAgentClearEphemeralKey)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBorderAgentDisconnect)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBorderAgentSetEphemeralKeyCallback)(otInstance *aInstance,
otBorderAgentEphemeralKeyCallback aCallback,
void *aContext);
bool OT_API_WRAPPER_NAME(otBorderAgentIsEphemeralKeyActive)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otBorderAgentIsEphemeralKeyActive)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otBorderAgentCounters *OT_API_WRAPPER_NAME(otBorderAgentGetCounters)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
const otBorderAgentCounters *ret = OT_API_REAL_NAME(otBorderAgentGetCounters)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otBorderAgentState OT_API_WRAPPER_NAME(otBorderAgentGetState)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otBorderAgentState ret = OT_API_REAL_NAME(otBorderAgentGetState)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderAgentGetId)(otInstance *aInstance, otBorderAgentId *aId)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderAgentGetId)(aInstance, aId);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderAgentSetEphemeralKey)(otInstance *aInstance,
const char *aKeyString,
uint32_t aTimeout,
uint16_t aUdpPort)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderAgentSetEphemeralKey)(aInstance, aKeyString, aTimeout, aUdpPort);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderAgentSetId)(otInstance *aInstance, const otBorderAgentId *aId)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderAgentSetId)(aInstance, aId);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otBorderAgentGetUdpPort)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otBorderAgentGetUdpPort)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otBorderAgentClearEphemeralKey)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderAgentClearEphemeralKey)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderAgentDisconnect)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderAgentDisconnect)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderAgentSetEphemeralKeyCallback)(otInstance *aInstance,
otBorderAgentEphemeralKeyCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderAgentSetEphemeralKeyCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,147 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Border Router APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/border_router.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otError OT_API_REAL_NAME(otBorderRouterAddOnMeshPrefix)(otInstance *aInstance,
const otBorderRouterConfig *aConfig);
extern otError OT_API_REAL_NAME(otBorderRouterAddRoute)(otInstance *aInstance, const otExternalRouteConfig *aConfig);
extern otError OT_API_REAL_NAME(otBorderRouterGetNetData)(otInstance *aInstance,
bool aStable,
uint8_t *aData,
uint8_t *aDataLength);
extern otError OT_API_REAL_NAME(otBorderRouterGetNextOnMeshPrefix)(otInstance *aInstance,
otNetworkDataIterator *aIterator,
otBorderRouterConfig *aConfig);
extern otError OT_API_REAL_NAME(otBorderRouterGetNextRoute)(otInstance *aInstance,
otNetworkDataIterator *aIterator,
otExternalRouteConfig *aConfig);
extern otError OT_API_REAL_NAME(otBorderRouterRegister)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBorderRouterRemoveOnMeshPrefix)(otInstance *aInstance, const otIp6Prefix *aPrefix);
extern otError OT_API_REAL_NAME(otBorderRouterRemoveRoute)(otInstance *aInstance, const otIp6Prefix *aPrefix);
extern void OT_API_REAL_NAME(otBorderRouterSetNetDataFullCallback)(otInstance *aInstance,
otBorderRouterNetDataFullCallback aCallback,
void *aContext);
otError OT_API_WRAPPER_NAME(otBorderRouterAddOnMeshPrefix)(otInstance *aInstance, const otBorderRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterAddOnMeshPrefix)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterAddRoute)(otInstance *aInstance, const otExternalRouteConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterAddRoute)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterGetNetData)(otInstance *aInstance,
bool aStable,
uint8_t *aData,
uint8_t *aDataLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterGetNetData)(aInstance, aStable, aData, aDataLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterGetNextOnMeshPrefix)(otInstance *aInstance,
otNetworkDataIterator *aIterator,
otBorderRouterConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterGetNextOnMeshPrefix)(aInstance, aIterator, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterGetNextRoute)(otInstance *aInstance,
otNetworkDataIterator *aIterator,
otExternalRouteConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterGetNextRoute)(aInstance, aIterator, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterRegister)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterRegister)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterRemoveOnMeshPrefix)(otInstance *aInstance, const otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterRemoveOnMeshPrefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRouterRemoveRoute)(otInstance *aInstance, const otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRouterRemoveRoute)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otBorderRouterSetNetDataFullCallback)(otInstance *aInstance,
otBorderRouterNetDataFullCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRouterSetNetDataFullCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,321 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Border Routing APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/border_routing.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otBorderRoutingDhcp6PdState OT_API_REAL_NAME(otBorderRoutingDhcp6PdGetState)(otInstance *aInstance);
extern otBorderRoutingState OT_API_REAL_NAME(otBorderRoutingGetState)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otBorderRoutingGetFavoredNat64Prefix)(otInstance *aInstance,
otIp6Prefix *aPrefix,
otRoutePreference *aPreference);
extern otError OT_API_REAL_NAME(otBorderRoutingGetFavoredOmrPrefix)(otInstance *aInstance,
otIp6Prefix *aPrefix,
otRoutePreference *aPreference);
extern otError OT_API_REAL_NAME(otBorderRoutingGetFavoredOnLinkPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix);
extern otError OT_API_REAL_NAME(otBorderRoutingGetNat64Prefix)(otInstance *aInstance, otIp6Prefix *aPrefix);
extern otError OT_API_REAL_NAME(otBorderRoutingGetNextPeerBrEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingPeerBorderRouterEntry *aEntry);
extern otError OT_API_REAL_NAME(otBorderRoutingGetNextPrefixTableEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingPrefixTableEntry *aEntry);
extern otError OT_API_REAL_NAME(otBorderRoutingGetNextRouterEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingRouterEntry *aEntry);
extern otError OT_API_REAL_NAME(otBorderRoutingGetOmrPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix);
extern otError OT_API_REAL_NAME(otBorderRoutingGetOnLinkPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix);
extern otError OT_API_REAL_NAME(otBorderRoutingGetPdOmrPrefix)(otInstance *aInstance,
otBorderRoutingPrefixTableEntry *aPrefixInfo);
extern otError OT_API_REAL_NAME(otBorderRoutingGetPdProcessedRaInfo)(otInstance *aInstance,
otPdProcessedRaInfo *aPdProcessedRaInfo);
extern otError OT_API_REAL_NAME(otBorderRoutingInit)(otInstance *aInstance,
uint32_t aInfraIfIndex,
bool aInfraIfIsRunning);
extern otError OT_API_REAL_NAME(otBorderRoutingSetEnabled)(otInstance *aInstance, bool aEnabled);
extern otError OT_API_REAL_NAME(otBorderRoutingSetExtraRouterAdvertOptions)(otInstance *aInstance,
const uint8_t *aOptions,
uint16_t aLength);
extern otRoutePreference OT_API_REAL_NAME(otBorderRoutingGetRouteInfoOptionPreference)(otInstance *aInstance);
extern otRoutePreference OT_API_REAL_NAME(otBorderRoutingGetRoutePreference)(otInstance *aInstance);
extern uint16_t OT_API_REAL_NAME(otBorderRoutingCountPeerBrs)(otInstance *aInstance, uint32_t *aMinAge);
extern void OT_API_REAL_NAME(otBorderRoutingClearRouteInfoOptionPreference)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBorderRoutingClearRoutePreference)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otBorderRoutingDhcp6PdSetEnabled)(otInstance *aInstance, bool aEnabled);
extern void OT_API_REAL_NAME(otBorderRoutingDhcp6PdSetRequestCallback)(otInstance *aInstance,
otBorderRoutingRequestDhcp6PdCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otBorderRoutingPrefixTableInitIterator)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator);
extern void OT_API_REAL_NAME(otBorderRoutingSetOnLinkPrefix)(otInstance *aInstance, const otIp6Prefix *aPrefix);
extern void OT_API_REAL_NAME(otBorderRoutingSetRouteInfoOptionPreference)(otInstance *aInstance,
otRoutePreference aPreference);
extern void OT_API_REAL_NAME(otBorderRoutingSetRoutePreference)(otInstance *aInstance, otRoutePreference aPreference);
otBorderRoutingDhcp6PdState OT_API_WRAPPER_NAME(otBorderRoutingDhcp6PdGetState)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otBorderRoutingDhcp6PdState ret = OT_API_REAL_NAME(otBorderRoutingDhcp6PdGetState)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otBorderRoutingState OT_API_WRAPPER_NAME(otBorderRoutingGetState)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otBorderRoutingState ret = OT_API_REAL_NAME(otBorderRoutingGetState)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetFavoredNat64Prefix)(otInstance *aInstance,
otIp6Prefix *aPrefix,
otRoutePreference *aPreference)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetFavoredNat64Prefix)(aInstance, aPrefix, aPreference);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetFavoredOmrPrefix)(otInstance *aInstance,
otIp6Prefix *aPrefix,
otRoutePreference *aPreference)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetFavoredOmrPrefix)(aInstance, aPrefix, aPreference);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetFavoredOnLinkPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetFavoredOnLinkPrefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetNat64Prefix)(otInstance *aInstance, otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetNat64Prefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetNextPeerBrEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingPeerBorderRouterEntry *aEntry)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetNextPeerBrEntry)(aInstance, aIterator, aEntry);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetNextPrefixTableEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingPrefixTableEntry *aEntry)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetNextPrefixTableEntry)(aInstance, aIterator, aEntry);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetNextRouterEntry)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator,
otBorderRoutingRouterEntry *aEntry)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetNextRouterEntry)(aInstance, aIterator, aEntry);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetOmrPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetOmrPrefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetOnLinkPrefix)(otInstance *aInstance, otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetOnLinkPrefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetPdOmrPrefix)(otInstance *aInstance,
otBorderRoutingPrefixTableEntry *aPrefixInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetPdOmrPrefix)(aInstance, aPrefixInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingGetPdProcessedRaInfo)(otInstance *aInstance,
otPdProcessedRaInfo *aPdProcessedRaInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingGetPdProcessedRaInfo)(aInstance, aPdProcessedRaInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingInit)(otInstance *aInstance, uint32_t aInfraIfIndex, bool aInfraIfIsRunning)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingInit)(aInstance, aInfraIfIndex, aInfraIfIsRunning);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingSetEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingSetEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otBorderRoutingSetExtraRouterAdvertOptions)(otInstance *aInstance,
const uint8_t *aOptions,
uint16_t aLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otBorderRoutingSetExtraRouterAdvertOptions)(aInstance, aOptions, aLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otRoutePreference OT_API_WRAPPER_NAME(otBorderRoutingGetRouteInfoOptionPreference)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otRoutePreference ret = OT_API_REAL_NAME(otBorderRoutingGetRouteInfoOptionPreference)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otRoutePreference OT_API_WRAPPER_NAME(otBorderRoutingGetRoutePreference)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otRoutePreference ret = OT_API_REAL_NAME(otBorderRoutingGetRoutePreference)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otBorderRoutingCountPeerBrs)(otInstance *aInstance, uint32_t *aMinAge)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otBorderRoutingCountPeerBrs)(aInstance, aMinAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otBorderRoutingClearRouteInfoOptionPreference)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingClearRouteInfoOptionPreference)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingClearRoutePreference)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingClearRoutePreference)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingDhcp6PdSetEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingDhcp6PdSetEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingDhcp6PdSetRequestCallback)(otInstance *aInstance,
otBorderRoutingRequestDhcp6PdCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingDhcp6PdSetRequestCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingPrefixTableInitIterator)(otInstance *aInstance,
otBorderRoutingPrefixTableIterator *aIterator)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingPrefixTableInitIterator)(aInstance, aIterator);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingSetOnLinkPrefix)(otInstance *aInstance, const otIp6Prefix *aPrefix)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingSetOnLinkPrefix)(aInstance, aPrefix);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingSetRouteInfoOptionPreference)(otInstance *aInstance,
otRoutePreference aPreference)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingSetRouteInfoOptionPreference)(aInstance, aPreference);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otBorderRoutingSetRoutePreference)(otInstance *aInstance, otRoutePreference aPreference)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otBorderRoutingSetRoutePreference)(aInstance, aPreference);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,205 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Channel Manager APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/channel_manager.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otChannelManagerGetAutoChannelSelectionEnabled)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otChannelManagerGetAutoCslChannelSelectionEnabled)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otChannelManagerRequestChannelSelect)(otInstance *aInstance, bool aSkipQualityCheck);
extern otError OT_API_REAL_NAME(otChannelManagerRequestCslChannelSelect)(otInstance *aInstance, bool aSkipQualityCheck);
extern otError OT_API_REAL_NAME(otChannelManagerSetAutoChannelSelectionInterval)(otInstance *aInstance,
uint32_t aInterval);
extern otError OT_API_REAL_NAME(otChannelManagerSetDelay)(otInstance *aInstance, uint16_t aDelay);
extern uint16_t OT_API_REAL_NAME(otChannelManagerGetCcaFailureRateThreshold)(otInstance *aInstance);
extern uint16_t OT_API_REAL_NAME(otChannelManagerGetDelay)(otInstance *aInstance);
extern uint32_t OT_API_REAL_NAME(otChannelManagerGetAutoChannelSelectionInterval)(otInstance *aInstance);
extern uint32_t OT_API_REAL_NAME(otChannelManagerGetFavoredChannels)(otInstance *aInstance);
extern uint32_t OT_API_REAL_NAME(otChannelManagerGetSupportedChannels)(otInstance *aInstance);
extern uint8_t OT_API_REAL_NAME(otChannelManagerGetRequestedChannel)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otChannelManagerRequestChannelChange)(otInstance *aInstance, uint8_t aChannel);
extern void OT_API_REAL_NAME(otChannelManagerSetAutoChannelSelectionEnabled)(otInstance *aInstance, bool aEnabled);
extern void OT_API_REAL_NAME(otChannelManagerSetAutoCslChannelSelectionEnabled)(otInstance *aInstance, bool aEnabled);
extern void OT_API_REAL_NAME(otChannelManagerSetCcaFailureRateThreshold)(otInstance *aInstance, uint16_t aThreshold);
extern void OT_API_REAL_NAME(otChannelManagerSetFavoredChannels)(otInstance *aInstance, uint32_t aChannelMask);
extern void OT_API_REAL_NAME(otChannelManagerSetSupportedChannels)(otInstance *aInstance, uint32_t aChannelMask);
bool OT_API_WRAPPER_NAME(otChannelManagerGetAutoChannelSelectionEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otChannelManagerGetAutoChannelSelectionEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otChannelManagerGetAutoCslChannelSelectionEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otChannelManagerGetAutoCslChannelSelectionEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otChannelManagerRequestChannelSelect)(otInstance *aInstance, bool aSkipQualityCheck)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otChannelManagerRequestChannelSelect)(aInstance, aSkipQualityCheck);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otChannelManagerRequestCslChannelSelect)(otInstance *aInstance, bool aSkipQualityCheck)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otChannelManagerRequestCslChannelSelect)(aInstance, aSkipQualityCheck);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otChannelManagerSetAutoChannelSelectionInterval)(otInstance *aInstance, uint32_t aInterval)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otChannelManagerSetAutoChannelSelectionInterval)(aInstance, aInterval);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otChannelManagerSetDelay)(otInstance *aInstance, uint16_t aDelay)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otChannelManagerSetDelay)(aInstance, aDelay);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otChannelManagerGetCcaFailureRateThreshold)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChannelManagerGetCcaFailureRateThreshold)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otChannelManagerGetDelay)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChannelManagerGetDelay)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelManagerGetAutoChannelSelectionInterval)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelManagerGetAutoChannelSelectionInterval)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelManagerGetFavoredChannels)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelManagerGetFavoredChannels)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelManagerGetSupportedChannels)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelManagerGetSupportedChannels)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint8_t OT_API_WRAPPER_NAME(otChannelManagerGetRequestedChannel)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint8_t ret = OT_API_REAL_NAME(otChannelManagerGetRequestedChannel)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otChannelManagerRequestChannelChange)(otInstance *aInstance, uint8_t aChannel)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerRequestChannelChange)(aInstance, aChannel);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChannelManagerSetAutoChannelSelectionEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerSetAutoChannelSelectionEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChannelManagerSetAutoCslChannelSelectionEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerSetAutoCslChannelSelectionEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChannelManagerSetCcaFailureRateThreshold)(otInstance *aInstance, uint16_t aThreshold)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerSetCcaFailureRateThreshold)(aInstance, aThreshold);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChannelManagerSetFavoredChannels)(otInstance *aInstance, uint32_t aChannelMask)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerSetFavoredChannels)(aInstance, aChannelMask);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChannelManagerSetSupportedChannels)(otInstance *aInstance, uint32_t aChannelMask)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChannelManagerSetSupportedChannels)(aInstance, aChannelMask);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,111 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Channel Monitor APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/channel_monitor.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otChannelMonitorIsEnabled)(otInstance *aInstance);
extern int8_t OT_API_REAL_NAME(otChannelMonitorGetRssiThreshold)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otChannelMonitorSetEnabled)(otInstance *aInstance, bool aEnabled);
extern uint16_t OT_API_REAL_NAME(otChannelMonitorGetChannelOccupancy)(otInstance *aInstance, uint8_t aChannel);
extern uint32_t OT_API_REAL_NAME(otChannelMonitorGetSampleCount)(otInstance *aInstance);
extern uint32_t OT_API_REAL_NAME(otChannelMonitorGetSampleInterval)(otInstance *aInstance);
extern uint32_t OT_API_REAL_NAME(otChannelMonitorGetSampleWindow)(otInstance *aInstance);
bool OT_API_WRAPPER_NAME(otChannelMonitorIsEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otChannelMonitorIsEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
int8_t OT_API_WRAPPER_NAME(otChannelMonitorGetRssiThreshold)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
int8_t ret = OT_API_REAL_NAME(otChannelMonitorGetRssiThreshold)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otChannelMonitorSetEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otChannelMonitorSetEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otChannelMonitorGetChannelOccupancy)(otInstance *aInstance, uint8_t aChannel)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChannelMonitorGetChannelOccupancy)(aInstance, aChannel);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelMonitorGetSampleCount)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelMonitorGetSampleCount)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelMonitorGetSampleInterval)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelMonitorGetSampleInterval)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otChannelMonitorGetSampleWindow)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otChannelMonitorGetSampleWindow)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,99 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Child Supervision APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/child_supervision.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern uint16_t OT_API_REAL_NAME(otChildSupervisionGetCheckFailureCounter)(otInstance *aInstance);
extern uint16_t OT_API_REAL_NAME(otChildSupervisionGetCheckTimeout)(otInstance *aInstance);
extern uint16_t OT_API_REAL_NAME(otChildSupervisionGetInterval)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otChildSupervisionResetCheckFailureCounter)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otChildSupervisionSetCheckTimeout)(otInstance *aInstance, uint16_t aTimeout);
extern void OT_API_REAL_NAME(otChildSupervisionSetInterval)(otInstance *aInstance, uint16_t aInterval);
uint16_t OT_API_WRAPPER_NAME(otChildSupervisionGetCheckFailureCounter)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChildSupervisionGetCheckFailureCounter)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otChildSupervisionGetCheckTimeout)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChildSupervisionGetCheckTimeout)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otChildSupervisionGetInterval)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otChildSupervisionGetInterval)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otChildSupervisionResetCheckFailureCounter)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChildSupervisionResetCheckFailureCounter)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChildSupervisionSetCheckTimeout)(otInstance *aInstance, uint16_t aTimeout)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChildSupervisionSetCheckTimeout)(aInstance, aTimeout);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otChildSupervisionSetInterval)(otInstance *aInstance, uint16_t aInterval)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otChildSupervisionSetInterval)(aInstance, aInterval);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,84 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Cli APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/cli.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otError OT_API_REAL_NAME(otCliSetUserCommands)(const otCliCommand *aUserCommands,
uint8_t aLength,
void *aContext);
extern void OT_API_REAL_NAME(otCliInit)(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
extern void OT_API_REAL_NAME(otCliInputLine)(char *aBuf);
extern int OT_API_REAL_NAME(CliUartOutput)(void *aContext, const char *aFormat, va_list aArguments);
otError OT_API_WRAPPER_NAME(otCliSetUserCommands)(const otCliCommand *aUserCommands, uint8_t aLength, void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCliSetUserCommands)(aUserCommands, aLength, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otCliInit)(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCliInit)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCliInputLine)(char *aBuf)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCliInputLine)(aBuf);
sl_ot_rtos_release_stack_mutex();
}
int OT_API_WRAPPER_NAME(CliUartOutput)(void *aContext, const char *aFormat, va_list aArguments)
{
sl_ot_rtos_acquire_stack_mutex();
int ret = OT_API_REAL_NAME(CliUartOutput)(aContext, aFormat, aArguments);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,325 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Coap Secure APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/coap_secure.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otCoapSecureIsClosed)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otCoapSecureIsConnected)(otInstance *aInstance);
extern bool OT_API_REAL_NAME(otCoapSecureIsConnectionActive)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otCoapSecureConnect)(otInstance *aInstance,
const otSockAddr *aSockAddr,
otHandleCoapSecureClientConnect aHandler,
void *aContext);
extern otError OT_API_REAL_NAME(otCoapSecureGetPeerCertificateBase64)(otInstance *aInstance,
unsigned char *aPeerCert,
size_t *aCertLength,
size_t aCertBufferSize);
extern otError OT_API_REAL_NAME(otCoapSecureSendRequest)(otInstance *aInstance,
otMessage *aMessage,
otCoapResponseHandler aHandler,
void *aContext);
extern otError OT_API_REAL_NAME(otCoapSecureSendRequestBlockWise)(otInstance *aInstance,
otMessage *aMessage,
otCoapResponseHandler aHandler,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook,
otCoapBlockwiseReceiveHook aReceiveHook);
extern otError OT_API_REAL_NAME(otCoapSecureSendResponse)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo);
extern otError OT_API_REAL_NAME(otCoapSecureSendResponseBlockWise)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook);
extern otError OT_API_REAL_NAME(otCoapSecureStart)(otInstance *aInstance, uint16_t aPort);
extern otError OT_API_REAL_NAME(otCoapSecureStartWithMaxConnAttempts)(otInstance *aInstance,
uint16_t aPort,
uint16_t aMaxAttempts,
otCoapSecureAutoStopCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otCoapSecureAddBlockWiseResource)(otInstance *aInstance,
otCoapBlockwiseResource *aResource);
extern void OT_API_REAL_NAME(otCoapSecureAddResource)(otInstance *aInstance, otCoapResource *aResource);
extern void OT_API_REAL_NAME(otCoapSecureDisconnect)(otInstance *aInstance);
extern void OT_API_REAL_NAME(otCoapSecureRemoveBlockWiseResource)(otInstance *aInstance,
otCoapBlockwiseResource *aResource);
extern void OT_API_REAL_NAME(otCoapSecureRemoveResource)(otInstance *aInstance, otCoapResource *aResource);
extern void OT_API_REAL_NAME(otCoapSecureSetCaCertificateChain)(otInstance *aInstance,
const uint8_t *aX509CaCertificateChain,
uint32_t aX509CaCertChainLength);
extern void OT_API_REAL_NAME(otCoapSecureSetCertificate)(otInstance *aInstance,
const uint8_t *aX509Cert,
uint32_t aX509Length,
const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength);
extern void OT_API_REAL_NAME(otCoapSecureSetClientConnectEventCallback)(otInstance *aInstance,
otHandleCoapSecureClientConnect aHandler,
void *aContext);
extern void OT_API_REAL_NAME(otCoapSecureSetDefaultHandler)(otInstance *aInstance,
otCoapRequestHandler aHandler,
void *aContext);
extern void OT_API_REAL_NAME(otCoapSecureSetPsk)(otInstance *aInstance,
const uint8_t *aPsk,
uint16_t aPskLength,
const uint8_t *aPskIdentity,
uint16_t aPskIdLength);
extern void OT_API_REAL_NAME(otCoapSecureSetSslAuthMode)(otInstance *aInstance, bool aVerifyPeerCertificate);
extern void OT_API_REAL_NAME(otCoapSecureStop)(otInstance *aInstance);
bool OT_API_WRAPPER_NAME(otCoapSecureIsClosed)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otCoapSecureIsClosed)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otCoapSecureIsConnected)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otCoapSecureIsConnected)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
bool OT_API_WRAPPER_NAME(otCoapSecureIsConnectionActive)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otCoapSecureIsConnectionActive)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureConnect)(otInstance *aInstance,
const otSockAddr *aSockAddr,
otHandleCoapSecureClientConnect aHandler,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSecureConnect)(aInstance, aSockAddr, aHandler, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureGetPeerCertificateBase64)(otInstance *aInstance,
unsigned char *aPeerCert,
size_t *aCertLength,
size_t aCertBufferSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otCoapSecureGetPeerCertificateBase64)(aInstance, aPeerCert, aCertLength, aCertBufferSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureSendRequest)(otInstance *aInstance,
otMessage *aMessage,
otCoapResponseHandler aHandler,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSecureSendRequest)(aInstance, aMessage, aHandler, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureSendRequestBlockWise)(otInstance *aInstance,
otMessage *aMessage,
otCoapResponseHandler aHandler,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook,
otCoapBlockwiseReceiveHook aReceiveHook)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(
otCoapSecureSendRequestBlockWise)(aInstance, aMessage, aHandler, aContext, aTransmitHook, aReceiveHook);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureSendResponse)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSecureSendResponse)(aInstance, aMessage, aMessageInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureSendResponseBlockWise)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otCoapSecureSendResponseBlockWise)(aInstance, aMessage, aMessageInfo, aContext, aTransmitHook);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureStart)(otInstance *aInstance, uint16_t aPort)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSecureStart)(aInstance, aPort);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSecureStartWithMaxConnAttempts)(otInstance *aInstance,
uint16_t aPort,
uint16_t aMaxAttempts,
otCoapSecureAutoStopCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otCoapSecureStartWithMaxConnAttempts)(aInstance, aPort, aMaxAttempts, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otCoapSecureAddBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureAddBlockWiseResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureAddResource)(otInstance *aInstance, otCoapResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureAddResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureDisconnect)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureDisconnect)(aInstance);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureRemoveBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureRemoveBlockWiseResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureRemoveResource)(otInstance *aInstance, otCoapResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureRemoveResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetCaCertificateChain)(otInstance *aInstance,
const uint8_t *aX509CaCertificateChain,
uint32_t aX509CaCertChainLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetCaCertificateChain)(aInstance, aX509CaCertificateChain, aX509CaCertChainLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetCertificate)(otInstance *aInstance,
const uint8_t *aX509Cert,
uint32_t aX509Length,
const uint8_t *aPrivateKey,
uint32_t aPrivateKeyLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetCertificate)(aInstance, aX509Cert, aX509Length, aPrivateKey, aPrivateKeyLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetClientConnectEventCallback)(otInstance *aInstance,
otHandleCoapSecureClientConnect aHandler,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetClientConnectEventCallback)(aInstance, aHandler, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetDefaultHandler)(otInstance *aInstance,
otCoapRequestHandler aHandler,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetDefaultHandler)(aInstance, aHandler, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetPsk)(otInstance *aInstance,
const uint8_t *aPsk,
uint16_t aPskLength,
const uint8_t *aPskIdentity,
uint16_t aPskIdLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetPsk)(aInstance, aPsk, aPskLength, aPskIdentity, aPskIdLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureSetSslAuthMode)(otInstance *aInstance, bool aVerifyPeerCertificate)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureSetSslAuthMode)(aInstance, aVerifyPeerCertificate);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSecureStop)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSecureStop)(aInstance);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,515 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Coap APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/coap.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern const char *OT_API_REAL_NAME(otCoapMessageCodeToString)(const otMessage *aMessage);
extern const otCoapOption *OT_API_REAL_NAME(otCoapOptionIteratorGetFirstOption)(otCoapOptionIterator *aIterator);
extern const otCoapOption *OT_API_REAL_NAME(otCoapOptionIteratorGetFirstOptionMatching)(otCoapOptionIterator *aIterator,
uint16_t aOption);
extern const otCoapOption *OT_API_REAL_NAME(otCoapOptionIteratorGetNextOption)(otCoapOptionIterator *aIterator);
extern const otCoapOption *OT_API_REAL_NAME(otCoapOptionIteratorGetNextOptionMatching)(otCoapOptionIterator *aIterator,
uint16_t aOption);
extern const uint8_t *OT_API_REAL_NAME(otCoapMessageGetToken)(const otMessage *aMessage);
extern otCoapCode OT_API_REAL_NAME(otCoapMessageGetCode)(const otMessage *aMessage);
extern otCoapType OT_API_REAL_NAME(otCoapMessageGetType)(const otMessage *aMessage);
extern otError OT_API_REAL_NAME(otCoapMessageAppendBlock1Option)(otMessage *aMessage,
uint32_t aNum,
bool aMore,
otCoapBlockSzx aSize);
extern otError OT_API_REAL_NAME(otCoapMessageAppendBlock2Option)(otMessage *aMessage,
uint32_t aNum,
bool aMore,
otCoapBlockSzx aSize);
extern otError OT_API_REAL_NAME(otCoapMessageAppendContentFormatOption)(otMessage *aMessage,
otCoapOptionContentFormat aContentFormat);
extern otError OT_API_REAL_NAME(otCoapMessageAppendMaxAgeOption)(otMessage *aMessage, uint32_t aMaxAge);
extern otError OT_API_REAL_NAME(otCoapMessageAppendObserveOption)(otMessage *aMessage, uint32_t aObserve);
extern otError OT_API_REAL_NAME(otCoapMessageAppendOption)(otMessage *aMessage,
uint16_t aNumber,
uint16_t aLength,
const void *aValue);
extern otError OT_API_REAL_NAME(otCoapMessageAppendProxyUriOption)(otMessage *aMessage, const char *aUriPath);
extern otError OT_API_REAL_NAME(otCoapMessageAppendUintOption)(otMessage *aMessage, uint16_t aNumber, uint32_t aValue);
extern otError OT_API_REAL_NAME(otCoapMessageAppendUriPathOptions)(otMessage *aMessage, const char *aUriPath);
extern otError OT_API_REAL_NAME(otCoapMessageAppendUriQueryOption)(otMessage *aMessage, const char *aUriQuery);
extern otError OT_API_REAL_NAME(otCoapMessageAppendUriQueryOptions)(otMessage *aMessage, const char *aUriQuery);
extern otError OT_API_REAL_NAME(otCoapMessageInitResponse)(otMessage *aResponse,
const otMessage *aRequest,
otCoapType aType,
otCoapCode aCode);
extern otError OT_API_REAL_NAME(otCoapMessageSetPayloadMarker)(otMessage *aMessage);
extern otError OT_API_REAL_NAME(otCoapMessageSetToken)(otMessage *aMessage,
const uint8_t *aToken,
uint8_t aTokenLength);
extern otError OT_API_REAL_NAME(otCoapOptionIteratorGetOptionUintValue)(otCoapOptionIterator *aIterator,
uint64_t *aValue);
extern otError OT_API_REAL_NAME(otCoapOptionIteratorGetOptionValue)(otCoapOptionIterator *aIterator, void *aValue);
extern otError OT_API_REAL_NAME(otCoapOptionIteratorInit)(otCoapOptionIterator *aIterator, const otMessage *aMessage);
extern otError OT_API_REAL_NAME(otCoapSendRequestBlockWiseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
otCoapResponseHandler aHandler,
void *aContext,
const otCoapTxParameters *aTxParameters,
otCoapBlockwiseTransmitHook aTransmitHook,
otCoapBlockwiseReceiveHook aReceiveHook);
extern otError OT_API_REAL_NAME(otCoapSendRequestWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
otCoapResponseHandler aHandler,
void *aContext,
const otCoapTxParameters *aTxParameters);
extern otError OT_API_REAL_NAME(otCoapSendResponseBlockWiseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
const otCoapTxParameters *aTxParameters,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook);
extern otError OT_API_REAL_NAME(otCoapSendResponseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
const otCoapTxParameters *aTxParameters);
extern otError OT_API_REAL_NAME(otCoapStart)(otInstance *aInstance, uint16_t aPort);
extern otError OT_API_REAL_NAME(otCoapStop)(otInstance *aInstance);
extern otMessage *OT_API_REAL_NAME(otCoapNewMessage)(otInstance *aInstance, const otMessageSettings *aSettings);
extern uint16_t OT_API_REAL_NAME(otCoapBlockSizeFromExponent)(otCoapBlockSzx aSize);
extern uint16_t OT_API_REAL_NAME(otCoapMessageGetMessageId)(const otMessage *aMessage);
extern uint8_t OT_API_REAL_NAME(otCoapMessageGetTokenLength)(const otMessage *aMessage);
extern void OT_API_REAL_NAME(otCoapAddBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource);
extern void OT_API_REAL_NAME(otCoapAddResource)(otInstance *aInstance, otCoapResource *aResource);
extern void OT_API_REAL_NAME(otCoapMessageGenerateToken)(otMessage *aMessage, uint8_t aTokenLength);
extern void OT_API_REAL_NAME(otCoapMessageInit)(otMessage *aMessage, otCoapType aType, otCoapCode aCode);
extern void OT_API_REAL_NAME(otCoapMessageSetCode)(otMessage *aMessage, otCoapCode aCode);
extern void OT_API_REAL_NAME(otCoapRemoveBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource);
extern void OT_API_REAL_NAME(otCoapRemoveResource)(otInstance *aInstance, otCoapResource *aResource);
extern void OT_API_REAL_NAME(otCoapSetDefaultHandler)(otInstance *aInstance,
otCoapRequestHandler aHandler,
void *aContext);
const char *OT_API_WRAPPER_NAME(otCoapMessageCodeToString)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
const char *ret = OT_API_REAL_NAME(otCoapMessageCodeToString)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otCoapOption *OT_API_WRAPPER_NAME(otCoapOptionIteratorGetFirstOption)(otCoapOptionIterator *aIterator)
{
sl_ot_rtos_acquire_stack_mutex();
const otCoapOption *ret = OT_API_REAL_NAME(otCoapOptionIteratorGetFirstOption)(aIterator);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otCoapOption *OT_API_WRAPPER_NAME(otCoapOptionIteratorGetFirstOptionMatching)(otCoapOptionIterator *aIterator,
uint16_t aOption)
{
sl_ot_rtos_acquire_stack_mutex();
const otCoapOption *ret = OT_API_REAL_NAME(otCoapOptionIteratorGetFirstOptionMatching)(aIterator, aOption);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otCoapOption *OT_API_WRAPPER_NAME(otCoapOptionIteratorGetNextOption)(otCoapOptionIterator *aIterator)
{
sl_ot_rtos_acquire_stack_mutex();
const otCoapOption *ret = OT_API_REAL_NAME(otCoapOptionIteratorGetNextOption)(aIterator);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otCoapOption *OT_API_WRAPPER_NAME(otCoapOptionIteratorGetNextOptionMatching)(otCoapOptionIterator *aIterator,
uint16_t aOption)
{
sl_ot_rtos_acquire_stack_mutex();
const otCoapOption *ret = OT_API_REAL_NAME(otCoapOptionIteratorGetNextOptionMatching)(aIterator, aOption);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const uint8_t *OT_API_WRAPPER_NAME(otCoapMessageGetToken)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
const uint8_t *ret = OT_API_REAL_NAME(otCoapMessageGetToken)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otCoapCode OT_API_WRAPPER_NAME(otCoapMessageGetCode)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
otCoapCode ret = OT_API_REAL_NAME(otCoapMessageGetCode)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otCoapType OT_API_WRAPPER_NAME(otCoapMessageGetType)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
otCoapType ret = OT_API_REAL_NAME(otCoapMessageGetType)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendBlock1Option)(otMessage *aMessage,
uint32_t aNum,
bool aMore,
otCoapBlockSzx aSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendBlock1Option)(aMessage, aNum, aMore, aSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendBlock2Option)(otMessage *aMessage,
uint32_t aNum,
bool aMore,
otCoapBlockSzx aSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendBlock2Option)(aMessage, aNum, aMore, aSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendContentFormatOption)(otMessage *aMessage,
otCoapOptionContentFormat aContentFormat)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendContentFormatOption)(aMessage, aContentFormat);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendMaxAgeOption)(otMessage *aMessage, uint32_t aMaxAge)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendMaxAgeOption)(aMessage, aMaxAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendObserveOption)(otMessage *aMessage, uint32_t aObserve)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendObserveOption)(aMessage, aObserve);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendOption)(otMessage *aMessage,
uint16_t aNumber,
uint16_t aLength,
const void *aValue)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendOption)(aMessage, aNumber, aLength, aValue);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendProxyUriOption)(otMessage *aMessage, const char *aUriPath)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendProxyUriOption)(aMessage, aUriPath);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendUintOption)(otMessage *aMessage, uint16_t aNumber, uint32_t aValue)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendUintOption)(aMessage, aNumber, aValue);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendUriPathOptions)(otMessage *aMessage, const char *aUriPath)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendUriPathOptions)(aMessage, aUriPath);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendUriQueryOption)(otMessage *aMessage, const char *aUriQuery)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendUriQueryOption)(aMessage, aUriQuery);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageAppendUriQueryOptions)(otMessage *aMessage, const char *aUriQuery)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageAppendUriQueryOptions)(aMessage, aUriQuery);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageInitResponse)(otMessage *aResponse,
const otMessage *aRequest,
otCoapType aType,
otCoapCode aCode)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageInitResponse)(aResponse, aRequest, aType, aCode);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageSetPayloadMarker)(otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageSetPayloadMarker)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapMessageSetToken)(otMessage *aMessage, const uint8_t *aToken, uint8_t aTokenLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapMessageSetToken)(aMessage, aToken, aTokenLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapOptionIteratorGetOptionUintValue)(otCoapOptionIterator *aIterator, uint64_t *aValue)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapOptionIteratorGetOptionUintValue)(aIterator, aValue);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapOptionIteratorGetOptionValue)(otCoapOptionIterator *aIterator, void *aValue)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapOptionIteratorGetOptionValue)(aIterator, aValue);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapOptionIteratorInit)(otCoapOptionIterator *aIterator, const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapOptionIteratorInit)(aIterator, aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSendRequestBlockWiseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
otCoapResponseHandler aHandler,
void *aContext,
const otCoapTxParameters *aTxParameters,
otCoapBlockwiseTransmitHook aTransmitHook,
otCoapBlockwiseReceiveHook aReceiveHook)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSendRequestBlockWiseWithParameters)(aInstance,
aMessage,
aMessageInfo,
aHandler,
aContext,
aTxParameters,
aTransmitHook,
aReceiveHook);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSendRequestWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
otCoapResponseHandler aHandler,
void *aContext,
const otCoapTxParameters *aTxParameters)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(
otCoapSendRequestWithParameters)(aInstance, aMessage, aMessageInfo, aHandler, aContext, aTxParameters);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSendResponseBlockWiseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
const otCoapTxParameters *aTxParameters,
void *aContext,
otCoapBlockwiseTransmitHook aTransmitHook)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSendResponseBlockWiseWithParameters)(aInstance,
aMessage,
aMessageInfo,
aTxParameters,
aContext,
aTransmitHook);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapSendResponseWithParameters)(otInstance *aInstance,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
const otCoapTxParameters *aTxParameters)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapSendResponseWithParameters)(aInstance, aMessage, aMessageInfo, aTxParameters);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapStart)(otInstance *aInstance, uint16_t aPort)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapStart)(aInstance, aPort);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCoapStop)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCoapStop)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otMessage *OT_API_WRAPPER_NAME(otCoapNewMessage)(otInstance *aInstance, const otMessageSettings *aSettings)
{
sl_ot_rtos_acquire_stack_mutex();
otMessage *ret = OT_API_REAL_NAME(otCoapNewMessage)(aInstance, aSettings);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otCoapBlockSizeFromExponent)(otCoapBlockSzx aSize)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otCoapBlockSizeFromExponent)(aSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otCoapMessageGetMessageId)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otCoapMessageGetMessageId)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint8_t OT_API_WRAPPER_NAME(otCoapMessageGetTokenLength)(const otMessage *aMessage)
{
sl_ot_rtos_acquire_stack_mutex();
uint8_t ret = OT_API_REAL_NAME(otCoapMessageGetTokenLength)(aMessage);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otCoapAddBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapAddBlockWiseResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapAddResource)(otInstance *aInstance, otCoapResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapAddResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapMessageGenerateToken)(otMessage *aMessage, uint8_t aTokenLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapMessageGenerateToken)(aMessage, aTokenLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapMessageInit)(otMessage *aMessage, otCoapType aType, otCoapCode aCode)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapMessageInit)(aMessage, aType, aCode);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapMessageSetCode)(otMessage *aMessage, otCoapCode aCode)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapMessageSetCode)(aMessage, aCode);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapRemoveBlockWiseResource)(otInstance *aInstance, otCoapBlockwiseResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapRemoveBlockWiseResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapRemoveResource)(otInstance *aInstance, otCoapResource *aResource)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapRemoveResource)(aInstance, aResource);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCoapSetDefaultHandler)(otInstance *aInstance, otCoapRequestHandler aHandler, void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCoapSetDefaultHandler)(aInstance, aHandler, aContext);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,282 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Commissioner APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/commissioner.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern const char *OT_API_REAL_NAME(otCommissionerGetId)(otInstance *aInstance);
extern const char *OT_API_REAL_NAME(otCommissionerGetProvisioningUrl)(otInstance *aInstance);
extern otCommissionerState OT_API_REAL_NAME(otCommissionerGetState)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otCommissionerAddJoiner)(otInstance *aInstance,
const otExtAddress *aEui64,
const char *aPskd,
uint32_t aTimeout);
extern otError OT_API_REAL_NAME(otCommissionerAddJoinerWithDiscerner)(otInstance *aInstance,
const otJoinerDiscerner *aDiscerner,
const char *aPskd,
uint32_t aTimeout);
extern otError OT_API_REAL_NAME(otCommissionerAnnounceBegin)(otInstance *aInstance,
uint32_t aChannelMask,
uint8_t aCount,
uint16_t aPeriod,
const otIp6Address *aAddress);
extern otError OT_API_REAL_NAME(otCommissionerEnergyScan)(otInstance *aInstance,
uint32_t aChannelMask,
uint8_t aCount,
uint16_t aPeriod,
uint16_t aScanDuration,
const otIp6Address *aAddress,
otCommissionerEnergyReportCallback aCallback,
void *aContext);
extern otError OT_API_REAL_NAME(otCommissionerGetNextJoinerInfo)(otInstance *aInstance,
uint16_t *aIterator,
otJoinerInfo *aJoiner);
extern otError OT_API_REAL_NAME(otCommissionerPanIdQuery)(otInstance *aInstance,
uint16_t aPanId,
uint32_t aChannelMask,
const otIp6Address *aAddress,
otCommissionerPanIdConflictCallback aCallback,
void *aContext);
extern otError OT_API_REAL_NAME(otCommissionerRemoveJoiner)(otInstance *aInstance, const otExtAddress *aEui64);
extern otError OT_API_REAL_NAME(otCommissionerRemoveJoinerWithDiscerner)(otInstance *aInstance,
const otJoinerDiscerner *aDiscerner);
extern otError OT_API_REAL_NAME(otCommissionerSendMgmtGet)(otInstance *aInstance,
const uint8_t *aTlvs,
uint8_t aLength);
extern otError OT_API_REAL_NAME(otCommissionerSendMgmtSet)(otInstance *aInstance,
const otCommissioningDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength);
extern otError OT_API_REAL_NAME(otCommissionerSetId)(otInstance *aInstance, const char *aId);
extern otError OT_API_REAL_NAME(otCommissionerSetProvisioningUrl)(otInstance *aInstance, const char *aProvisioningUrl);
extern otError OT_API_REAL_NAME(otCommissionerStart)(otInstance *aInstance,
otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void *aCallbackContext);
extern otError OT_API_REAL_NAME(otCommissionerStop)(otInstance *aInstance);
extern uint16_t OT_API_REAL_NAME(otCommissionerGetSessionId)(otInstance *aInstance);
const char *OT_API_WRAPPER_NAME(otCommissionerGetId)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
const char *ret = OT_API_REAL_NAME(otCommissionerGetId)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const char *OT_API_WRAPPER_NAME(otCommissionerGetProvisioningUrl)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
const char *ret = OT_API_REAL_NAME(otCommissionerGetProvisioningUrl)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otCommissionerState OT_API_WRAPPER_NAME(otCommissionerGetState)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otCommissionerState ret = OT_API_REAL_NAME(otCommissionerGetState)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerAddJoiner)(otInstance *aInstance,
const otExtAddress *aEui64,
const char *aPskd,
uint32_t aTimeout)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerAddJoiner)(aInstance, aEui64, aPskd, aTimeout);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerAddJoinerWithDiscerner)(otInstance *aInstance,
const otJoinerDiscerner *aDiscerner,
const char *aPskd,
uint32_t aTimeout)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerAddJoinerWithDiscerner)(aInstance, aDiscerner, aPskd, aTimeout);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerAnnounceBegin)(otInstance *aInstance,
uint32_t aChannelMask,
uint8_t aCount,
uint16_t aPeriod,
const otIp6Address *aAddress)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerAnnounceBegin)(aInstance, aChannelMask, aCount, aPeriod, aAddress);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerEnergyScan)(otInstance *aInstance,
uint32_t aChannelMask,
uint8_t aCount,
uint16_t aPeriod,
uint16_t aScanDuration,
const otIp6Address *aAddress,
otCommissionerEnergyReportCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerEnergyScan)(aInstance,
aChannelMask,
aCount,
aPeriod,
aScanDuration,
aAddress,
aCallback,
aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerGetNextJoinerInfo)(otInstance *aInstance,
uint16_t *aIterator,
otJoinerInfo *aJoiner)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerGetNextJoinerInfo)(aInstance, aIterator, aJoiner);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerPanIdQuery)(otInstance *aInstance,
uint16_t aPanId,
uint32_t aChannelMask,
const otIp6Address *aAddress,
otCommissionerPanIdConflictCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otCommissionerPanIdQuery)(aInstance, aPanId, aChannelMask, aAddress, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerRemoveJoiner)(otInstance *aInstance, const otExtAddress *aEui64)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerRemoveJoiner)(aInstance, aEui64);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerRemoveJoinerWithDiscerner)(otInstance *aInstance,
const otJoinerDiscerner *aDiscerner)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerRemoveJoinerWithDiscerner)(aInstance, aDiscerner);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerSendMgmtGet)(otInstance *aInstance, const uint8_t *aTlvs, uint8_t aLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerSendMgmtGet)(aInstance, aTlvs, aLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerSendMgmtSet)(otInstance *aInstance,
const otCommissioningDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerSendMgmtSet)(aInstance, aDataset, aTlvs, aLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerSetId)(otInstance *aInstance, const char *aId)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerSetId)(aInstance, aId);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerSetProvisioningUrl)(otInstance *aInstance, const char *aProvisioningUrl)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerSetProvisioningUrl)(aInstance, aProvisioningUrl);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerStart)(otInstance *aInstance,
otCommissionerStateCallback aStateCallback,
otCommissionerJoinerCallback aJoinerCallback,
void *aCallbackContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerStart)(aInstance, aStateCallback, aJoinerCallback, aCallbackContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otCommissionerStop)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otCommissionerStop)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint16_t OT_API_WRAPPER_NAME(otCommissionerGetSessionId)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint16_t ret = OT_API_REAL_NAME(otCommissionerGetSessionId)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Config APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/config.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif

View File

@@ -0,0 +1,91 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Crypto APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/crypto.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern void OT_API_REAL_NAME(otCryptoAesCcm)(const otCryptoKey *aKey,
uint8_t aTagLength,
const void *aNonce,
uint8_t aNonceLength,
const void *aHeader,
uint32_t aHeaderLength,
void *aPlainText,
void *aCipherText,
uint32_t aLength,
bool aEncrypt,
void *aTag);
extern void OT_API_REAL_NAME(otCryptoHmacSha256)(const otCryptoKey *aKey,
const uint8_t *aBuf,
uint16_t aBufLength,
otCryptoSha256Hash *aHash);
void OT_API_WRAPPER_NAME(otCryptoAesCcm)(const otCryptoKey *aKey,
uint8_t aTagLength,
const void *aNonce,
uint8_t aNonceLength,
const void *aHeader,
uint32_t aHeaderLength,
void *aPlainText,
void *aCipherText,
uint32_t aLength,
bool aEncrypt,
void *aTag)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCryptoAesCcm)
(aKey, aTagLength, aNonce, aNonceLength, aHeader, aHeaderLength, aPlainText, aCipherText, aLength, aEncrypt, aTag);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otCryptoHmacSha256)(const otCryptoKey *aKey,
const uint8_t *aBuf,
uint16_t aBufLength,
otCryptoSha256Hash *aHash)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otCryptoHmacSha256)(aKey, aBuf, aBufLength, aHash);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,75 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dataset Ftd APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dataset_ftd.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern otError OT_API_REAL_NAME(otDatasetCreateNewNetwork)(otInstance *aInstance, otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetSetDelayTimerMinimal)(otInstance *aInstance, uint32_t aDelayTimerMinimal);
extern uint32_t OT_API_REAL_NAME(otDatasetGetDelayTimerMinimal)(otInstance *aInstance);
otError OT_API_WRAPPER_NAME(otDatasetCreateNewNetwork)(otInstance *aInstance, otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetCreateNewNetwork)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSetDelayTimerMinimal)(otInstance *aInstance, uint32_t aDelayTimerMinimal)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetSetDelayTimerMinimal)(aInstance, aDelayTimerMinimal);
sl_ot_rtos_release_stack_mutex();
return ret;
}
uint32_t OT_API_WRAPPER_NAME(otDatasetGetDelayTimerMinimal)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
uint32_t ret = OT_API_REAL_NAME(otDatasetGetDelayTimerMinimal)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,80 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dataset Updater APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dataset_updater.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otDatasetUpdaterIsUpdateOngoing)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otDatasetUpdaterRequestUpdate)(otInstance *aInstance,
const otOperationalDataset *aDataset,
otDatasetUpdaterCallback aCallback,
void *aContext);
extern void OT_API_REAL_NAME(otDatasetUpdaterCancelUpdate)(otInstance *aInstance);
bool OT_API_WRAPPER_NAME(otDatasetUpdaterIsUpdateOngoing)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otDatasetUpdaterIsUpdateOngoing)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetUpdaterRequestUpdate)(otInstance *aInstance,
const otOperationalDataset *aDataset,
otDatasetUpdaterCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetUpdaterRequestUpdate)(aInstance, aDataset, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDatasetUpdaterCancelUpdate)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDatasetUpdaterCancelUpdate)(aInstance);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,263 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dataset APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dataset.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otDatasetIsCommissioned)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otDatasetGeneratePskc)(const char *aPassPhrase,
const otNetworkName *aNetworkName,
const otExtendedPanId *aExtPanId,
otPskc *aPskc);
extern otError OT_API_REAL_NAME(otDatasetGetActive)(otInstance *aInstance, otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetGetActiveTlvs)(otInstance *aInstance, otOperationalDatasetTlvs *aDataset);
extern otError OT_API_REAL_NAME(otDatasetGetPending)(otInstance *aInstance, otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetGetPendingTlvs)(otInstance *aInstance, otOperationalDatasetTlvs *aDataset);
extern otError OT_API_REAL_NAME(otDatasetParseTlvs)(const otOperationalDatasetTlvs *aDatasetTlvs,
otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetSendMgmtActiveGet)(otInstance *aInstance,
const otOperationalDatasetComponents *aDatasetComponents,
const uint8_t *aTlvTypes,
uint8_t aLength,
const otIp6Address *aAddress);
extern otError OT_API_REAL_NAME(otDatasetSendMgmtActiveSet)(otInstance *aInstance,
const otOperationalDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength,
otDatasetMgmtSetCallback aCallback,
void *aContext);
extern otError OT_API_REAL_NAME(otDatasetSendMgmtPendingGet)(otInstance *aInstance,
const otOperationalDatasetComponents *aDatasetComponents,
const uint8_t *aTlvTypes,
uint8_t aLength,
const otIp6Address *aAddress);
extern otError OT_API_REAL_NAME(otDatasetSendMgmtPendingSet)(otInstance *aInstance,
const otOperationalDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength,
otDatasetMgmtSetCallback aCallback,
void *aContext);
extern otError OT_API_REAL_NAME(otDatasetSetActive)(otInstance *aInstance, const otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetSetActiveTlvs)(otInstance *aInstance,
const otOperationalDatasetTlvs *aDataset);
extern otError OT_API_REAL_NAME(otDatasetSetPending)(otInstance *aInstance, const otOperationalDataset *aDataset);
extern otError OT_API_REAL_NAME(otDatasetSetPendingTlvs)(otInstance *aInstance,
const otOperationalDatasetTlvs *aDataset);
extern otError OT_API_REAL_NAME(otDatasetUpdateTlvs)(const otOperationalDataset *aDataset,
otOperationalDatasetTlvs *aDatasetTlvs);
extern otError OT_API_REAL_NAME(otNetworkNameFromString)(otNetworkName *aNetworkName, const char *aNameString);
extern void OT_API_REAL_NAME(otDatasetConvertToTlvs)(const otOperationalDataset *aDataset,
otOperationalDatasetTlvs *aDatasetTlvs);
bool OT_API_WRAPPER_NAME(otDatasetIsCommissioned)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otDatasetIsCommissioned)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetGeneratePskc)(const char *aPassPhrase,
const otNetworkName *aNetworkName,
const otExtendedPanId *aExtPanId,
otPskc *aPskc)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetGeneratePskc)(aPassPhrase, aNetworkName, aExtPanId, aPskc);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetGetActive)(otInstance *aInstance, otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetGetActive)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetGetActiveTlvs)(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetGetActiveTlvs)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetGetPending)(otInstance *aInstance, otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetGetPending)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetGetPendingTlvs)(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetGetPendingTlvs)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetParseTlvs)(const otOperationalDatasetTlvs *aDatasetTlvs,
otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetParseTlvs)(aDatasetTlvs, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSendMgmtActiveGet)(otInstance *aInstance,
const otOperationalDatasetComponents *aDatasetComponents,
const uint8_t *aTlvTypes,
uint8_t aLength,
const otIp6Address *aAddress)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otDatasetSendMgmtActiveGet)(aInstance, aDatasetComponents, aTlvTypes, aLength, aAddress);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSendMgmtActiveSet)(otInstance *aInstance,
const otOperationalDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength,
otDatasetMgmtSetCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otDatasetSendMgmtActiveSet)(aInstance, aDataset, aTlvs, aLength, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSendMgmtPendingGet)(otInstance *aInstance,
const otOperationalDatasetComponents *aDatasetComponents,
const uint8_t *aTlvTypes,
uint8_t aLength,
const otIp6Address *aAddress)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otDatasetSendMgmtPendingGet)(aInstance, aDatasetComponents, aTlvTypes, aLength, aAddress);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSendMgmtPendingSet)(otInstance *aInstance,
const otOperationalDataset *aDataset,
const uint8_t *aTlvs,
uint8_t aLength,
otDatasetMgmtSetCallback aCallback,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otDatasetSendMgmtPendingSet)(aInstance, aDataset, aTlvs, aLength, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSetActive)(otInstance *aInstance, const otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetSetActive)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSetActiveTlvs)(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetSetActiveTlvs)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSetPending)(otInstance *aInstance, const otOperationalDataset *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetSetPending)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetSetPendingTlvs)(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetSetPendingTlvs)(aInstance, aDataset);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDatasetUpdateTlvs)(const otOperationalDataset *aDataset,
otOperationalDatasetTlvs *aDatasetTlvs)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDatasetUpdateTlvs)(aDataset, aDatasetTlvs);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otNetworkNameFromString)(otNetworkName *aNetworkName, const char *aNameString)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otNetworkNameFromString)(aNetworkName, aNameString);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDatasetConvertToTlvs)(const otOperationalDataset *aDataset,
otOperationalDatasetTlvs *aDatasetTlvs)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDatasetConvertToTlvs)(aDataset, aDatasetTlvs);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,85 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Diag APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/diag.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otDiagIsEnabled)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otDiagProcessCmd)(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[]);
extern otError OT_API_REAL_NAME(otDiagProcessCmdLine)(otInstance *aInstance, const char *aString);
extern void OT_API_REAL_NAME(otDiagSetOutputCallback)(otInstance *aInstance,
otDiagOutputCallback aCallback,
void *aContext);
bool OT_API_WRAPPER_NAME(otDiagIsEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otDiagIsEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDiagProcessCmd)(otInstance *aInstance, uint8_t aArgsLength, char *aArgs[])
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDiagProcessCmd)(aInstance, aArgsLength, aArgs);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDiagProcessCmdLine)(otInstance *aInstance, const char *aString)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDiagProcessCmdLine)(aInstance, aString);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDiagSetOutputCallback)(otInstance *aInstance, otDiagOutputCallback aCallback, void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDiagSetOutputCallback)(aInstance, aCallback, aContext);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,289 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dns Client APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dns_client.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern const otDnsQueryConfig *OT_API_REAL_NAME(otDnsClientGetDefaultConfig)(otInstance *aInstance);
extern otError OT_API_REAL_NAME(otDnsAddressResponseGetAddress)(const otDnsAddressResponse *aResponse,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl);
extern otError OT_API_REAL_NAME(otDnsAddressResponseGetHostName)(const otDnsAddressResponse *aResponse,
char *aNameBuffer,
uint16_t aNameBufferSize);
extern otError OT_API_REAL_NAME(otDnsBrowseResponseGetHostAddress)(const otDnsBrowseResponse *aResponse,
const char *aHostName,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl);
extern otError OT_API_REAL_NAME(otDnsBrowseResponseGetServiceInfo)(const otDnsBrowseResponse *aResponse,
const char *aInstanceLabel,
otDnsServiceInfo *aServiceInfo);
extern otError OT_API_REAL_NAME(otDnsBrowseResponseGetServiceInstance)(const otDnsBrowseResponse *aResponse,
uint16_t aIndex,
char *aLabelBuffer,
uint8_t aLabelBufferSize);
extern otError OT_API_REAL_NAME(otDnsBrowseResponseGetServiceName)(const otDnsBrowseResponse *aResponse,
char *aNameBuffer,
uint16_t aNameBufferSize);
extern otError OT_API_REAL_NAME(otDnsClientBrowse)(otInstance *aInstance,
const char *aServiceName,
otDnsBrowseCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig);
extern otError OT_API_REAL_NAME(otDnsClientResolveAddress)(otInstance *aInstance,
const char *aHostName,
otDnsAddressCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig);
extern otError OT_API_REAL_NAME(otDnsClientResolveIp4Address)(otInstance *aInstance,
const char *aHostName,
otDnsAddressCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig);
extern otError OT_API_REAL_NAME(otDnsClientResolveService)(otInstance *aInstance,
const char *aInstanceLabel,
const char *aServiceName,
otDnsServiceCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig);
extern otError OT_API_REAL_NAME(otDnsClientResolveServiceAndHostAddress)(otInstance *aInstance,
const char *aInstanceLabel,
const char *aServiceName,
otDnsServiceCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig);
extern otError OT_API_REAL_NAME(otDnsServiceResponseGetHostAddress)(const otDnsServiceResponse *aResponse,
const char *aHostName,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl);
extern otError OT_API_REAL_NAME(otDnsServiceResponseGetServiceInfo)(const otDnsServiceResponse *aResponse,
otDnsServiceInfo *aServiceInfo);
extern otError OT_API_REAL_NAME(otDnsServiceResponseGetServiceName)(const otDnsServiceResponse *aResponse,
char *aLabelBuffer,
uint8_t aLabelBufferSize,
char *aNameBuffer,
uint16_t aNameBufferSize);
extern void OT_API_REAL_NAME(otDnsClientSetDefaultConfig)(otInstance *aInstance, const otDnsQueryConfig *aConfig);
const otDnsQueryConfig *OT_API_WRAPPER_NAME(otDnsClientGetDefaultConfig)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
const otDnsQueryConfig *ret = OT_API_REAL_NAME(otDnsClientGetDefaultConfig)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsAddressResponseGetAddress)(const otDnsAddressResponse *aResponse,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsAddressResponseGetAddress)(aResponse, aIndex, aAddress, aTtl);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsAddressResponseGetHostName)(const otDnsAddressResponse *aResponse,
char *aNameBuffer,
uint16_t aNameBufferSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsAddressResponseGetHostName)(aResponse, aNameBuffer, aNameBufferSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsBrowseResponseGetHostAddress)(const otDnsBrowseResponse *aResponse,
const char *aHostName,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsBrowseResponseGetHostAddress)(aResponse, aHostName, aIndex, aAddress, aTtl);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsBrowseResponseGetServiceInfo)(const otDnsBrowseResponse *aResponse,
const char *aInstanceLabel,
otDnsServiceInfo *aServiceInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsBrowseResponseGetServiceInfo)(aResponse, aInstanceLabel, aServiceInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsBrowseResponseGetServiceInstance)(const otDnsBrowseResponse *aResponse,
uint16_t aIndex,
char *aLabelBuffer,
uint8_t aLabelBufferSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret =
OT_API_REAL_NAME(otDnsBrowseResponseGetServiceInstance)(aResponse, aIndex, aLabelBuffer, aLabelBufferSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsBrowseResponseGetServiceName)(const otDnsBrowseResponse *aResponse,
char *aNameBuffer,
uint16_t aNameBufferSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsBrowseResponseGetServiceName)(aResponse, aNameBuffer, aNameBufferSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsClientBrowse)(otInstance *aInstance,
const char *aServiceName,
otDnsBrowseCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsClientBrowse)(aInstance, aServiceName, aCallback, aContext, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsClientResolveAddress)(otInstance *aInstance,
const char *aHostName,
otDnsAddressCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsClientResolveAddress)(aInstance, aHostName, aCallback, aContext, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsClientResolveIp4Address)(otInstance *aInstance,
const char *aHostName,
otDnsAddressCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsClientResolveIp4Address)(aInstance, aHostName, aCallback, aContext, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsClientResolveService)(otInstance *aInstance,
const char *aInstanceLabel,
const char *aServiceName,
otDnsServiceCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(
otDnsClientResolveService)(aInstance, aInstanceLabel, aServiceName, aCallback, aContext, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsClientResolveServiceAndHostAddress)(otInstance *aInstance,
const char *aInstanceLabel,
const char *aServiceName,
otDnsServiceCallback aCallback,
void *aContext,
const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(
otDnsClientResolveServiceAndHostAddress)(aInstance, aInstanceLabel, aServiceName, aCallback, aContext, aConfig);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsServiceResponseGetHostAddress)(const otDnsServiceResponse *aResponse,
const char *aHostName,
uint16_t aIndex,
otIp6Address *aAddress,
uint32_t *aTtl)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsServiceResponseGetHostAddress)(aResponse, aHostName, aIndex, aAddress, aTtl);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsServiceResponseGetServiceInfo)(const otDnsServiceResponse *aResponse,
otDnsServiceInfo *aServiceInfo)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsServiceResponseGetServiceInfo)(aResponse, aServiceInfo);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsServiceResponseGetServiceName)(const otDnsServiceResponse *aResponse,
char *aLabelBuffer,
uint8_t aLabelBufferSize,
char *aNameBuffer,
uint16_t aNameBufferSize)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(
otDnsServiceResponseGetServiceName)(aResponse, aLabelBuffer, aLabelBufferSize, aNameBuffer, aNameBufferSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDnsClientSetDefaultConfig)(otInstance *aInstance, const otDnsQueryConfig *aConfig)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnsClientSetDefaultConfig)(aInstance, aConfig);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,101 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dns APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dns.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otDnsIsNameCompressionEnabled)(void);
extern otError OT_API_REAL_NAME(otDnsEncodeTxtData)(const otDnsTxtEntry *aTxtEntries,
uint16_t aNumTxtEntries,
uint8_t *aTxtData,
uint16_t *aTxtDataLength);
extern otError OT_API_REAL_NAME(otDnsGetNextTxtEntry)(otDnsTxtEntryIterator *aIterator, otDnsTxtEntry *aEntry);
extern void OT_API_REAL_NAME(otDnsInitTxtEntryIterator)(otDnsTxtEntryIterator *aIterator,
const uint8_t *aTxtData,
uint16_t aTxtDataLength);
extern void OT_API_REAL_NAME(otDnsSetNameCompressionEnabled)(bool aEnabled);
bool OT_API_WRAPPER_NAME(otDnsIsNameCompressionEnabled)(void)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otDnsIsNameCompressionEnabled)();
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsEncodeTxtData)(const otDnsTxtEntry *aTxtEntries,
uint16_t aNumTxtEntries,
uint8_t *aTxtData,
uint16_t *aTxtDataLength)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsEncodeTxtData)(aTxtEntries, aNumTxtEntries, aTxtData, aTxtDataLength);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otError OT_API_WRAPPER_NAME(otDnsGetNextTxtEntry)(otDnsTxtEntryIterator *aIterator, otDnsTxtEntry *aEntry)
{
sl_ot_rtos_acquire_stack_mutex();
otError ret = OT_API_REAL_NAME(otDnsGetNextTxtEntry)(aIterator, aEntry);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDnsInitTxtEntryIterator)(otDnsTxtEntryIterator *aIterator,
const uint8_t *aTxtData,
uint16_t aTxtDataLength)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnsInitTxtEntryIterator)(aIterator, aTxtData, aTxtDataLength);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otDnsSetNameCompressionEnabled)(bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnsSetNameCompressionEnabled)(aEnabled);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,132 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Dnssd Server APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/dnssd_server.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern bool OT_API_REAL_NAME(otDnssdUpstreamQueryIsEnabled)(otInstance *aInstance);
extern const otDnssdCounters *OT_API_REAL_NAME(otDnssdGetCounters)(otInstance *aInstance);
extern const otDnssdQuery *OT_API_REAL_NAME(otDnssdGetNextQuery)(otInstance *aInstance, const otDnssdQuery *aQuery);
extern otDnssdQueryType OT_API_REAL_NAME(otDnssdGetQueryTypeAndName)(const otDnssdQuery *aQuery,
char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE]);
extern void OT_API_REAL_NAME(otDnssdQueryHandleDiscoveredHost)(otInstance *aInstance,
const char *aHostFullName,
otDnssdHostInfo *aHostInfo);
extern void OT_API_REAL_NAME(otDnssdQueryHandleDiscoveredServiceInstance)(otInstance *aInstance,
const char *aServiceFullName,
otDnssdServiceInstanceInfo *aInstanceInfo);
extern void OT_API_REAL_NAME(otDnssdQuerySetCallbacks)(otInstance *aInstance,
otDnssdQuerySubscribeCallback aSubscribe,
otDnssdQueryUnsubscribeCallback aUnsubscribe,
void *aContext);
extern void OT_API_REAL_NAME(otDnssdUpstreamQuerySetEnabled)(otInstance *aInstance, bool aEnabled);
bool OT_API_WRAPPER_NAME(otDnssdUpstreamQueryIsEnabled)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
bool ret = OT_API_REAL_NAME(otDnssdUpstreamQueryIsEnabled)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otDnssdCounters *OT_API_WRAPPER_NAME(otDnssdGetCounters)(otInstance *aInstance)
{
sl_ot_rtos_acquire_stack_mutex();
const otDnssdCounters *ret = OT_API_REAL_NAME(otDnssdGetCounters)(aInstance);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otDnssdQuery *OT_API_WRAPPER_NAME(otDnssdGetNextQuery)(otInstance *aInstance, const otDnssdQuery *aQuery)
{
sl_ot_rtos_acquire_stack_mutex();
const otDnssdQuery *ret = OT_API_REAL_NAME(otDnssdGetNextQuery)(aInstance, aQuery);
sl_ot_rtos_release_stack_mutex();
return ret;
}
otDnssdQueryType OT_API_WRAPPER_NAME(otDnssdGetQueryTypeAndName)(const otDnssdQuery *aQuery,
char (*aNameOutput)[OT_DNS_MAX_NAME_SIZE])
{
sl_ot_rtos_acquire_stack_mutex();
otDnssdQueryType ret = OT_API_REAL_NAME(otDnssdGetQueryTypeAndName)(aQuery, aNameOutput);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otDnssdQueryHandleDiscoveredHost)(otInstance *aInstance,
const char *aHostFullName,
otDnssdHostInfo *aHostInfo)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnssdQueryHandleDiscoveredHost)(aInstance, aHostFullName, aHostInfo);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otDnssdQueryHandleDiscoveredServiceInstance)(otInstance *aInstance,
const char *aServiceFullName,
otDnssdServiceInstanceInfo *aInstanceInfo)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnssdQueryHandleDiscoveredServiceInstance)(aInstance, aServiceFullName, aInstanceInfo);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otDnssdQuerySetCallbacks)(otInstance *aInstance,
otDnssdQuerySubscribeCallback aSubscribe,
otDnssdQueryUnsubscribeCallback aUnsubscribe,
void *aContext)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnssdQuerySetCallbacks)(aInstance, aSubscribe, aUnsubscribe, aContext);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otDnssdUpstreamQuerySetEnabled)(otInstance *aInstance, bool aEnabled)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otDnssdUpstreamQuerySetEnabled)(aInstance, aEnabled);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,57 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Error APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/error.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern const char *OT_API_REAL_NAME(otThreadErrorToString)(otError aError);
const char *OT_API_WRAPPER_NAME(otThreadErrorToString)(otError aError)
{
sl_ot_rtos_acquire_stack_mutex();
const char *ret = OT_API_REAL_NAME(otThreadErrorToString)(aError);
sl_ot_rtos_release_stack_mutex();
return ret;
}

View File

@@ -0,0 +1,65 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread Heap APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/heap.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern void *OT_API_REAL_NAME(otHeapCAlloc)(size_t aCount, size_t aSize);
extern void OT_API_REAL_NAME(otHeapFree)(void *aPointer);
void *OT_API_WRAPPER_NAME(otHeapCAlloc)(size_t aCount, size_t aSize)
{
sl_ot_rtos_acquire_stack_mutex();
void *ret = OT_API_REAL_NAME(otHeapCAlloc)(aCount, aSize);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otHeapFree)(void *aPointer)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otHeapFree)(aPointer);
sl_ot_rtos_release_stack_mutex();
}

View File

@@ -0,0 +1,200 @@
/*******************************************************************************
* @file
* @brief OpenThread wrapper functions for OpenThread History Tracker APIs
* allowing access to the thread stack in a multi-threaded environment.
*******************************************************************************
* # License
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* 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_ot_rtos_adaptation.h"
#include <openthread/history_tracker.h>
#if defined(__GNUC__)
#define REAL_NAME(function) __real_##function
#define WRAPPER_NAME(function) __wrap_##function
#define OT_API_REAL_NAME(function) REAL_NAME(function)
#define OT_API_WRAPPER_NAME(function) WRAPPER_NAME(function)
// #elif defined(__IAR_SYSTEMS_ICC__)
// #define REAL_NAME(function) $Super$$##function
// #define WRAPPER_NAME(function) $Sub$$##function
// #define OT_API_REAL_NAME(function) $Super$$__iar_dl##function
// #define OT_API_WRAPPER_NAME(function) $Sub$$__iar_dl##function
#else
#error Unsupported compiler
#endif
extern const otHistoryTrackerExternalRouteInfo *OT_API_REAL_NAME(otHistoryTrackerIterateExternalRouteHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerMessageInfo *OT_API_REAL_NAME(
otHistoryTrackerIterateRxHistory)(otInstance *aInstance, otHistoryTrackerIterator *aIterator, uint32_t *aEntryAge);
extern const otHistoryTrackerMessageInfo *OT_API_REAL_NAME(
otHistoryTrackerIterateTxHistory)(otInstance *aInstance, otHistoryTrackerIterator *aIterator, uint32_t *aEntryAge);
extern const otHistoryTrackerMulticastAddressInfo *OT_API_REAL_NAME(otHistoryTrackerIterateMulticastAddressHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerNeighborInfo *OT_API_REAL_NAME(otHistoryTrackerIterateNeighborHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerNetworkInfo *OT_API_REAL_NAME(otHistoryTrackerIterateNetInfoHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerOnMeshPrefixInfo *OT_API_REAL_NAME(otHistoryTrackerIterateOnMeshPrefixHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerRouterInfo *OT_API_REAL_NAME(otHistoryTrackerIterateRouterHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern const otHistoryTrackerUnicastAddressInfo *OT_API_REAL_NAME(otHistoryTrackerIterateUnicastAddressHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge);
extern void OT_API_REAL_NAME(otHistoryTrackerEntryAgeToString)(uint32_t aEntryAge, char *aBuffer, uint16_t aSize);
extern void OT_API_REAL_NAME(otHistoryTrackerInitIterator)(otHistoryTrackerIterator *aIterator);
const otHistoryTrackerExternalRouteInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateExternalRouteHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerExternalRouteInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateExternalRouteHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerMessageInfo *OT_API_WRAPPER_NAME(
otHistoryTrackerIterateRxHistory)(otInstance *aInstance, otHistoryTrackerIterator *aIterator, uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerMessageInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateRxHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerMessageInfo *OT_API_WRAPPER_NAME(
otHistoryTrackerIterateTxHistory)(otInstance *aInstance, otHistoryTrackerIterator *aIterator, uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerMessageInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateTxHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerMulticastAddressInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateMulticastAddressHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerMulticastAddressInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateMulticastAddressHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerNeighborInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateNeighborHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerNeighborInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateNeighborHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerNetworkInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateNetInfoHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerNetworkInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateNetInfoHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerOnMeshPrefixInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateOnMeshPrefixHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerOnMeshPrefixInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateOnMeshPrefixHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerRouterInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateRouterHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerRouterInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateRouterHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
const otHistoryTrackerUnicastAddressInfo *OT_API_WRAPPER_NAME(otHistoryTrackerIterateUnicastAddressHistory)(
otInstance *aInstance,
otHistoryTrackerIterator *aIterator,
uint32_t *aEntryAge)
{
sl_ot_rtos_acquire_stack_mutex();
const otHistoryTrackerUnicastAddressInfo *ret =
OT_API_REAL_NAME(otHistoryTrackerIterateUnicastAddressHistory)(aInstance, aIterator, aEntryAge);
sl_ot_rtos_release_stack_mutex();
return ret;
}
void OT_API_WRAPPER_NAME(otHistoryTrackerEntryAgeToString)(uint32_t aEntryAge, char *aBuffer, uint16_t aSize)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otHistoryTrackerEntryAgeToString)(aEntryAge, aBuffer, aSize);
sl_ot_rtos_release_stack_mutex();
}
void OT_API_WRAPPER_NAME(otHistoryTrackerInitIterator)(otHistoryTrackerIterator *aIterator)
{
sl_ot_rtos_acquire_stack_mutex();
OT_API_REAL_NAME(otHistoryTrackerInitIterator)(aIterator);
sl_ot_rtos_release_stack_mutex();
}

Some files were not shown because too many files have changed in this diff Show More