364 lines
12 KiB
C
364 lines
12 KiB
C
/***************************************************************************//**
|
|
* @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
|