diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d50dfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +precompil/* +build/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..733f7c2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.15) +project(sigfox_ep_addon_rfp) + +#Check if Project configure by himself or by a parent project (like sfx_lib_core_protocol) +if ( ${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} ) + if (NOT DEFINED SFX_LIB_CORE_PROTOCOL_DIR) + message(FATAL_ERROR "${PROJECT_NAME} cannot be configured without -DSFX_LIB_CORE_PROTOCOL_DIR=") + endif() + set(ADDON_RFP OFF) + add_subdirectory(${SFX_LIB_CORE_PROTOCOL_DIR} "${CMAKE_CURRENT_BINARY_DIR}/${SFX_LIB_CORE_PROTOCOL_DIR}") +else() + message("${PROJECT_NAME} is Fetched by a parent project") +endif() + +set(ADDON_RFP_SOURCES + src/sigfox_ep_addon_rfp_api.c + src/tests_mode/sigfox_rfp_test_mode_a.c + src/tests_mode/sigfox_rfp_test_mode_b.c + src/tests_mode/sigfox_rfp_test_mode_c.c + src/tests_mode/sigfox_rfp_test_mode_g.c + src/tests_mode/sigfox_rfp_test_mode_j.c + src/tests_mode/sigfox_rfp_test_mode_k.c + src/tests_mode/sigfox_rfp_test_mode_l.c +) + +set(ADDON_RFP_HEADERS + inc/sigfox_ep_addon_rfp_api.h + inc/sigfox_ep_addon_rfp_version.h + inc/tests_mode/sigfox_rfp_test_mode_types.h +) + +set(ADDON_RFP_PUBLIC_HEADERS + inc/sigfox_ep_addon_rfp_api.h + inc/sigfox_ep_addon_rfp_version.h +) + +#When sigfox_ep_flag.h is don't used +if(${USE_SIGFOX_EP_FLAGS_H} STREQUAL "ON") +else() + if(${CERTIFICATION} STREQUAL "OFF") + message(FATAL_ERROR "CERTIFICATION Flag must be activated for this addon") + endif() + if((${RC3C} STREQUAL OFF) AND (${RC5} STREQUAL OFF)) + list(REMOVE_ITEM ADDON_RFP_SOURCES "src/tests_mode/sigfox_rfp_test_mode_g.c") + endif() + if((${PUBLIC_KEY_CAPABLE} STREQUAL OFF) ) + list(REMOVE_ITEM ADDON_RFP_SOURCES "src/tests_mode/sigfox_rfp_test_mode_k.c") + endif() +endif() + +#Add Cmake module path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + +#Precompile module +include(precompile_addon_rfp) + +add_library(${PROJECT_NAME} STATIC ${PRECOMPIL_ADDON_RFP_SOURCES}) +add_dependencies(${PROJECT_NAME} precompil_${PROJECT_NAME}) +target_include_directories(${PROJECT_NAME} PUBLIC ${PRECOMPIL_DIR}/inc) +target_compile_definitions(${PROJECT_NAME} PUBLIC ${DEF_FLAG_LIST}) +target_compile_options(${PROJECT_NAME} PRIVATE -Wall) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${PRECOMPIL_ADDON_RFP_PUBLIC_HEADERS}") +set_target_properties(${PROJECT_NAME} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${LIB_LOCATION} + LIBRARY_OUTPUT_DIRECTORY ${LIB_LOCATION} +) +install(TARGETS ${PROJECT_NAME} + ARCHIVE DESTINATION ${LIB_LOCATION} + PUBLIC_HEADER DESTINATION ${API_LOCATION} +) + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..bb86680 --- /dev/null +++ b/README.md @@ -0,0 +1,113 @@ +# Sigfox End-Point RF & Protocol addon (EP_ADDON_RFP) + +## Description + +This **Sigfox End-Point RF & Protocol addon** show an exemple of the [RF & Protocol test](https://support.sigfox.com/docs/rf-protocol-test-specification) implementation. This addon is an application of the [EP LIB](https://github.com/sigfox-tech-radio/sigfox-ep-lib) to offers a new API provided in the "sigfox_ep_addon_rfp_api.h" to execute different tests mode. + +## Stack architecture + +

+ +

+ +## Code optimization + +The **EP_ADDON_RFP** shared the same compilation flgas as the **EP-LIB**. For more details of these flags see **EP-LIB** repository. + +## Getting Started + +### Cloning the repository +```bash +$ git clone https://github.com/sigfox-tech-radio/sigfox-ep-addon-rfp.git +``` + +### Usage + +Like the **EP-LIB** this **EP_ADDON_RFP** can be used in many ways: + * The [original source code](#original-source-code) to used the raw sources files + * The [precompiled source code](#precompiled-source-code) to remove all unused source code and have more readability. + * The [library](#library) to used a compiled library. + +### Original source code + +#### Dependency + +The only dependence is the [EP-LIB](https://github.com/sigfox-tech-radio/sigfox-ep-lib) source code. + +#### Building Process + +Sources files are available in `inc` and `src` folders and must be copied directly in the embedded project. The configuration flags must be the same than the EP-LIB. + +### Precompiled source code + +#### Dependency + +Before building process install **unifdef**, **cmake** tools and clone or download the [EP_LIB](https://github.com/sigfox-tech-radio/sigfox-ep-lib) from github repository. +The unifdef tool is used to remove dead code and cmake to build. +All precompiles option are the same as EP-LIB (see [README.md](https://github.com/sigfox-tech-radio/sigfox-ep-lib/blob/master/README.md)). + +#### Building Process + +If you want to **precompile** the sources files for a given flags selection, you need to use the **cmake** commands: +Create a build folder: + +```bash +$ cd sigfox-ep-addon-rfp +$ mkdir build +$ cd build +``` + +* Precompiling by reading the `inc/sigfox_ep_flags.h` file: + +```bash +$ cmake -DUSE_SIGFOX_EP_FLAGS_H=ON \ + -DSFX_LIB_CORE_PROTOCOL_DIR= .. +$ make precompil_sigfox_ep_addon_rfp +``` + +* Precompiling by entering the flags selection on command line: + +```bash +$ cmake -DUSE_SIGFOX_EP_FLAGS_H=OFF \ + -DRC1=ON \ + -DRC2=ON \ + -DRC3C=ON \ + -DRC3D=ON \ + -DRC4=ON \ + -DRC5=ON \ + -DRC6=ON \ + -DRC7=ON \ + -DAPPLICATION_MESSAGES=ON \ + -DCONTROL_KEEP_ALIVE_MESSAGE=ON \ + -DBIDIRECTIONAL=ON \ + -DASYNCHRONOUS=ON \ + -DLOW_LEVEL_OPEN_CLOSE=ON \ + -DREGULATORY=ON \ + -DSINGLE_FRAME=ON \ + -DPARAMETERS_CHECK=ON \ + -DCERTIFICATION=ON \ + -DPUBLIC_KEY_CAPABLE=ON \ + -DVERBOSE=ON \ + -DCRC_HW=OFF \ + -DERROR_CODES=ON \ + -DUL_BIT_RATE_BPS=OFF \ + -DT_IFU_MS=OFF \ + -DT_CONF_MS=OFF \ + -DUL_PAYLOAD_SIZE=OFF \ + -DMESSAGE_COUNTER_ROLLOVER=OFF \ + -DERROR_STACK=12 \ + -DSFX_LIB_CORE_PROTOCOL_DIR= .. +$ make precompil_sigfox_ep_addon_rfp +``` + +The precompiled files will be generated in the `build/precompil` folder. + +### Library + +If you want to build a **static library**, you need to run this additionnal **cmake** command: + +```bash +$ make sigfox_ep_addon_rfp +``` + +The archive will be generated in the `build/lib` folder. diff --git a/cmake/precompile_addon_rfp.cmake b/cmake/precompile_addon_rfp.cmake new file mode 100644 index 0000000..809bf77 --- /dev/null +++ b/cmake/precompile_addon_rfp.cmake @@ -0,0 +1,51 @@ +find_program(UNIFDEF unifdef REQUIRED) +if(NOT UNIFDEF) + message(FATAL_ERROR "unifdef not found!") +endif() +find_program(SPLINT splint REQUIRED) +if(NOT SPLINT) + message(FATAL_ERROR "splint not found!") +endif() + +find_program(UNIFDEF unifdef REQUIRED) +if(NOT UNIFDEF) + message(FATAL_ERROR "unifdef not found!") +endif() +find_program(SPLINT splint REQUIRED) +if(NOT SPLINT) + message(FATAL_ERROR "splint not found!") +endif() + + +#List of precompileInc and precompileSrc files +foreach(X IN LISTS ADDON_RFP_SOURCES) + LIST(APPEND PRECOMPIL_ADDON_RFP_SOURCES "${PRECOMPIL_DIR}/${X}") +endforeach() +foreach(X IN LISTS ADDON_RFP_HEADERS) + LIST(APPEND PRECOMPIL_ADDON_RFP_HEADERS "${PRECOMPIL_DIR}/${X}") +endforeach() +foreach(X IN LISTS ADDON_RFP_PUBLIC_HEADERS) + LIST(APPEND PRECOMPIL_ADDON_RFP_PUBLIC_HEADERS "${PRECOMPIL_DIR}/${X}") +endforeach() + +#Custom command Loop for all Sources +foreach(X IN LISTS ADDON_RFP_SOURCES ADDON_RFP_HEADERS) +add_custom_command( + OUTPUT "${PRECOMPIL_DIR}/${X}" + DEPENDS ${CMAKE_BINARY_DIR}/undefs_file + DEPENDS ${CMAKE_BINARY_DIR}/defs_file + DEPENDS ${X} + COMMAND ${CMAKE_COMMAND} -E make_directory ${PRECOMPIL_DIR}/src/tests_mode ${PRECOMPIL_DIR}/inc/tests_mode + COMMAND unifdef -B -k -x 2 -f ${CMAKE_BINARY_DIR}/undefs_file -f ${CMAKE_BINARY_DIR}/defs_file ${PROJECT_SOURCE_DIR}/${X} > "${PRECOMPIL_DIR}/${X}" + VERBATIM +) + +endforeach() +set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1) + +add_custom_target(precompil_${PROJECT_NAME} + DEPENDS precompil + DEPENDS ${PRECOMPIL_ADDON_RFP_SOURCES} + DEPENDS ${PRECOMPIL_ADDON_RFP_HEADERS} + VERBATIM +) diff --git a/docs/images/sigfox_ep_addon_rfp_architecture.png b/docs/images/sigfox_ep_addon_rfp_architecture.png new file mode 100644 index 0000000..c9b74bb Binary files /dev/null and b/docs/images/sigfox_ep_addon_rfp_architecture.png differ diff --git a/inc/sigfox_ep_addon_rfp_api.h b/inc/sigfox_ep_addon_rfp_api.h new file mode 100644 index 0000000..1d2af0b --- /dev/null +++ b/inc/sigfox_ep_addon_rfp_api.h @@ -0,0 +1,207 @@ +/*!***************************************************************** + * \file sigfox_ep_addon_rfp_api.h + * \brief [mandatory]One Line file Description + * \details This file provides firmware functions to manage the following + * functionalities of the Serial Peripheral Interface (SPI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 SIGFOX_EP_ADDON_RFP_API_H_ +#define SIGFOX_EP_ADDON_RFP_API_H_ +#ifdef USE_SIGFOX_EP_FLAGS_H +#include "sigfox_ep_flags.h" +#endif +#include "sigfox_types.h" +#include "sigfox_error.h" +#ifdef CERTIFICATION + + +#ifdef ERROR_CODES +typedef enum { + SIGFOX_EP_ADDON_RFP_API_SUCCESS = 0, + SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER, + SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API, + SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API, + SIGFOX_EP_ADDON_RFP_API_ERROR_STATE, + SIGFOX_EP_ADDON_RFP_API_ERROR_TEST_MODE, + SIGFOX_EP_ADDON_RFP_API_ERROR_TEST_MODE_START, + SIGFOX_EP_ADDON_RFP_API_ERROR_TEST_MODE_PROCESS, +} SIGFOX_EP_ADDON_RFP_API_status_t; +#else +typedef void SIGFOX_EP_ADDON_RFP_API_status_t; +#endif + +#ifdef ASYNCHRONOUS +/*!****************************************************************** + * \brief Sigfox EP ADDON RFP API callback functions. + * \fn SIGFOX_EP_ADDON_RFP_API_process_cb_t: Will be called each time a low level IRQ is handled by the addon library. Warning: runs in a IRQ context. Should only change variables state, and call as soon as possible @ref SIGFOX_EP_ADDON_EP_API_process. + * \fn SIGFOX_EP_ADDON_RFP_API_test_mode_cplt_cb_t: Will be called when the test mode sequence is done. Optional, could be set to NULL. + *******************************************************************/ +typedef void (*SIGFOX_EP_ADDON_RFP_API_process_cb_t)(void); +typedef void (*SIGFOX_EP_ADDON_RFP_API_test_mode_cplt_cb_t)(void); +#endif + +/*!****************************************************************** + * \enum SIGFOX_EP_ADDON_RFP_API_config_t + * \briefS Sigfox EP ADDON RFP configuration structure. + *******************************************************************/ +typedef struct { + const SIGFOX_rc_t *rc; +#ifdef ASYNCHRONOUS + SIGFOX_EP_ADDON_RFP_API_process_cb_t process_cb; +#endif +#ifndef MESSAGE_COUNTER_ROLLOVER + SIGFOX_message_counter_rollover_t message_counter_rollover; +#endif +} SIGFOX_EP_ADDON_RFP_API_config_t; + +/*!****************************************************************** + * \enum SIGFOX_EP_ADDON_RFP_API_test_mode_t + * \brief RF and protocol Test mode type. All tests modes reference are described in Sigfox RF & Protocol Test Specification document chapter 5 (https://support.sigfox.com/docs/rf-protocol-test-specification) + *******************************************************************/ +typedef enum +{ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_C = 0, /*!< Only BPSK with Synchro Bit + Synchro frame + PN sequence : no hopping centered on the TX_frequency */ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_J = 1, /*!< with full protocol with AES key defined at SIGFOX_API_open call: send all SIGFOX protocol frames available with hopping */ +#if defined BIDIRECTIONAL + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_F = 2, /*!< with full protocol with AES key defined at SIGFOX_API_open call: send SIGFOX protocol frames w/ initiate_downlink_flag = SFX_TRUE */ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_D = 3, /*!< with known pattern with SB + SF + Pattern on RX_Frequency defined at SIGFOX_API_open function : od internaly compare re ceived frame <=> known pattern and call sfx_test_report() */ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_E = 4, /*!< Do uplink + downlink frame with AES key defined at SIGFOX_API_open call but specific shorter timings */ +#endif + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_A = 5, /*!< Do 9 uplink frames to measure frequency synthesis step */ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_B = 6, /*!< Call all Sigfox frames of all types and size on all the Sigfox Band */ +#if (defined RC3C) || (defined RC5) + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_G = 11, /*!< Call twice the Sigfox frames (payload 1 bit only) */ +#endif + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_K = 12, /*!< Execute the public key test - all the frames of the protocol needs to be sent */ + SIGFOX_EP_ADDON_RFP_API_TEST_MODE_L = 13, /*!< Execute the nvm test */ +}SIGFOX_EP_ADDON_RFP_API_test_mode_reference_t; + + +/*!****************************************************************** + * \struct SIGFOX_EP_API_control_message_t + * \brief Control message parameters. + *******************************************************************/ +typedef struct { + SIGFOX_EP_ADDON_RFP_API_test_mode_reference_t test_mode_reference; +#ifndef UL_BIT_RATE_BPS + SIGFOX_ul_bit_rate_t ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sfx_s8 tx_power_dbm_eirp; +#endif +#ifdef ASYNCHRONOUS + SIGFOX_EP_ADDON_RFP_API_test_mode_cplt_cb_t test_mode_cplt_cb; +#endif +} SIGFOX_EP_ADDON_RFP_API_test_mode_t; + +/*!****************************************************************** + * \union SIGFOX_EP_API_message_status_t + * \brief Message status bitfield. + *******************************************************************/ +typedef struct { + struct { + unsigned error : 1; + }status; + unsigned progress : 7; +} SIGFOX_EP_ADDON_RFP_API_progress_status_t; + +/*** SIGFOX EP API functions ***/ + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_open(SIGFOX_EP_API_config_t *config) + * \brief Open the EP library. + * \param[in] config: Pointer to the library configuration. + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_open(SIGFOX_EP_ADDON_RFP_API_config_t *config); + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_close(void) + * \brief Close the EP library. + * \param[in] none + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_close(void); + +#ifdef ASYNCHRONOUS +/*!****************************************************************** + * \fn void SIGFOX_EP_ADDON_RFP_API_process(void) + * \brief Main process function of the library. This function should be called as soon as possible when the process callback is triggered. + * \param[in] none + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_process(void); +#endif + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_test_mode() + * \brief This function executes the test modes needed for the Sigfox RF and Protocol Tests. + * \param[in] config: . + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_test_mode(SIGFOX_EP_ADDON_RFP_API_test_mode_t *test_mode); + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_EP_ADDON_RFP_API_get_test_mode_progress_status(void) + * \brief Get the current message status. + * \param[in] none + * \param[out] none + * \retval Curren progress status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_EP_ADDON_RFP_API_get_test_mode_progress_status(void); + + +#ifdef VERBOSE +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_get_version(sfx_u8 **version, sfx_u8 *version_size_char) + * \brief Get EP library version. + * \param[out] version: Version string. + * \param[out] version_size_char: Pointer to the string size. + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_get_version(sfx_u8 **version, sfx_u8 *version_size_char); +#endif + +#else +#error "CERTIFICATION flag must be define for this RFP addon" +#endif +#endif /* SIGFOX_EP_ADDON_RFP_API_H_ */ diff --git a/inc/sigfox_ep_addon_rfp_version.h b/inc/sigfox_ep_addon_rfp_version.h new file mode 100644 index 0000000..cddb03f --- /dev/null +++ b/inc/sigfox_ep_addon_rfp_version.h @@ -0,0 +1,47 @@ +/*!***************************************************************** + * \file sigfox_ep_addon_rfp_version.c + * \brief Sigfox End_Point RF & Protocol version file + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 __SIGFOX_EP_ADDON_RFP_VERSION_H__ +#define __SIGFOX_EP_ADDON_RFP_VERSION_H__ + +#ifdef USE_SIGFOX_EP_FLAGS_H +#include "sigfox_ep_flags.h" +#endif + +/*** Main version ***/ + +#define SIGFOX_EP_ADDON_RFP_VERSION "1.0" + +#endif /* __SIGFOX_EP_ADDON_RFP_VERSION_H__ */ diff --git a/inc/tests_mode/sigfox_rfp_test_mode_types.h b/inc/tests_mode/sigfox_rfp_test_mode_types.h new file mode 100644 index 0000000..8d6c3d6 --- /dev/null +++ b/inc/tests_mode/sigfox_rfp_test_mode_types.h @@ -0,0 +1,79 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_types.h + * \brief RFP test mode types + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 SIGFOX_RFP_TEST_MODE_TYPES_H_ +#define SIGFOX_RFP_TEST_MODE_TYPES_H_ +#ifdef USE_SIGFOX_EP_FLAGS_H +#include "sigfox_ep_flags.h" +#endif +#include "sigfox_types.h" +#include "sigfox_ep_addon_rfp_api.h" +#ifdef CERTIFICATION + +typedef struct { + const SIGFOX_rc_t *rc; +#ifndef UL_BIT_RATE_BPS + SIGFOX_ul_bit_rate_t ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sfx_s8 tx_power_dbm_eirp; +#endif +#ifdef ASYNCHRONOUS + void (*process_cb)(void); + void (*cplt_cb)(void); +#endif +} SIGFOX_RFP_test_mode_t; + +typedef struct { + SIGFOX_EP_ADDON_RFP_API_status_t (*init_fn)(SIGFOX_RFP_test_mode_t *test_mode_callbacks); + SIGFOX_EP_ADDON_RFP_API_status_t (*process_fn)(void); + SIGFOX_EP_ADDON_RFP_API_progress_status_t (*get_progress_status_fn)(void); +} SIGFOX_RFP_test_mode_fn_t; + +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_A_fn; +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_B_fn; +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_C_fn; +#if (defined RC3C) || (defined RC5) +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_G_fn; +#endif +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_J_fn; +#ifdef PUBLIC_KEY_CAPABLE +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_K_fn; +#endif +extern const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_L_fn; + +#endif +#endif /* SIGFOX_RFP_TEST_MODE_TYPES_H_ */ diff --git a/src/sigfox_ep_addon_rfp_api.c b/src/sigfox_ep_addon_rfp_api.c new file mode 100644 index 0000000..6f5ff71 --- /dev/null +++ b/src/sigfox_ep_addon_rfp_api.c @@ -0,0 +1,437 @@ +/*!***************************************************************** + * \file sigfox_ep_addon_rfp_api.c + * \brief Sigfox End-Point RF & Protocol API + * \details This file provides functions to manage RF & Protocol test modes + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "sigfox_ep_addon_rfp_api.h" +#include "sigfox_ep_addon_rfp_version.h" +#include "sigfox_ep_api.h" +#include "tests_mode/sigfox_rfp_test_mode_types.h" +#ifdef CERTIFICATION + +typedef enum { + SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE, + SIGFOX_EP_ADDON_RFP_API_STATE_READY, +#ifdef ASYNCHRONOUS + SIGFOX_EP_ADDON_RFP_API_STATE_PROCESS, +#endif +}SIGFOX_EP_ADDON_RFP_API_state_t; + +#ifdef ASYNCHRONOUS +typedef union { + struct { + // IRQ flags. + unsigned ep_api_process : 1; + unsigned rfp_test_mode_process : 1; + unsigned rfp_test_mode_cplt : 1; + }; + sfx_u8 all; +} SIGFOX_EP_ADDON_RFP_API_flags_t; +#endif + +typedef struct { + const SIGFOX_rc_t *rc; + const SIGFOX_RFP_test_mode_fn_t *test_mode_fn; + SIGFOX_EP_ADDON_RFP_API_state_t state; +#ifdef ASYNCHRONOUS + volatile SIGFOX_EP_ADDON_RFP_API_flags_t flags; + SIGFOX_EP_ADDON_RFP_API_process_cb_t process_cb; + SIGFOX_EP_ADDON_RFP_API_test_mode_cplt_cb_t test_mode_cplt_cb; +#endif +} SIGFOX_EP_ADDON_RFP_API_context_t; + +/*** SIGFOX EP API local global variables ***/ + +static SIGFOX_EP_ADDON_RFP_API_context_t sigfox_ep_addon_rfp_api_ctx = { + .rc = SFX_NULL, + .test_mode_fn = SFX_NULL, + .state = SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE, +#ifdef ASYNCHRONOUS + .flags.ep_api_process = 0, + .flags.rfp_test_mode_process= 0, + .flags.rfp_test_mode_cplt = 0, + .process_cb = SFX_NULL, + .test_mode_cplt_cb = SFX_NULL, +#endif +}; + +/*** SIGFOX EP API local functions ***/ + +/*!****************************************************************** + * \fn void _CHECK_RFP_STATE(expected_state) + * \brief Exit if the library state is not the expected one (given in parameter). + * \param[in] expected_state: Expected state of the library which will be compared to the current. + * \param[out] none + * \retval none + *******************************************************************/ +#define _CHECK_RFP_STATE(state_condition) { if (sigfox_ep_addon_rfp_api_ctx.state state_condition) { EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_STATE); } } + +#ifdef ASYNCHRONOUS +/*!****************************************************************** + * \fn void _SIGFOX_EP_API_process_callback(void) + * \brief Execute the process callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_process_callback(void) { + sigfox_ep_addon_rfp_api_ctx.flags.ep_api_process = 1; + if (sigfox_ep_addon_rfp_api_ctx.process_cb != SFX_NULL) { + sigfox_ep_addon_rfp_api_ctx.process_cb(); + } +} + +/*!****************************************************************** + * \fn static void _SIGFOX_RFP_TEST_MODE_process_callback(void) + * \brief Execute the rfp test mode process callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_RFP_TEST_MODE_process_callback(void) { + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_process = 1; + if (sigfox_ep_addon_rfp_api_ctx.process_cb != SFX_NULL) { + sigfox_ep_addon_rfp_api_ctx.process_cb(); + } +} + +/*!****************************************************************** + * \fn static void _SIGFOX_RFP_TEST_MODE_completion_callback(void) + * \brief Execute the rfp test mode completion callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_RFP_TEST_MODE_completion_callback(void) { + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_cplt = 1; + if (sigfox_ep_addon_rfp_api_ctx.process_cb != SFX_NULL) { + sigfox_ep_addon_rfp_api_ctx.process_cb(); + } +} +#endif + +/*** SIGFOX EP API functions ***/ + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_open(SIGFOX_EP_ADDON_RFP_API_config_t *config) + * \brief Open the RFP addon. + * \param[in] config: Pointer to the rfp addon configuration. + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_open(SIGFOX_EP_ADDON_RFP_API_config_t *config) { + // Local variables. + SIGFOX_EP_API_config_t ep_api_config; +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + // Check RFP ADDON state. + _CHECK_RFP_STATE(!= SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE); + // Open EP library. + ep_api_config.rc = config->rc; +#ifdef ASYNCHRONOUS + ep_api_config.process_cb = &_SIGFOX_EP_API_process_callback; +#endif +#ifndef MESSAGE_COUNTER_ROLLOVER + ep_api_config.message_counter_rollover = config->message_counter_rollover; +#endif + // Open library. +#ifdef ERROR_CODES + ep_api_status = SIGFOX_EP_API_open(&ep_api_config); + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + SIGFOX_EP_API_open(&ep_api_config); +#endif + //Store and configure parameters into static context if no error occurred. + sigfox_ep_addon_rfp_api_ctx.rc = config->rc; +#ifdef ASYNCHRONOUS + sigfox_ep_addon_rfp_api_ctx.process_cb = config->process_cb; +#endif + // Update ADDON RFP state if no error occurred. + sigfox_ep_addon_rfp_api_ctx.state = SIGFOX_EP_ADDON_RFP_API_STATE_READY; +errors: + #ifdef ERROR_CODES + return status; + #else + return; + #endif +} + +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_close(void) { + // Local variables. +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + // Close EP library. +#ifdef ERROR_CODES + ep_api_status = SIGFOX_EP_API_close(); + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + SIGFOX_EP_API_close(); +#endif + //Reset parameters into static context + sigfox_ep_addon_rfp_api_ctx.rc = SFX_NULL; +#ifdef ASYNCHRONOUS + sigfox_ep_addon_rfp_api_ctx.process_cb = SFX_NULL; +#endif + // Update ADDON RFP state if no error occurred. + sigfox_ep_addon_rfp_api_ctx.state = SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE; +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +#ifdef ASYNCHRONOUS +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_process(void) + * \brief Main process function of the RFP addon. + * \brief In asynchronous mode, this function is called by the client when the process callback is triggered. + * \brief In blocking mode, this function is called by the library itself until the requested operation is completed. + * \param[in] none + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_process(void) { + // Local variables. +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + if (sigfox_ep_addon_rfp_api_ctx.flags.ep_api_process == 1) { +#ifdef ERROR_CODES + ep_api_status = SIGFOX_EP_API_process(); + sigfox_ep_addon_rfp_api_ctx.flags.ep_api_process = 0; + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + SIGFOX_EP_API_process(); +#endif + } + + switch(sigfox_ep_addon_rfp_api_ctx.state) { + case SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE : + break; + case SIGFOX_EP_ADDON_RFP_API_STATE_READY : + break; + case SIGFOX_EP_ADDON_RFP_API_STATE_PROCESS : + if (sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_process == 1) { + if (sigfox_ep_addon_rfp_api_ctx.test_mode_fn != SFX_NULL) { +#ifdef ERROR_CODES + status = sigfox_ep_addon_rfp_api_ctx.test_mode_fn->process_fn(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + sigfox_ep_addon_rfp_api_ctx.test_mode_fn->process_fn(); +#endif + } + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_process = 0; + } + if ( sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_cplt == 1) { + + if (sigfox_ep_addon_rfp_api_ctx.test_mode_cplt_cb != SFX_NULL) + sigfox_ep_addon_rfp_api_ctx.test_mode_cplt_cb(); + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_cplt = 0; + sigfox_ep_addon_rfp_api_ctx.state = SIGFOX_EP_ADDON_RFP_API_STATE_READY; + } + break; + default: + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_STATE); + } + RETURN(); +errors: + if (sigfox_ep_addon_rfp_api_ctx.test_mode_cplt_cb != SFX_NULL) + sigfox_ep_addon_rfp_api_ctx.test_mode_cplt_cb(); + sigfox_ep_addon_rfp_api_ctx.state = SIGFOX_EP_ADDON_RFP_API_STATE_READY; + RETURN(); +} +#endif + + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_test_mode(SIGFOX_EP_ADDON_RFP_API_test_mode_t test_mode) + * \brief Execute a specific test mode for RF & Protocol test. + * \param[in] test_mode: Pointer to the test_mode data. + * \param[out] none + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_test_mode(SIGFOX_EP_ADDON_RFP_API_test_mode_t *test_mode) { + // Local variables. +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif + SIGFOX_RFP_test_mode_t rfp_test_mode; + // Check RFP ADDON is opened. + _CHECK_RFP_STATE(!= SIGFOX_EP_ADDON_RFP_API_STATE_READY); + switch (test_mode->test_mode_reference) { + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_A: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_A_fn; + break; + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_B: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_B_fn; + break; + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_C: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_C_fn; + break; +#if defined BIDIRECTIONAL + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_D: + break; + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_E: + break; + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_F: + break; +#endif +#if (defined RC3C) || (defined RC5) + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_G: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_G_fn; + break; +#endif + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_J: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_J_fn; + break; +#ifdef PUBLIC_KEY_CAPABLE + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_K: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_K_fn; + break; +#endif + case SIGFOX_EP_ADDON_RFP_API_TEST_MODE_L: + sigfox_ep_addon_rfp_api_ctx.test_mode_fn = &SIGFOX_RFP_TEST_MODE_L_fn; + break; + default: +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_TEST_MODE) +#else + goto errors; +#endif + } +#ifdef ASYNCHRONOUS + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_process = 0; + sigfox_ep_addon_rfp_api_ctx.flags.rfp_test_mode_cplt = 0; + sigfox_ep_addon_rfp_api_ctx.test_mode_cplt_cb = test_mode->test_mode_cplt_cb; + rfp_test_mode.process_cb =_SIGFOX_RFP_TEST_MODE_process_callback; + rfp_test_mode.cplt_cb = _SIGFOX_RFP_TEST_MODE_completion_callback; +#endif + rfp_test_mode.rc = sigfox_ep_addon_rfp_api_ctx.rc; +#ifndef UL_BIT_RATE_BPS + rfp_test_mode.ul_bit_rate = test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + rfp_test_mode.tx_power_dbm_eirp = test_mode->tx_power_dbm_eirp; +#endif + if (sigfox_ep_addon_rfp_api_ctx.test_mode_fn == SFX_NULL) +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_TEST_MODE) +#else + goto errors; +#endif +#ifdef ERROR_CODES + status = sigfox_ep_addon_rfp_api_ctx.test_mode_fn->init_fn(&rfp_test_mode); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + sigfox_ep_addon_rfp_api_ctx.test_mode_fn->init_fn(&rfp_test_mode); +#endif + +#ifdef ERROR_CODES + status = sigfox_ep_addon_rfp_api_ctx.test_mode_fn->process_fn(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + sigfox_ep_addon_rfp_api_ctx.test_mode_fn->process_fn(); +#endif +#ifdef ASYNCHRONOUS + sigfox_ep_addon_rfp_api_ctx.state = SIGFOX_EP_ADDON_RFP_API_STATE_PROCESS; + if (sigfox_ep_addon_rfp_api_ctx.process_cb == SFX_NULL) { + // Block until library goes back to READY state. + while (sigfox_ep_addon_rfp_api_ctx.state != SIGFOX_EP_ADDON_RFP_API_STATE_READY) { +#ifdef ERROR_CODES + status = SIGFOX_EP_ADDON_RFP_API_process(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else //ERROR_CODES + SIGFOX_EP_API_process(); +#endif + } + } +#else //SYNCHRONOUS + +#endif + RETURN(); +errors: + RETURN(); +} + +/*!****************************************************************** + * \fn SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_EP_ADDON_RFP_API_get_test_mode_progress_status(void) + * \brief Get the current message status. + * \param[in] none + * \param[out] none + * \retval Current progression status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_EP_ADDON_RFP_API_get_test_mode_progress_status(void) +{ + // Local variables. + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; + if(sigfox_ep_addon_rfp_api_ctx.test_mode_fn->get_progress_status_fn != SFX_NULL) + progress_status = sigfox_ep_addon_rfp_api_ctx.test_mode_fn->get_progress_status_fn(); + return progress_status; +} + + +#ifdef VERBOSE +/*!****************************************************************** + * \fn SIGFOX_EP_API_status_t SIGFOX_EP_ADDON_RFP_API_get_version(sfx_u8 **version, sfx_u8 *version_size_char) + * \brief Get EP library version. + * \param[in] version_type: Version to get. + * \param[out] version: Version string. + * \param[out] version_size_char: Pointer to the string size. + * \retval Function execution status. + *******************************************************************/ +SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_EP_ADDON_RFP_API_get_version(sfx_u8 **version, sfx_u8 *version_size_char) { + // Local variables. +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if ((version == SFX_NULL) || (version_size_char == SFX_NULL)) { + EXIT_ERROR(SIGFOX_EP_API_ERROR_NULL_PARAMETER); + } +#endif + // Check library is opened. + _CHECK_RFP_STATE(== SIGFOX_EP_ADDON_RFP_API_STATE_CLOSE); + (*version) = (sfx_u8*) SIGFOX_EP_ADDON_RFP_VERSION; + (*version_size_char) = (sfx_u8) sizeof(SIGFOX_EP_ADDON_RFP_VERSION); +errors: + RETURN(); +} +#endif +#endif //CERTIFICATION diff --git a/src/tests_mode/sigfox_rfp_test_mode_a.c b/src/tests_mode/sigfox_rfp_test_mode_a.c new file mode 100644 index 0000000..429fa3c --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_a.c @@ -0,0 +1,404 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_a.c + * \brief Sigfox addon RF & Protocol test mode A module + * \details Loop (at least) on 9 repetitions of the following : ( initial condition : + * F = Central Uplink Frequency) + * \arg Within a window of 9s, Send one Sigfox frame (repetition 1)** at F. Hz + * \arg Update the frequency F = F + 100Hz + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "manuf/mcu_api.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#ifdef CERTIFICATION + + +#define LOOP 9 +#define WINDOW_TIME_MS 9000 +#define TIMER_INSTANCE MCU_API_TIMER_3 +#define START_PAYLOAD 0x40 + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned mcu_api_timer_cplt : 1; + unsigned test_mode_req : 1; + }flags; + SIGFOX_RFP_test_mode_t test_mode; + sfx_u8 loop_iter; + sfx_u32 frequency; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_A_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_A_get_progress_status_fn(void); + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_A_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_A_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_A_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_A_get_progress_status_fn, +}; + +static SIGFOX_RFP_TEST_MODE_A_context_t sigfox_rfp_test_mode_a_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.mcu_api_timer_cplt = 0, + .flags.test_mode_req = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .loop_iter = 0, + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + +/*!****************************************************************** + * \fn static void _SIGFOX_EP_API_message_cplt_cb(void) + * \brief Message completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_a_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_a_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static void _MCU_API_timer_cplt_cb(void) + * \brief Timer completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _MCU_API_timer_cplt_cb(void) { + sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_a_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_a_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] none + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif + MCU_API_timer_t timer; + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#endif +#else + SIGFOX_EP_API_control_message_t application_message = {0}; +#endif + //Configure application message structure +#ifndef UL_BIT_RATE_BPS + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_a_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_a_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 1; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = 500; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +#endif + // application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; + // application_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = sigfox_rfp_test_mode_a_ctx.frequency; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) + data[data_cnt] = START_PAYLOAD + data_cnt; + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; + application_message.ul_payload_size_bytes = 0; + application_message.ul_payload = SFX_NULL; +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; + timer.cplt_cb = &_MCU_API_timer_cplt_cb; +#endif + //Configure timer structure + timer.duration_ms = WINDOW_TIME_MS; + timer.instance = TIMER_INSTANCE; + //Start timer and send Application message +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_start(&timer); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + MCU_API_timer_start(&timer); +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_wait_cplt(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_wait_cplt(TIMER_INSTANCE); +#endif + _MCU_API_timer_cplt_cb(); + +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode A. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt =0; + sigfox_rfp_test_mode_a_ctx.loop_iter = 0; + sigfox_rfp_test_mode_a_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_a_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_a_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_a_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_a_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_a_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_a_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_a_ctx.flags.test_mode_req = 1; + sigfox_rfp_test_mode_a_ctx.frequency = sigfox_rfp_test_mode_a_ctx.test_mode.rc->f_ul_hz; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_A_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + if (sigfox_rfp_test_mode_a_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_a_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if ((sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt == 1) && + (sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt == 1)) { + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt = 0; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + sigfox_rfp_test_mode_a_ctx.loop_iter++; + tmp = 100 * (sigfox_rfp_test_mode_a_ctx.loop_iter); + tmp /= LOOP; + sigfox_rfp_test_mode_a_ctx.progress_status.progress = (sfx_u8)tmp; + if (sigfox_rfp_test_mode_a_ctx.loop_iter < LOOP) { + sigfox_rfp_test_mode_a_ctx.frequency += 100; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } else { + if (sigfox_rfp_test_mode_a_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_a_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_a_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_a_ctx.loop_iter < LOOP) { + if (sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if ((sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt == 1) && + (sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt == 1)) { + sigfox_rfp_test_mode_a_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_a_ctx.flags.mcu_api_timer_cplt = 0; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + sigfox_rfp_test_mode_a_ctx.loop_iter++; + if (sigfox_rfp_test_mode_a_ctx.loop_iter < LOOP) { + sigfox_rfp_test_mode_a_ctx.frequency += 100; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } + } + } + sigfox_rfp_test_mode_a_ctx.progress_status.progress = 100; +#endif + RETURN(); +errors: + sigfox_rfp_test_mode_a_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + MCU_API_timer_stop(TIMER_INSTANCE); + sigfox_rfp_test_mode_a_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_A_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_A_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_a_ctx.progress_status; +} +#endif diff --git a/src/tests_mode/sigfox_rfp_test_mode_b.c b/src/tests_mode/sigfox_rfp_test_mode_b.c new file mode 100644 index 0000000..c6280aa --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_b.c @@ -0,0 +1,458 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_b.c + * \brief Sigfox addon RF & Protocol test mode B module + * \details Loop (at least) on 300 repetitions of the following : + * \arg Start a 18s timer. + * \arg Within the 12s after the start of the timer, Send one of the supported types of Sigfox messages*. + * \arg Wait for the end of this 18s before sending a new message. + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "manuf/mcu_api.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#ifdef CERTIFICATION + + +#define LOOP 100 +#define CNT_MESSAGE_LOOP 3 +#define WINDOW_TIME_MS 18000 +#define TIMER_INSTANCE MCU_API_TIMER_3 +#define START_PAYLOAD 0x40 + + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned mcu_api_timer_cplt : 1; + unsigned test_mode_req : 1; + }flags; + SIGFOX_RFP_test_mode_t test_mode; + sfx_u16 loop_iter; + sfx_u16 cnt_message; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_B_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_B_get_progress_status_fn(void); + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_B_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_B_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_B_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_B_get_progress_status_fn, +}; + +static SIGFOX_RFP_TEST_MODE_B_context_t sigfox_rfp_test_mode_b_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.mcu_api_timer_cplt = 0, + .flags.test_mode_req = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .loop_iter = 0, + .cnt_message = 0, + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + +/*!****************************************************************** + * \fn static void _SIGFOX_EP_API_message_cplt_cb(void) + * \brief Message completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_b_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_b_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static void _MCU_API_timer_cplt_cb(void) + * \brief Timer completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _MCU_API_timer_cplt_cb(void) { + sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_b_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_b_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] none + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#endif +#else + SIGFOX_EP_API_control_message_t application_message = {0}; +#endif + + //Configure application message structure +#ifndef UL_BIT_RATE_BPS + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_b_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_b_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 1; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = 500; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +#endif +// application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +// application_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = 0; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for(data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) + data[data_cnt] = START_PAYLOAD + data_cnt; + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; + application_message.ul_payload_size_bytes = 0; + application_message.ul_payload = SFX_NULL; +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; +#endif + //Send Application message +#ifdef ERROR_CODES +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +static SIGFOX_EP_ADDON_RFP_API_status_t _start_timer(void) { + // Local variables. +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif + MCU_API_timer_t timer; + //Configure timer structure + timer.duration_ms = WINDOW_TIME_MS; + timer.instance = TIMER_INSTANCE; +#ifdef ASYNCHRONOUS + timer.cplt_cb = &_MCU_API_timer_cplt_cb; +#endif +#ifdef ERROR_CODES + //Start timer + mcu_status = MCU_API_timer_start(&timer); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_start(&timer); +#endif +#ifdef ERROR_CODES + errors: +#endif + RETURN(); +} + + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode A. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt =0; + sigfox_rfp_test_mode_b_ctx.loop_iter = 0; + sigfox_rfp_test_mode_b_ctx.cnt_message = 0; + sigfox_rfp_test_mode_b_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_b_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_b_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_b_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_b_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_b_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_b_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_b_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_B_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + if (sigfox_rfp_test_mode_b_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_b_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _start_timer(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _start_timer(); + _send_application_message(); +#endif + + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_b_ctx.cnt_message++; + if (sigfox_rfp_test_mode_b_ctx.cnt_message < CNT_MESSAGE_LOOP) { +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } + } + if ((sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt == 1) && + (sigfox_rfp_test_mode_b_ctx.cnt_message >= CNT_MESSAGE_LOOP)) { + sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt = 0; + sigfox_rfp_test_mode_b_ctx.cnt_message = 0; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + sigfox_rfp_test_mode_b_ctx.loop_iter++; + tmp = 100 * (sigfox_rfp_test_mode_b_ctx.loop_iter); + tmp /= LOOP; + sigfox_rfp_test_mode_b_ctx.progress_status.progress = (sfx_u8)tmp; + if (sigfox_rfp_test_mode_b_ctx.loop_iter < LOOP) { +#ifdef ERROR_CODES + status = _start_timer(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _start_timer(); + _send_application_message(); +#endif + } else { + if (sigfox_rfp_test_mode_b_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_b_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_b_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_b_ctx.loop_iter < LOOP) { + if (sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_b_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_b_ctx.cnt_message++; + if (sigfox_rfp_test_mode_b_ctx.cnt_message < CNT_MESSAGE_LOOP) { +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } else { +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_wait_cplt(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_wait_cplt(TIMER_INSTANCE); +#endif + _MCU_API_timer_cplt_cb(); + } + } + if ((sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt == 1) && + (sigfox_rfp_test_mode_b_ctx.cnt_message >= CNT_MESSAGE_LOOP)) { + sigfox_rfp_test_mode_b_ctx.flags.mcu_api_timer_cplt = 0; + sigfox_rfp_test_mode_b_ctx.cnt_message = 0; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + sigfox_rfp_test_mode_b_ctx.loop_iter++; + if (sigfox_rfp_test_mode_b_ctx.loop_iter < LOOP) { +#ifdef ERROR_CODES + status = _start_timer(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _start_timer(); + _send_application_message(); +#endif + } + } + } + sigfox_rfp_test_mode_b_ctx.progress_status.progress = 100; +#endif + + RETURN(); +errors: + sigfox_rfp_test_mode_b_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + MCU_API_timer_stop(TIMER_INSTANCE); + sigfox_rfp_test_mode_b_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_B_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_B_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_b_ctx.progress_status; +} +#endif diff --git a/src/tests_mode/sigfox_rfp_test_mode_c.c b/src/tests_mode/sigfox_rfp_test_mode_c.c new file mode 100644 index 0000000..99f5e0c --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_c.c @@ -0,0 +1,375 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_c.c + * \brief Sigfox addon RF & Protocol test mode C module + * \details In case of SINGLE-FRAME UUT : + * + * \arg f_ul_hz; + test_param.tx_frequency_hz = sigfox_rfp_test_mode_c_ctx.test_mode.rc->f_ul_hz; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) { + data[data_cnt] = (sfx_u8)0xAA; + } + application_message.ul_payload = data; +#endif +#else + application_message.ul_payload_size_bytes = SIGFOX_UL_PAYLOAD_MAX_SIZE_BYTES; + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < SIGFOX_UL_PAYLOAD_MAX_SIZE_BYTES; data_cnt++) { + data[data_cnt] = (sfx_u8)0xAA; + } + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; +#endif + + //Send Application message +#ifdef ERROR_CODES +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_start_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode C. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_c_ctx.loop_iter = 0; + sigfox_rfp_test_mode_c_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_c_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_c_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_c_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_c_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_c_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_c_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_c_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + + if (sigfox_rfp_test_mode_c_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_c_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_c_ctx.loop_iter++; + if (sigfox_rfp_test_mode_c_ctx.loop_iter < LOOP) { + tmp = 100 * (sigfox_rfp_test_mode_c_ctx.loop_iter); + tmp /= LOOP; + sigfox_rfp_test_mode_c_ctx.progress_status.progress = (sfx_u8)tmp; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } else { + if (sigfox_rfp_test_mode_c_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_c_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_c_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_c_ctx.loop_iter < LOOP) { + if (sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_c_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_c_ctx.loop_iter++; + if (sigfox_rfp_test_mode_c_ctx.loop_iter < LOOP) { +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } + } + } + sigfox_rfp_test_mode_c_ctx.progress_status.progress = 100; +#endif + + RETURN(); +errors: + sigfox_rfp_test_mode_c_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + sigfox_rfp_test_mode_c_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_C_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_C_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_c_ctx.progress_status; +} +#endif //CERTIFICATION diff --git a/src/tests_mode/sigfox_rfp_test_mode_g.c b/src/tests_mode/sigfox_rfp_test_mode_g.c new file mode 100644 index 0000000..9d68907 --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_g.c @@ -0,0 +1,351 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_g.c + * \brief Sigfox addon RF & Protocol test mode G module + * \details Send twice, one of the supported types of Sigfox messages + * ( Uplink request only ) with no delay between the messages. + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#if (defined CERTIFICATION) && ( (defined SPECTRUM_ACCESS_LBT)) + +#ifndef SINGLE_FRAME + #define LOOP 2 + #ifndef T_IFU_MS + #define INTERFRAME_MS 1000 + #endif +#else + #define LOOP 2 +#endif + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned test_mode_req : 1; + }flags; + SIGFOX_RFP_test_mode_t test_mode; + sfx_u8 loop_iter; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_G_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_G_get_progress_status_fn(void); + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_G_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_G_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_G_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_G_get_progress_status_fn, +}; + +static SIGFOX_RFP_TEST_MODE_G_context_t sigfox_rfp_test_mode_g_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.test_mode_req = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .loop_iter = 0, + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + +/*!****************************************************************** + * \fn static void _SIGFOX_RFP_TEST_MODE_completion_callback(void) + * \brief Execute the rfp test mode completion callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_g_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_g_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] none + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#endif +#else + SIGFOX_EP_API_control_message_t application_message = {0}; +#endif + //Configure application message structure +#ifndef UL_BIT_RATE_BPS + /*TODO manage 100/600*/ + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_g_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_g_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 3; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = INTERFRAME_MS; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +#endif + // application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; + // application_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = 0; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_TRUE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) { + data[data_cnt] = (sfx_u8)0xAA; + } + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; +#endif + + //Send Application message +#ifdef ERROR_CODES +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_start_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode C. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_g_ctx.loop_iter = 0; + sigfox_rfp_test_mode_g_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_g_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_g_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_g_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_g_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_g_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_g_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_g_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_G_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + + if (sigfox_rfp_test_mode_g_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_g_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_g_ctx.loop_iter++; + if (sigfox_rfp_test_mode_g_ctx.loop_iter < LOOP) { + tmp = 100 * (sigfox_rfp_test_mode_g_ctx.loop_iter); + tmp /= LOOP; + sigfox_rfp_test_mode_g_ctx.progress_status.progress = (sfx_u8)tmp; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } else { + if (sigfox_rfp_test_mode_g_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_g_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_g_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_g_ctx.loop_iter < LOOP) { + if (sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_g_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_g_ctx.loop_iter++; + if (sigfox_rfp_test_mode_g_ctx.loop_iter < LOOP) { +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } + } + } + sigfox_rfp_test_mode_g_ctx.progress_status.progress = 100; +#endif + + RETURN(); +errors: + sigfox_rfp_test_mode_g_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + sigfox_rfp_test_mode_g_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_G_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_G_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_g_ctx.progress_status; +} +#endif //CERTIFICATION diff --git a/src/tests_mode/sigfox_rfp_test_mode_j.c b/src/tests_mode/sigfox_rfp_test_mode_j.c new file mode 100644 index 0000000..c785c85 --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_j.c @@ -0,0 +1,535 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_j.c + * \brief Sigfox addon RF & Protocol test mode J module + * \details Send all supported types of Sigfox messages with all possible sizes. + * Each message has to be send following the below procedure : + * \arg Start a 18s timer. + * \arg Wait for the end of this 18s before sending a new message. + * + * Sigfox messages could be : + * \arg Send bit (0 or 1). + * \arg Keep-Alive Control Message. + * \arg Send Frame (12 different payload), payload has to be set to 0x40 + byte index. + * \arg Send Frame (no payload). + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "manuf/mcu_api.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#ifdef CERTIFICATION + +#define WINDOW_TIME_MS 18000 +#define TIMER_INSTANCE MCU_API_TIMER_3 +#define START_PAYLOAD 0x40 + +typedef struct test_mode_c_message_s test_mode_c_message_t; +typedef struct test_mode_c_message_s { + SIGFOX_EP_ADDON_RFP_API_status_t (*send_ptr)(const test_mode_c_message_t *test_mode_c_message); +#ifndef UL_PAYLOAD_SIZE + sfx_u8 size; +#endif + union { +#ifdef APPLICATION_MESSAGES + SIGFOX_application_message_type_t message_type; +#endif +#ifdef CONTROL_KEEP_ALIVE_MESSAGE + SIGFOX_control_message_type_t control_type; +#endif + }type; +}test_mode_c_message_t; + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned mcu_api_timer_cplt : 1; + unsigned test_mode_req : 1; + }flags; + sfx_u8 message_list_idx; + SIGFOX_RFP_test_mode_t test_mode; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_J_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_J_get_progress_status_fn(void); +#ifdef CONTROL_KEEP_ALIVE_MESSAGE +static SIGFOX_EP_ADDON_RFP_API_status_t _send_control_message(const test_mode_c_message_t *test_mode_c_message); +#endif +#ifdef APPLICATION_MESSAGES +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(const test_mode_c_message_t *test_mode_c_message); +#endif + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_J_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_J_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_J_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_J_get_progress_status_fn, +}; + +static const test_mode_c_message_t MESSAGE_LIST[] = { +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + {&_send_application_message, {SIGFOX_APPLICATION_MESSAGE_TYPE_BIT0}}, + {&_send_application_message, {SIGFOX_APPLICATION_MESSAGE_TYPE_BIT1}}, + {&_send_application_message, {SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY}}, + +#else + {&_send_application_message, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, +#endif +#else + {&_send_application_message, 0, {SIGFOX_APPLICATION_MESSAGE_TYPE_BIT0}}, + {&_send_application_message, 0, {SIGFOX_APPLICATION_MESSAGE_TYPE_BIT1}}, + {&_send_application_message, 1, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 2, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 3, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 4, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 5, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 6, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 7, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 8, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 9, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 10, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 11, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 12, {SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY}}, + {&_send_application_message, 0, {SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY}}, +#endif +#endif +#ifdef CONTROL_KEEP_ALIVE_MESSAGE +#ifdef UL_PAYLOAD_SIZE + {&_send_control_message, {SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE}}, +#else + {&_send_control_message, 0, {SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE}}, +#endif +#endif +}; + +static SIGFOX_RFP_TEST_MODE_J_context_t sigfox_rfp_test_mode_j_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.mcu_api_timer_cplt = 0, + .flags.test_mode_req = 0, + .message_list_idx = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + + +/*!****************************************************************** + * \fn static void _SIGFOX_EP_API_message_cplt_cb(void) + * \brief Message completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_j_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_j_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static void _MCU_API_timer_cplt_cb(void) + * \brief Timer completion callback. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _MCU_API_timer_cplt_cb(void) { + sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_j_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_j_ctx.test_mode.process_cb(); +#endif +} + +#ifdef CONTROL_KEEP_ALIVE_MESSAGE +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_control_message(const test_mode_c_message_t *test_mode_c_message) { + * \brief Send control message + * \param[in] test_mode_c_message: message to send + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_control_message(const test_mode_c_message_t *test_mode_c_message) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif + MCU_API_timer_t timer; + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; + SIGFOX_EP_API_control_message_t control_message = {0}; + //Configure control message structure +#ifndef UL_BIT_RATE_BPS + /*TODO manage 100/600*/ + control_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_j_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + control_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_j_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + control_message.common_parameters.number_of_frames = 3; +#ifndef T_IFU_MS + control_message.common_parameters.t_ifu_ms = 500; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + control_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +#endif +// control_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +// control_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = 0; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif + control_message.type = test_mode_c_message->type.control_type; +#ifdef ASYNCHRONOUS + control_message.uplink_cplt_cb = SFX_NULL; + control_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; + timer.cplt_cb = &_MCU_API_timer_cplt_cb; +#endif + //Configure timer structure + timer.duration_ms = WINDOW_TIME_MS; + timer.instance = TIMER_INSTANCE; + //Configure timer and send control message +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_start(&timer); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&control_message, &test_param); + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + MCU_API_timer_start(&timer); + SIGFOX_EP_API_TEST_send_control_message(&control_message, &test_param); +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_wait_cplt(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_wait_cplt(TIMER_INSTANCE); +#endif + _MCU_API_timer_cplt_cb(); + +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} +#endif +#ifdef APPLICATION_MESSAGES +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] test_mode_c_message: message to send + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(const test_mode_c_message_t *test_mode_c_message) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif + MCU_API_timer_t timer; + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#else + sfx_u8 data_cnt; + sfx_u8 data[SIGFOX_UL_PAYLOAD_MAX_SIZE_BYTES] = {0x00}; +#endif + //Configure control message structure +#ifndef UL_BIT_RATE_BPS + /*TODO manage 100/600*/ + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_j_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_j_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 3; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = 500; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +#endif +// application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +// application_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = 0; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif + application_message.type = test_mode_c_message->type.message_type; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE > 0) + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) + data[data_cnt] = START_PAYLOAD + data_cnt; + application_message.ul_payload = data; +#endif +#else + application_message.ul_payload_size_bytes = test_mode_c_message->size; + for (data_cnt = 0; data_cnt < test_mode_c_message->size; data_cnt++) + data[data_cnt] = START_PAYLOAD + data_cnt; + application_message.ul_payload = data; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; + timer.cplt_cb = &_MCU_API_timer_cplt_cb; +#endif + //Configure timer structure + timer.duration_ms = WINDOW_TIME_MS; + timer.instance = TIMER_INSTANCE; + //Start timer and send Application message +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_start(&timer); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else + MCU_API_timer_start(&timer); + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_wait_cplt(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_wait_cplt(TIMER_INSTANCE); +#endif + _MCU_API_timer_cplt_cb(); + +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} +#endif + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode A. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt = 0; + sigfox_rfp_test_mode_j_ctx.message_list_idx = 0; + sigfox_rfp_test_mode_j_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_j_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_j_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_j_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_j_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_j_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_j_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_j_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_J_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + MCU_API_status_t mcu_status = MCU_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + + if (sigfox_rfp_test_mode_j_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_j_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if ( (sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt == 1) && + (sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt == 1)) { + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt = 0; + sigfox_rfp_test_mode_j_ctx.message_list_idx++; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + if (sigfox_rfp_test_mode_j_ctx.message_list_idx < sizeof(MESSAGE_LIST) / sizeof(test_mode_c_message_t)) { + tmp = 100 * (sigfox_rfp_test_mode_j_ctx.message_list_idx); + tmp /= (sizeof(MESSAGE_LIST) / sizeof(test_mode_c_message_t)); + sigfox_rfp_test_mode_j_ctx.progress_status.progress = (sfx_u8)tmp; +#ifdef ERROR_CODES + + status = MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); +#endif + } else { + if (sigfox_rfp_test_mode_j_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_j_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_j_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_j_ctx.message_list_idx < sizeof(MESSAGE_LIST) / sizeof(test_mode_c_message_t)) { + if (sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if ((sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt == 1) && + (sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt == 1)) { + sigfox_rfp_test_mode_j_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_j_ctx.flags.mcu_api_timer_cplt = 0; +#ifdef ERROR_CODES + mcu_status = MCU_API_timer_stop(TIMER_INSTANCE); + MCU_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_MCU_API); +#else + MCU_API_timer_stop(TIMER_INSTANCE); +#endif + sigfox_rfp_test_mode_j_ctx.message_list_idx++; + if (sigfox_rfp_test_mode_j_ctx.message_list_idx < sizeof(MESSAGE_LIST) / sizeof(test_mode_c_message_t)) { +#ifdef ERROR_CODES + status = MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx].send_ptr(&MESSAGE_LIST[sigfox_rfp_test_mode_j_ctx.message_list_idx]); +#endif + } + } + } + sigfox_rfp_test_mode_j_ctx.progress_status.progress = 100; +#endif + RETURN(); +errors: + sigfox_rfp_test_mode_j_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + MCU_API_timer_stop(TIMER_INSTANCE); + sigfox_rfp_test_mode_j_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_J_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_J_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_j_ctx.progress_status; +} +#endif diff --git a/src/tests_mode/sigfox_rfp_test_mode_k.c b/src/tests_mode/sigfox_rfp_test_mode_k.c new file mode 100644 index 0000000..ed7f109 --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_k.c @@ -0,0 +1,321 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_k.c + * \brief Sigfox addon RF & Protocol test mode K module + * \details \arg Switch the device in public key + * + * \arg Send one of the supported types of Sigfox messages* without downlink request + * + * \arg Switch the device back to private key. + * + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#if (defined CERTIFICATION) && (defined PUBLIC_KEY_CAPABLE) + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned test_mode_req : 1; + }flags; + SIGFOX_RFP_test_mode_t test_mode; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_C_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_K_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_K_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_K_get_progress_status_fn(void); + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_K_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_K_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_K_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_K_get_progress_status_fn, +}; + +static SIGFOX_RFP_TEST_MODE_C_context_t sigfox_rfp_test_mode_k_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.test_mode_req = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + +/*!****************************************************************** + * \fn static void _SIGFOX_RFP_TEST_MODE_completion_callback(void) + * \brief Execute the rfp test mode completion callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_k_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_k_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] none + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#endif +#else + SIGFOX_EP_API_control_message_t application_message = {0}; +#endif + //Configure application message structure +#ifndef UL_BIT_RATE_BPS + /*TODO manage 100/600*/ + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_k_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_k_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 3; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = 1000; +#endif +#endif +#ifdef PUBLIC_KEY_CAPABLE + application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PUBLIC; +#endif +// application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PUBLIC; +// application_message.common_parameters.tx_frequency_hz = sigfox_rfp_test_mode_k_ctx.test_mode.rc->f_ul_hz; + test_param.tx_frequency_hz = sigfox_rfp_test_mode_k_ctx.test_mode.rc->f_ul_hz;; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) { + data[data_cnt] = (sfx_u8)0xAA; + } + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; + +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; +#endif + + //Send Application message +#ifdef ERROR_CODES +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_start_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode C. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_K_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_k_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_k_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_k_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_k_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_k_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_k_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_k_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_k_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_C_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_K_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif + + if (sigfox_rfp_test_mode_k_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_k_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_k_ctx.progress_status.progress = 100; + if (sigfox_rfp_test_mode_k_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_k_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_k_ctx.test_mode.cplt_cb(); + } + } + } +#else + while(1) { + if (sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_k_ctx.flags.ep_api_message_cplt = 0; + break; + } + } + sigfox_rfp_test_mode_k_ctx.progress_status.progress = 100; +#endif + + RETURN(); +errors: + sigfox_rfp_test_mode_k_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + sigfox_rfp_test_mode_k_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_C_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_K_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_k_ctx.progress_status; +} +#endif //CERTIFICATION diff --git a/src/tests_mode/sigfox_rfp_test_mode_l.c b/src/tests_mode/sigfox_rfp_test_mode_l.c new file mode 100644 index 0000000..d9a88a9 --- /dev/null +++ b/src/tests_mode/sigfox_rfp_test_mode_l.c @@ -0,0 +1,350 @@ +/*!***************************************************************** + * \file sigfox_rfp_test_mode_l.c + * \brief Sigfox addon RF & Protocol test mode L module + * \details In case of multiFrame feature : + * \arg Send one of the supported types of Sigfox messages* without downlink request + * + * In case of singleFrame feature : Loop on 3 repetitions of the following : + * \arg Send one of the supported types of Sigfox messages*without downlink request + ******************************************************************* + * \copyright + * + * Copyright (c) 2022, UnaBiz SAS + * 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 UnaBiz SAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY + * THIS LICENSE. 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 "tests_mode/sigfox_rfp_test_mode_types.h" +#include "sigfox_error.h" +#include "sigfox_ep_api_test.h" +#ifdef CERTIFICATION + +#ifndef SINGLE_FRAME + #define LOOP 1 + #ifndef T_IFU_MS + #define INTERFRAME_MS 1000 + #endif +#else + #define LOOP 3 +#endif + +typedef struct { + struct { + unsigned ep_api_message_cplt : 1; + unsigned ep_api_message_error : 1; + unsigned test_mode_req : 1; + }flags; + SIGFOX_RFP_test_mode_t test_mode; + sfx_u8 loop_iter; + SIGFOX_EP_ADDON_RFP_API_progress_status_t progress_status; +}SIGFOX_RFP_TEST_MODE_L_context_t; + +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_init_fn(SIGFOX_RFP_test_mode_t *test_mode_callback); +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_process_fn(void); +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_L_get_progress_status_fn(void); + +const SIGFOX_RFP_test_mode_fn_t SIGFOX_RFP_TEST_MODE_L_fn = { + .init_fn = &SIGFOX_RFP_TEST_MODE_L_init_fn, + .process_fn = &SIGFOX_RFP_TEST_MODE_L_process_fn, + .get_progress_status_fn = &SIGFOX_RFP_TEST_MODE_L_get_progress_status_fn, +}; + +static SIGFOX_RFP_TEST_MODE_L_context_t sigfox_rfp_test_mode_l_ctx = { + .flags.ep_api_message_cplt = 0, + .flags.ep_api_message_error = 0, + .flags.test_mode_req = 0, + .test_mode.rc = SFX_NULL, +#ifndef UL_BIT_RATE_BPS + .test_mode.ul_bit_rate = 0, +#endif +#ifndef TX_POWER_DBM_EIRP + .test_mode.tx_power_dbm_eirp = 0, +#endif +#ifdef ASYNCHRONOUS + .test_mode.process_cb = SFX_NULL, + .test_mode.cplt_cb = SFX_NULL, +#endif + .loop_iter = 0, + .progress_status.status.error = 0, + .progress_status.progress = 0, +}; + +/*!****************************************************************** + * \fn static void _SIGFOX_RFP_TEST_MODE_completion_callback(void) + * \brief Execute the rfp test mode completion callback if the not null. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static void _SIGFOX_EP_API_message_cplt_cb(void) { + // Local variables. + SIGFOX_EP_API_message_status_t message_status; + message_status = SIGFOX_EP_API_get_message_status(); + if (message_status.app_frame_1 == 1) { + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt = 1; + } + if (message_status.error == 1) + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error = 1; +#ifdef ASYNCHRONOUS + if (sigfox_rfp_test_mode_l_ctx.test_mode.process_cb != SFX_NULL) + sigfox_rfp_test_mode_l_ctx.test_mode.process_cb(); +#endif +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) + * \brief Send application message + * \param[in] none + * \param[out] none + * \retval SIGFOX_EP_ADDON_RFP_API_status_t + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t _send_application_message(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; + SIGFOX_EP_API_status_t ep_api_status = SIGFOX_EP_API_SUCCESS; +#endif + SIGFOX_EP_API_TEST_parameters_t test_param = {0}; +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_application_message_t application_message = {0}; +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE != 0) + sfx_u8 data_cnt; + sfx_u8 data[UL_PAYLOAD_SIZE] = {0x00}; +#endif +#endif +#else + SIGFOX_EP_API_control_message_t application_message = {0}; +#endif + //Configure application message structure +#ifndef UL_BIT_RATE_BPS + application_message.common_parameters.ul_bit_rate = sigfox_rfp_test_mode_l_ctx.test_mode.ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + application_message.common_parameters.tx_power_dbm_eirp = sigfox_rfp_test_mode_l_ctx.test_mode.tx_power_dbm_eirp; +#endif +#ifndef SINGLE_FRAME + application_message.common_parameters.number_of_frames = 3; +#ifndef T_IFU_MS + application_message.common_parameters.t_ifu_ms = INTERFRAME_MS; +#endif +#endif +// application_message.common_parameters.ep_key_type = SIGFOX_EP_KEY_PRIVATE; +// application_message.common_parameters.tx_frequency_hz = 0; + test_param.tx_frequency_hz = 0; +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_FH) + test_param.fh_timer_enable = SFX_FALSE; +#endif +#if (defined REGULATORY) && (defined SPECTRUM_ACCESS_LBT) + test_param.lbt_enable = SFX_FALSE; +#endif +#ifdef APPLICATION_MESSAGES +#ifdef UL_PAYLOAD_SIZE +#if (UL_PAYLOAD_SIZE == 0) + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_BYTE_ARRAY; + for (data_cnt = 0; data_cnt < UL_PAYLOAD_SIZE; data_cnt++) { + data[data_cnt] = (sfx_u8)0xAA; + } + application_message.ul_payload = data; +#endif +#else + application_message.type = SIGFOX_APPLICATION_MESSAGE_TYPE_EMPTY; +#endif +#else + application_message.type = SIGFOX_CONTROL_MESSAGE_TYPE_KEEP_ALIVE; +#endif +#ifdef ASYNCHRONOUS + application_message.uplink_cplt_cb = SFX_NULL; + application_message.message_cplt_cb = &_SIGFOX_EP_API_message_cplt_cb; +#endif + + //Send Application message +#ifdef ERROR_CODES +#ifdef APPLICATION_MESSAGES + ep_api_status = SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + ep_api_status = SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif + SIGFOX_EP_API_check_status(SIGFOX_EP_ADDON_RFP_API_ERROR_EP_API); +#else +#ifdef APPLICATION_MESSAGES + SIGFOX_EP_API_TEST_send_application_message(&application_message, &test_param); +#else + SIGFOX_EP_API_TEST_send_control_message(&application_message, &test_param); +#endif +#endif +#ifndef ASYNCHRONOUS + _SIGFOX_EP_API_message_cplt_cb(); +#endif +#ifdef ERROR_CODES +errors: +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_start_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) + * \brief Start Test Mode C. + * \param[in] rfp_test_mode: test mode parameters + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_init_fn(SIGFOX_RFP_test_mode_t *rfp_test_mode) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef PARAMETERS_CHECK + if (rfp_test_mode == SFX_NULL) { +#ifdef ERROR_CODES + EXIT_ERROR(SIGFOX_EP_ADDON_RFP_API_ERROR_NULL_PARAMETER); +#else + goto errors; +#endif + } +#endif /* PARAMETERS_CHECK */ + //Reset static context + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error = 0; + sigfox_rfp_test_mode_l_ctx.loop_iter = 0; + sigfox_rfp_test_mode_l_ctx.progress_status.status.error = 0; + sigfox_rfp_test_mode_l_ctx.progress_status.progress = 0; + // Store test mode parameters locally. + sigfox_rfp_test_mode_l_ctx.test_mode.rc = rfp_test_mode->rc; +#ifndef UL_BIT_RATE_BPS + sigfox_rfp_test_mode_l_ctx.test_mode.ul_bit_rate = rfp_test_mode->ul_bit_rate; +#endif +#ifndef TX_POWER_DBM_EIRP + sigfox_rfp_test_mode_l_ctx.test_mode.tx_power_dbm_eirp = rfp_test_mode->tx_power_dbm_eirp, +#endif +#ifdef ASYNCHRONOUS + sigfox_rfp_test_mode_l_ctx.test_mode.process_cb = rfp_test_mode->process_cb; + sigfox_rfp_test_mode_l_ctx.test_mode.cplt_cb = rfp_test_mode->cplt_cb; +#endif + sigfox_rfp_test_mode_l_ctx.flags.test_mode_req = 1; +#ifdef PARAMETERS_CHECK +errors: +#endif + RETURN(); +} + + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_process_fn(void) + * \brief Process Test Mode C. + * \param[in] none + * \param[out] none + * \retval none + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_status_t SIGFOX_RFP_TEST_MODE_L_process_fn(void) { +#ifdef ERROR_CODES + SIGFOX_EP_ADDON_RFP_API_status_t status = SIGFOX_EP_ADDON_RFP_API_SUCCESS; +#endif +#ifdef ASYNCHRONOUS + sfx_u16 tmp; +#endif + + if (sigfox_rfp_test_mode_l_ctx.flags.test_mode_req == 1) { + sigfox_rfp_test_mode_l_ctx.flags.test_mode_req = 0; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } +#ifdef ASYNCHRONOUS + else { + if (sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_l_ctx.loop_iter++; + if (sigfox_rfp_test_mode_l_ctx.loop_iter < LOOP) { + tmp = 100 * (sigfox_rfp_test_mode_l_ctx.loop_iter); + tmp /= LOOP; + sigfox_rfp_test_mode_l_ctx.progress_status.progress = (sfx_u8)tmp; +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } else { + if (sigfox_rfp_test_mode_l_ctx.test_mode.cplt_cb != SFX_NULL) { + sigfox_rfp_test_mode_l_ctx.progress_status.progress = 100; + sigfox_rfp_test_mode_l_ctx.test_mode.cplt_cb(); + } + } + } + } +#else + while(sigfox_rfp_test_mode_l_ctx.loop_iter < LOOP) { + if (sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error == 1) { + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_error = 0; + goto errors; + } + if (sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt == 1) { + sigfox_rfp_test_mode_l_ctx.flags.ep_api_message_cplt = 0; + sigfox_rfp_test_mode_l_ctx.loop_iter++; + if (sigfox_rfp_test_mode_l_ctx.loop_iter < LOOP) { +#ifdef ERROR_CODES + status = _send_application_message(); + CHECK_STATUS(SIGFOX_EP_ADDON_RFP_API_SUCCESS); +#else + _send_application_message(); +#endif + } + } + } + sigfox_rfp_test_mode_l_ctx.progress_status.progress = 100; +#endif + + RETURN(); +errors: + sigfox_rfp_test_mode_l_ctx.progress_status.status.error = 1; +#ifdef ASYNCHRONOUS + // test procedure done. + sigfox_rfp_test_mode_l_ctx.test_mode.cplt_cb(); +#endif + RETURN(); +} + +/*!****************************************************************** + * \fn static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_L_get_progress_status_fn(void) { + * \brief Get the progression status + * \param[in] none + * \param[out] none + * \retval Progression status + *******************************************************************/ +static SIGFOX_EP_ADDON_RFP_API_progress_status_t SIGFOX_RFP_TEST_MODE_L_get_progress_status_fn(void) { + return sigfox_rfp_test_mode_l_ctx.progress_status; +} +#endif //CERTIFICATION