add lorawan project
This commit is contained in:
parent
7761a3acdb
commit
fe6803fa40
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file adc.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the ADC instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __ADC_H__
|
||||
#define __ADC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
#endif
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void MX_ADC1_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADC_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file adc_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief API and configuration of the adc_if.c instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __ADC_IF_H__
|
||||
#define __ADC_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "platform.h"
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define VDDA_VREFINT_CAL ((uint32_t) 3000)
|
||||
#define BAT_CR2032 ((uint32_t) 3000)
|
||||
#define VDD_BAT BAT_CR2032
|
||||
#define VDD_MIN 1800
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/*!
|
||||
* @brief Initializes the ADC input
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void SYS_InitMeasurement(void);
|
||||
|
||||
/*!
|
||||
* @brief DeInitializes the ADC
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void SYS_DeInitMeasurement(void);
|
||||
|
||||
/*!
|
||||
* @brief Get the current temperature
|
||||
* @param none
|
||||
* @retval value temperature in degreeCelcius( q7.8 )
|
||||
*/
|
||||
int16_t SYS_GetTemperatureLevel(void);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Get the current battery level
|
||||
* @param none
|
||||
* @retval value battery level in linear scale
|
||||
*/
|
||||
uint16_t SYS_GetBatteryLevel(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ADC_IF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file dma.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for driver dma.c module
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __DMA_H__
|
||||
#define __DMA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* DMA memory to memory transfer handles -------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
/**
|
||||
* @brief Enables DMA controller clock
|
||||
* @param None
|
||||
* @retval None
|
||||
*
|
||||
*/
|
||||
void MX_DMA_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DMA_H__ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -50,6 +50,10 @@ extern "C" {
|
|||
|
||||
/* USER CODE END EM */
|
||||
|
||||
#define RTC_N_PREDIV_S 10 /* subsecond number of bits */
|
||||
#define RTC_PREDIV_S ((1<<RTC_N_PREDIV_S)-1) /* RTC_SYNCH_PREDIV; */
|
||||
#define RTC_PREDIV_A (1<<(15-RTC_N_PREDIV_S))-1 /* RTC_ASYNCH_PREDIV; */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "gpio.h"
|
||||
#include "tos_k.h"
|
||||
#include "stdio.h"
|
||||
#include "app_system.h"
|
||||
#include "app_lorawan.h"
|
||||
|
||||
void board_init(void);
|
||||
void SystemClock_Config(void);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file platform.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of general hw instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PLATFORM_H__
|
||||
#define __PLATFORM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include "stm32wlxx.h"
|
||||
#include "stm32wlxx_ll_gpio.h"
|
||||
#include "main.h"
|
||||
#include "usart.h"
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
|
||||
/* #warning "DBG LCH: VREFINT to be defined from AN" */
|
||||
|
||||
|
||||
/* Nothing for L4 but other platform might need it */
|
||||
#define __HAL_RCC_DBGMCU_CLK_ENABLE()
|
||||
#define __HAL_RCC_DBGMCU_CLK_DISABLE()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PLATFORM_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file rtc.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the RTC instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __RTC_H__
|
||||
#define __RTC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
/* Defines ------------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Initializes the RTC
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_RTC_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RTC_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file rtc_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the rtc_if.c instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RTC_IF_H__
|
||||
#define __RTC_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
//#include "stm32_timer.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/*!
|
||||
* @brief Initializes the RTC timer
|
||||
* @note The timer is based on the RTC
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void RTC_Init( void );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Return the minimum timeout in ticks the RTC is able to handle
|
||||
* @param none
|
||||
* @retval minimum value for a timeout in ticks
|
||||
*/
|
||||
uint32_t RTC_GetMinimumTimeout( void );
|
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer elapsed time since the last Alarm was set
|
||||
* @param none
|
||||
* @retval RTC Elapsed time in ticks
|
||||
*/
|
||||
uint32_t RTC_GetTimerElapsedTime(void);
|
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer value
|
||||
* @param none
|
||||
* @retval RTC Timer value in ticks
|
||||
*/
|
||||
uint32_t RTC_GetTimerValue( void );
|
||||
|
||||
/*!
|
||||
* @brief set Time Reference set also the RTC_DateStruct and RTC_TimeStruct
|
||||
* @param none
|
||||
* @retval Timer Reference Value in Ticks
|
||||
*/
|
||||
uint32_t RTC_SetTimerContext( void );
|
||||
|
||||
/*!
|
||||
* @brief Get the RTC timer Reference
|
||||
* @param none
|
||||
* @retval Timer Value in Ticks
|
||||
*/
|
||||
uint32_t RTC_GetTimerContext( void );
|
||||
|
||||
/*!
|
||||
* @brief RTC IRQ Handler on the RTC Alarm
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void RTC_IrqHandler ( void );
|
||||
|
||||
/*!
|
||||
* @brief a delay of delay ms by polling RTC
|
||||
* @param delay in ms
|
||||
* @retval none
|
||||
*/
|
||||
void RTC_DelayMs(uint32_t delay);
|
||||
|
||||
/*!
|
||||
* @brief calculates the wake up time between wake up and mcu start
|
||||
* @note resolution in RTC_ALARM_TIME_BASE in timer ticks
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void RTC_setMcuWakeUpTime(void);
|
||||
|
||||
/*!
|
||||
* @brief returns the wake up time in us
|
||||
* @param none
|
||||
* @retval wake up time in ticks
|
||||
*/
|
||||
int16_t RTC_getMcuWakeUpTime( void );
|
||||
|
||||
/*!
|
||||
* @brief converts time in ms to time in ticks
|
||||
* @param [IN] time in milliseconds
|
||||
* @retval returns time in timer ticks
|
||||
*/
|
||||
uint32_t RTC_ms2Tick( uint32_t timeMicroSec );
|
||||
|
||||
/*!
|
||||
* @brief converts time in ticks to time in ms
|
||||
* @param [IN] time in timer ticks
|
||||
* @retval returns time in timer milliseconds
|
||||
*/
|
||||
uint32_t RTC_Tick2ms( uint32_t tick );
|
||||
|
||||
/*!
|
||||
* \brief Get system time
|
||||
* \param [IN] subSeconds in ms
|
||||
*
|
||||
* \uint32_t seconds
|
||||
*/
|
||||
uint32_t HW_RTC_GetCalendarTime(uint16_t *subSeconds);
|
||||
|
||||
/*!
|
||||
* \brief Read from backup registers
|
||||
* \param [IN] Data 0
|
||||
* \param [IN] Data 1
|
||||
*
|
||||
*/
|
||||
void HW_RTC_BKUPRead(uint32_t *Data0, uint32_t *Data1);
|
||||
|
||||
/*!
|
||||
* \brief Write in backup registers
|
||||
* \param [IN] Data 0
|
||||
* \param [IN] Data 1
|
||||
*
|
||||
*/
|
||||
|
||||
void HW_RTC_BKUPWrite(uint32_t Data0, uint32_t Data1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RTC_IF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_lpm_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for stm32_lpm_f.c module (deveice specfic LP management)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32_LPM_IF_H__
|
||||
#define __STM32_LPM_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32_lpm.h"
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterOffMode(void);
|
||||
/**
|
||||
* @brief Exits Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitOffMode(void);
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Stop Mode
|
||||
* @note ARM exists the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterStopMode(void);
|
||||
/**
|
||||
* @brief Exits Low Power Stop Mode
|
||||
* @note Enable the pll at 32MHz
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitStopMode(void);
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterSleepMode(void);
|
||||
|
||||
/**
|
||||
* @brief Enters Low Power Sleep Mode
|
||||
* @note ARM exits the function when waking up
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitSleepMode(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__STM32_LPM_IF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -33,30 +33,30 @@
|
|||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
/* #define HAL_ADC_MODULE_ENABLED */
|
||||
/* #define HAL_COMP_MODULE_ENABLED */
|
||||
/* #define HAL_CRC_MODULE_ENABLED */
|
||||
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||
/* #define HAL_DAC_MODULE_ENABLED */
|
||||
/* #define HAL_GTZC_MODULE_ENABLED */
|
||||
/* #define HAL_HSEM_MODULE_ENABLED */
|
||||
/* #define HAL_I2C_MODULE_ENABLED */
|
||||
/* #define HAL_I2S_MODULE_ENABLED */
|
||||
/* #define HAL_IPCC_MODULE_ENABLED */
|
||||
/* #define HAL_IRDA_MODULE_ENABLED */
|
||||
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||
/* #define HAL_LPTIM_MODULE_ENABLED */
|
||||
/* #define HAL_PKA_MODULE_ENABLED */
|
||||
/* #define HAL_RNG_MODULE_ENABLED */
|
||||
/* #define HAL_RTC_MODULE_ENABLED */
|
||||
/* #define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/* #define HAL_SMBUS_MODULE_ENABLED */
|
||||
/* #define HAL_SPI_MODULE_ENABLED */
|
||||
/* #define HAL_SUBGHZ_MODULE_ENABLED */
|
||||
/* #define HAL_TIM_MODULE_ENABLED */
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
//#define HAL_COMP_MODULE_ENABLED
|
||||
//#define HAL_CRC_MODULE_ENABLED
|
||||
//#define HAL_CRYP_MODULE_ENABLED
|
||||
//#define HAL_DAC_MODULE_ENABLED
|
||||
//#define HAL_GTZC_MODULE_ENABLED
|
||||
//#define HAL_HSEM_MODULE_ENABLED
|
||||
//#define HAL_I2C_MODULE_ENABLED
|
||||
//#define HAL_I2S_MODULE_ENABLED
|
||||
//#define HAL_IPCC_MODULE_ENABLED
|
||||
//#define HAL_IRDA_MODULE_ENABLED
|
||||
//#define HAL_IWDG_MODULE_ENABLED
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
//#define HAL_PKA_MODULE_ENABLED
|
||||
//#define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
//#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
//#define HAL_SMBUS_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
#define HAL_SUBGHZ_MODULE_ENABLED
|
||||
//#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/* #define HAL_USART_MODULE_ENABLED */
|
||||
/* #define HAL_WWDG_MODULE_ENABLED */
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
//#define HAL_WWDG_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* File Name : USART.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the USART instances.
|
||||
* @file usart.h
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the USART instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __usart_H
|
||||
#define __usart_H
|
||||
#ifndef __USART_H__
|
||||
#define __USART_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
|
@ -30,34 +31,32 @@
|
|||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern UART_HandleTypeDef hlpuart1;
|
||||
|
||||
/* Pin mapping */
|
||||
|
||||
#define USARTx_TX_Pin GPIO_PIN_6
|
||||
#define USARTx_TX_GPIO_Port GPIOB
|
||||
|
||||
#define USARTx_RX_Pin GPIO_PIN_7
|
||||
#define USARTx_RX_GPIO_Port GPIOB
|
||||
|
||||
/* Not generated BY MX (?), was definied in usart_if.c */
|
||||
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define USARTx_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
|
||||
|
||||
#define USARTx_TX_AF GPIO_AF7_USART1
|
||||
#define USARTx_RX_AF GPIO_AF7_USART1
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_LPUART1_UART_Init(void);
|
||||
void MX_USART1_UART_Init(void);
|
||||
void MX_USART2_UART_Init(void);
|
||||
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*__ usart_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* __USART_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file usart_if.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file for the UART driver handling for hyperterminal communication
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "usart.h"
|
||||
#include "dma.h"
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USART_IF_H__
|
||||
#define __USART_IF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Init the UART and associated DMA.
|
||||
* @param TxCpltCallback
|
||||
* @return none
|
||||
*/
|
||||
uint8_t vcom_Init(void (*cb)(void*));
|
||||
|
||||
|
||||
/**
|
||||
* @brief DeInit the UART and associated DMA.
|
||||
* @param none
|
||||
* @return none
|
||||
*/
|
||||
uint8_t vcom_DeInit(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief send buffer @p_data of size size to vcom using DMA
|
||||
* @param p_data data to be sent
|
||||
* @param szie of buffer p_data to be sent
|
||||
* @return none
|
||||
*/
|
||||
uint8_t vcom_Trace(uint8_t *p_data, uint16_t size);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USART_IF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,936 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state (there are options to use 32-bit types if available).
|
||||
|
||||
The combination of mix columns and byte substitution used here is based on
|
||||
that developed by Karl Malbrain. His contribution is acknowledged.
|
||||
*/
|
||||
|
||||
/* define if you have a fast memcpy function on your system */
|
||||
#if 0
|
||||
# define HAVE_MEMCPY
|
||||
# include <string.h>
|
||||
# if defined( _MSC_VER )
|
||||
# include <intrin.h>
|
||||
# pragma intrinsic( memcpy )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* define if you have fast 32-bit types on your system */
|
||||
#if ( __CORTEX_M != 0 ) // if Cortex is different from M0/M0+
|
||||
# define HAVE_UINT_32T
|
||||
#endif
|
||||
|
||||
/* define if you don't want any tables */
|
||||
#if 1
|
||||
# define USE_TABLES
|
||||
#endif
|
||||
|
||||
/* On Intel Core 2 duo VERSION_1 is faster */
|
||||
|
||||
/* alternative versions (test for performance on your system) */
|
||||
#if 1
|
||||
# define VERSION_1
|
||||
#endif
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
//#if defined( HAVE_UINT_32T )
|
||||
// typedef unsigned long uint32_t;
|
||||
//#endif
|
||||
|
||||
/* functions for finite field multiplication in the AES Galois field */
|
||||
|
||||
#define WPOLY 0x011b
|
||||
#define BPOLY 0x1b
|
||||
#define DPOLY 0x008d
|
||||
|
||||
#define f1(x) (x)
|
||||
#define f2(x) ((x << 1) ^ (((x >> 7) & 1) * WPOLY))
|
||||
#define f4(x) ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY))
|
||||
#define f8(x) ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \
|
||||
^ (((x >> 5) & 4) * WPOLY))
|
||||
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
|
||||
|
||||
#define f3(x) (f2(x) ^ x)
|
||||
#define f9(x) (f8(x) ^ x)
|
||||
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||
|
||||
#if defined( USE_TABLES )
|
||||
|
||||
#define sb_data(w) { /* S Box data values */ \
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
|
||||
|
||||
#define isb_data(w) { /* inverse S Box data values */ \
|
||||
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
|
||||
|
||||
#define mm_data(w) { /* basic data for forming finite field tables */ \
|
||||
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
|
||||
|
||||
static const uint8_t sbox[256] = sb_data(f1);
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
static const uint8_t isbox[256] = isb_data(f1);
|
||||
#endif
|
||||
|
||||
static const uint8_t gfm2_sbox[256] = sb_data(f2);
|
||||
static const uint8_t gfm3_sbox[256] = sb_data(f3);
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
static const uint8_t gfmul_9[256] = mm_data(f9);
|
||||
static const uint8_t gfmul_b[256] = mm_data(fb);
|
||||
static const uint8_t gfmul_d[256] = mm_data(fd);
|
||||
static const uint8_t gfmul_e[256] = mm_data(fe);
|
||||
#endif
|
||||
|
||||
#define s_box(x) sbox[(x)]
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
#define is_box(x) isbox[(x)]
|
||||
#endif
|
||||
#define gfm2_sb(x) gfm2_sbox[(x)]
|
||||
#define gfm3_sb(x) gfm3_sbox[(x)]
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
#define gfm_9(x) gfmul_9[(x)]
|
||||
#define gfm_b(x) gfmul_b[(x)]
|
||||
#define gfm_d(x) gfmul_d[(x)]
|
||||
#define gfm_e(x) gfmul_e[(x)]
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* this is the high bit of x right shifted by 1 */
|
||||
/* position. Since the starting polynomial has */
|
||||
/* 9 bits (0x11b), this right shift keeps the */
|
||||
/* values of all top bits within a byte */
|
||||
|
||||
static uint8_t hibit(const uint8_t x)
|
||||
{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
return (r + 1) >> 1;
|
||||
}
|
||||
|
||||
/* return the inverse of the finite field element x */
|
||||
|
||||
static uint8_t gf_inv(const uint8_t x)
|
||||
{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
|
||||
if(x < 2)
|
||||
return x;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
if(n1)
|
||||
while(n2 >= n1) /* divide polynomial p2 by p1 */
|
||||
{
|
||||
n2 /= n1; /* shift smaller polynomial left */
|
||||
p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
|
||||
v2 ^= (v1 * n2); /* shift accumulated value and */
|
||||
n2 = hibit(p2); /* add into result */
|
||||
}
|
||||
else
|
||||
return v1;
|
||||
|
||||
if(n2) /* repeat with values swapped */
|
||||
while(n1 >= n2)
|
||||
{
|
||||
n1 /= n2;
|
||||
p1 ^= p2 * n1;
|
||||
v1 ^= v2 * n1;
|
||||
n1 = hibit(p1);
|
||||
}
|
||||
else
|
||||
return v2;
|
||||
}
|
||||
}
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
uint8_t fwd_affine(const uint8_t x)
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
uint32_t w = x;
|
||||
w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
|
||||
return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
#else
|
||||
return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4)
|
||||
^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t inv_affine(const uint8_t x)
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
uint32_t w = x;
|
||||
w = (w << 1) ^ (w << 3) ^ (w << 6);
|
||||
return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
#else
|
||||
return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6)
|
||||
^ (x >> 7) ^ (x >> 5) ^ (x >> 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define s_box(x) fwd_affine(gf_inv(x))
|
||||
#define is_box(x) gf_inv(inv_affine(x))
|
||||
#define gfm2_sb(x) f2(s_box(x))
|
||||
#define gfm3_sb(x) f3(s_box(x))
|
||||
#define gfm_9(x) f9(x)
|
||||
#define gfm_b(x) fb(x)
|
||||
#define gfm_d(x) fd(x)
|
||||
#define gfm_e(x) fe(x)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( HAVE_MEMCPY )
|
||||
# define block_copy_nn(d, s, l) memcpy(d, s, l)
|
||||
# define block_copy(d, s) memcpy(d, s, N_BLOCK)
|
||||
#else
|
||||
# define block_copy_nn(d, s, l) copy_block_nn(d, s, l)
|
||||
# define block_copy(d, s) copy_block(d, s)
|
||||
#endif
|
||||
|
||||
static void copy_block( void *d, const void *s )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0];
|
||||
((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1];
|
||||
((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2];
|
||||
((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3];
|
||||
#else
|
||||
((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0];
|
||||
((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1];
|
||||
((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2];
|
||||
((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3];
|
||||
((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4];
|
||||
((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5];
|
||||
((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6];
|
||||
((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7];
|
||||
((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8];
|
||||
((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9];
|
||||
((uint8_t*)d)[10] = ((uint8_t*)s)[10];
|
||||
((uint8_t*)d)[11] = ((uint8_t*)s)[11];
|
||||
((uint8_t*)d)[12] = ((uint8_t*)s)[12];
|
||||
((uint8_t*)d)[13] = ((uint8_t*)s)[13];
|
||||
((uint8_t*)d)[14] = ((uint8_t*)s)[14];
|
||||
((uint8_t*)d)[15] = ((uint8_t*)s)[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copy_block_nn( uint8_t * d, const uint8_t *s, uint8_t nn )
|
||||
{
|
||||
while( nn-- )
|
||||
//*((uint8_t*)d)++ = *((uint8_t*)s)++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
static void xor_block( void *d, const void *s )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint32_t*)d)[ 0] ^= ((uint32_t*)s)[ 0];
|
||||
((uint32_t*)d)[ 1] ^= ((uint32_t*)s)[ 1];
|
||||
((uint32_t*)d)[ 2] ^= ((uint32_t*)s)[ 2];
|
||||
((uint32_t*)d)[ 3] ^= ((uint32_t*)s)[ 3];
|
||||
#else
|
||||
((uint8_t*)d)[ 0] ^= ((uint8_t*)s)[ 0];
|
||||
((uint8_t*)d)[ 1] ^= ((uint8_t*)s)[ 1];
|
||||
((uint8_t*)d)[ 2] ^= ((uint8_t*)s)[ 2];
|
||||
((uint8_t*)d)[ 3] ^= ((uint8_t*)s)[ 3];
|
||||
((uint8_t*)d)[ 4] ^= ((uint8_t*)s)[ 4];
|
||||
((uint8_t*)d)[ 5] ^= ((uint8_t*)s)[ 5];
|
||||
((uint8_t*)d)[ 6] ^= ((uint8_t*)s)[ 6];
|
||||
((uint8_t*)d)[ 7] ^= ((uint8_t*)s)[ 7];
|
||||
((uint8_t*)d)[ 8] ^= ((uint8_t*)s)[ 8];
|
||||
((uint8_t*)d)[ 9] ^= ((uint8_t*)s)[ 9];
|
||||
((uint8_t*)d)[10] ^= ((uint8_t*)s)[10];
|
||||
((uint8_t*)d)[11] ^= ((uint8_t*)s)[11];
|
||||
((uint8_t*)d)[12] ^= ((uint8_t*)s)[12];
|
||||
((uint8_t*)d)[13] ^= ((uint8_t*)s)[13];
|
||||
((uint8_t*)d)[14] ^= ((uint8_t*)s)[14];
|
||||
((uint8_t*)d)[15] ^= ((uint8_t*)s)[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copy_and_key( void *d, const void *s, const void *k )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0] ^ ((uint32_t*)k)[ 0];
|
||||
((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1] ^ ((uint32_t*)k)[ 1];
|
||||
((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2] ^ ((uint32_t*)k)[ 2];
|
||||
((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3] ^ ((uint32_t*)k)[ 3];
|
||||
#elif 1
|
||||
((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0] ^ ((uint8_t*)k)[ 0];
|
||||
((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1] ^ ((uint8_t*)k)[ 1];
|
||||
((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2] ^ ((uint8_t*)k)[ 2];
|
||||
((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3] ^ ((uint8_t*)k)[ 3];
|
||||
((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4] ^ ((uint8_t*)k)[ 4];
|
||||
((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5] ^ ((uint8_t*)k)[ 5];
|
||||
((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6] ^ ((uint8_t*)k)[ 6];
|
||||
((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7] ^ ((uint8_t*)k)[ 7];
|
||||
((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8] ^ ((uint8_t*)k)[ 8];
|
||||
((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9] ^ ((uint8_t*)k)[ 9];
|
||||
((uint8_t*)d)[10] = ((uint8_t*)s)[10] ^ ((uint8_t*)k)[10];
|
||||
((uint8_t*)d)[11] = ((uint8_t*)s)[11] ^ ((uint8_t*)k)[11];
|
||||
((uint8_t*)d)[12] = ((uint8_t*)s)[12] ^ ((uint8_t*)k)[12];
|
||||
((uint8_t*)d)[13] = ((uint8_t*)s)[13] ^ ((uint8_t*)k)[13];
|
||||
((uint8_t*)d)[14] = ((uint8_t*)s)[14] ^ ((uint8_t*)k)[14];
|
||||
((uint8_t*)d)[15] = ((uint8_t*)s)[15] ^ ((uint8_t*)k)[15];
|
||||
#else
|
||||
block_copy(d, s);
|
||||
xor_block(d, k);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void add_round_key( uint8_t d[N_BLOCK], const uint8_t k[N_BLOCK] )
|
||||
{
|
||||
xor_block(d, k);
|
||||
}
|
||||
|
||||
static void shift_sub_rows( uint8_t st[N_BLOCK] )
|
||||
{ uint8_t tt;
|
||||
|
||||
st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]);
|
||||
st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]);
|
||||
|
||||
tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]);
|
||||
st[ 9] = s_box(st[13]); st[13] = s_box( tt );
|
||||
|
||||
tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt );
|
||||
tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt );
|
||||
|
||||
tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]);
|
||||
st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt );
|
||||
}
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
|
||||
static void inv_shift_sub_rows( uint8_t st[N_BLOCK] )
|
||||
{ uint8_t tt;
|
||||
|
||||
st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]);
|
||||
st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]);
|
||||
|
||||
tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]);
|
||||
st[ 5] = is_box(st[1]); st[ 1] = is_box( tt );
|
||||
|
||||
tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt );
|
||||
tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt );
|
||||
|
||||
tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]);
|
||||
st[11] = is_box(st[15]); st[15] = is_box( tt );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( VERSION_1 )
|
||||
static void mix_sub_columns( uint8_t dt[N_BLOCK] )
|
||||
{ uint8_t st[N_BLOCK];
|
||||
block_copy(st, dt);
|
||||
#else
|
||||
static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] )
|
||||
{
|
||||
#endif
|
||||
dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]);
|
||||
dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]);
|
||||
dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]);
|
||||
dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]);
|
||||
|
||||
dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]);
|
||||
dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]);
|
||||
dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]);
|
||||
dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]);
|
||||
|
||||
dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]);
|
||||
dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]);
|
||||
dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]);
|
||||
dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]);
|
||||
|
||||
dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]);
|
||||
dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]);
|
||||
dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]);
|
||||
dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]);
|
||||
}
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
|
||||
#if defined( VERSION_1 )
|
||||
static void inv_mix_sub_columns( uint8_t dt[N_BLOCK] )
|
||||
{ uint8_t st[N_BLOCK];
|
||||
block_copy(st, dt);
|
||||
#else
|
||||
static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t st[N_BLOCK] )
|
||||
{
|
||||
#endif
|
||||
dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3]));
|
||||
dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3]));
|
||||
dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3]));
|
||||
dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3]));
|
||||
|
||||
dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7]));
|
||||
dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7]));
|
||||
dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7]));
|
||||
dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7]));
|
||||
|
||||
dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11]));
|
||||
dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11]));
|
||||
dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11]));
|
||||
dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11]));
|
||||
|
||||
dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15]));
|
||||
dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15]));
|
||||
dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15]));
|
||||
dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15]));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
|
||||
|
||||
/* Set the cipher key for the pre-keyed version */
|
||||
|
||||
return_type aes_set_key( const uint8_t key[], length_type keylen, aes_context ctx[1] )
|
||||
{
|
||||
uint8_t cc, rc, hi;
|
||||
|
||||
switch( keylen )
|
||||
{
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
ctx->rnd = 0;
|
||||
return ( uint8_t )-1;
|
||||
}
|
||||
block_copy_nn(ctx->ksch, key, keylen);
|
||||
hi = (keylen + 28) << 2;
|
||||
ctx->rnd = (hi >> 4) - 1;
|
||||
for( cc = keylen, rc = 1; cc < hi; cc += 4 )
|
||||
{ uint8_t tt, t0, t1, t2, t3;
|
||||
|
||||
t0 = ctx->ksch[cc - 4];
|
||||
t1 = ctx->ksch[cc - 3];
|
||||
t2 = ctx->ksch[cc - 2];
|
||||
t3 = ctx->ksch[cc - 1];
|
||||
if( cc % keylen == 0 )
|
||||
{
|
||||
tt = t0;
|
||||
t0 = s_box(t1) ^ rc;
|
||||
t1 = s_box(t2);
|
||||
t2 = s_box(t3);
|
||||
t3 = s_box(tt);
|
||||
rc = f2(rc);
|
||||
}
|
||||
else if( keylen > 24 && cc % keylen == 16 )
|
||||
{
|
||||
t0 = s_box(t0);
|
||||
t1 = s_box(t1);
|
||||
t2 = s_box(t2);
|
||||
t3 = s_box(t3);
|
||||
}
|
||||
tt = cc - keylen;
|
||||
ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
|
||||
ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
|
||||
ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
|
||||
ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_PREKEYED )
|
||||
|
||||
/* Encrypt a single block of 16 bytes */
|
||||
|
||||
return_type aes_encrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
if( ctx->rnd )
|
||||
{
|
||||
uint8_t s1[N_BLOCK], r;
|
||||
copy_and_key( s1, in, ctx->ksch );
|
||||
|
||||
for( r = 1 ; r < ctx->rnd ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns( s1 );
|
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK);
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
|
||||
}
|
||||
#endif
|
||||
shift_sub_rows( s1 );
|
||||
copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
|
||||
}
|
||||
else
|
||||
return ( uint8_t )-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CBC encrypt a number of blocks (input and return an IV) */
|
||||
|
||||
return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out,
|
||||
int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
|
||||
while(n_block--)
|
||||
{
|
||||
xor_block(iv, in);
|
||||
if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
//memcpy(out, iv, N_BLOCK);
|
||||
block_copy(out, iv);
|
||||
in += N_BLOCK;
|
||||
out += N_BLOCK;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
|
||||
/* Decrypt a single block of 16 bytes */
|
||||
|
||||
return_type aes_decrypt( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
if( ctx->rnd )
|
||||
{
|
||||
uint8_t s1[N_BLOCK], r;
|
||||
copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = ctx->rnd ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
copy_and_key( out, s1, ctx->ksch );
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CBC decrypt a number of blocks (input and return an IV) */
|
||||
|
||||
return_type aes_cbc_decrypt( const uint8_t *in, uint8_t *out,
|
||||
int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
while(n_block--)
|
||||
{ uint8_t tmp[N_BLOCK];
|
||||
|
||||
//memcpy(tmp, in, N_BLOCK);
|
||||
block_copy(tmp, in);
|
||||
if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS)
|
||||
return EXIT_FAILURE;
|
||||
xor_block(out, iv);
|
||||
//memcpy(iv, tmp, N_BLOCK);
|
||||
block_copy(iv, tmp);
|
||||
in += N_BLOCK;
|
||||
out += N_BLOCK;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_128_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 128 bit keys */
|
||||
|
||||
static void update_encrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc )
|
||||
{ uint8_t cc;
|
||||
|
||||
k[0] ^= s_box(k[13]) ^ *rc;
|
||||
k[1] ^= s_box(k[14]);
|
||||
k[2] ^= s_box(k[15]);
|
||||
k[3] ^= s_box(k[12]);
|
||||
*rc = f2( *rc );
|
||||
|
||||
for(cc = 4; cc < 16; cc += 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
|
||||
|
||||
void aes_encrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
|
||||
const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
|
||||
{ uint8_t s1[N_BLOCK], r, rc = 1;
|
||||
|
||||
if(o_key != key)
|
||||
block_copy( o_key, key );
|
||||
copy_and_key( s1, in, o_key );
|
||||
|
||||
for( r = 1 ; r < 10 ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns( s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
copy_and_key( s1, s2, o_key );
|
||||
}
|
||||
#endif
|
||||
|
||||
shift_sub_rows( s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_128_OTFK )
|
||||
|
||||
/* The 'on the fly' decryption key update for for 128 bit keys */
|
||||
|
||||
static void update_decrypt_key_128( uint8_t k[N_BLOCK], uint8_t *rc )
|
||||
{ uint8_t cc;
|
||||
|
||||
for( cc = 12; cc > 0; cc -= 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
*rc = d2(*rc);
|
||||
k[0] ^= s_box(k[13]) ^ *rc;
|
||||
k[1] ^= s_box(k[14]);
|
||||
k[2] ^= s_box(k[15]);
|
||||
k[3] ^= s_box(k[12]);
|
||||
}
|
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
|
||||
|
||||
void aes_decrypt_128( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
|
||||
const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
|
||||
{
|
||||
uint8_t s1[N_BLOCK], r, rc = 0x6c;
|
||||
if(o_key != key)
|
||||
block_copy( o_key, key );
|
||||
|
||||
copy_and_key( s1, in, o_key );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = 10 ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
copy_and_key( s2, s1, o_key );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_256_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */
|
||||
|
||||
static void update_encrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc )
|
||||
{ uint8_t cc;
|
||||
|
||||
k[0] ^= s_box(k[29]) ^ *rc;
|
||||
k[1] ^= s_box(k[30]);
|
||||
k[2] ^= s_box(k[31]);
|
||||
k[3] ^= s_box(k[28]);
|
||||
*rc = f2( *rc );
|
||||
|
||||
for(cc = 4; cc < 16; cc += 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
k[16] ^= s_box(k[12]);
|
||||
k[17] ^= s_box(k[13]);
|
||||
k[18] ^= s_box(k[14]);
|
||||
k[19] ^= s_box(k[15]);
|
||||
|
||||
for( cc = 20; cc < 32; cc += 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
|
||||
|
||||
void aes_encrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
|
||||
const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
|
||||
{
|
||||
uint8_t s1[N_BLOCK], r, rc = 1;
|
||||
if(o_key != key)
|
||||
{
|
||||
block_copy( o_key, key );
|
||||
block_copy( o_key + 16, key + 16 );
|
||||
}
|
||||
copy_and_key( s1, in, o_key );
|
||||
|
||||
for( r = 1 ; r < 14 ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns(s1);
|
||||
if( r & 1 )
|
||||
add_round_key( s1, o_key + 16 );
|
||||
else
|
||||
{
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
if( r & 1 )
|
||||
copy_and_key( s1, s2, o_key + 16 );
|
||||
else
|
||||
{
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
copy_and_key( s1, s2, o_key );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
shift_sub_rows( s1 );
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_256_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */
|
||||
|
||||
static void update_decrypt_key_256( uint8_t k[2 * N_BLOCK], uint8_t *rc )
|
||||
{ uint8_t cc;
|
||||
|
||||
for(cc = 28; cc > 16; cc -= 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
k[16] ^= s_box(k[12]);
|
||||
k[17] ^= s_box(k[13]);
|
||||
k[18] ^= s_box(k[14]);
|
||||
k[19] ^= s_box(k[15]);
|
||||
|
||||
for(cc = 12; cc > 0; cc -= 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
*rc = d2(*rc);
|
||||
k[0] ^= s_box(k[29]) ^ *rc;
|
||||
k[1] ^= s_box(k[30]);
|
||||
k[2] ^= s_box(k[31]);
|
||||
k[3] ^= s_box(k[28]);
|
||||
}
|
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly'
|
||||
256 bit keying
|
||||
*/
|
||||
void aes_decrypt_256( const uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
|
||||
const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
|
||||
{
|
||||
uint8_t s1[N_BLOCK], r, rc = 0x80;
|
||||
|
||||
if(o_key != key)
|
||||
{
|
||||
block_copy( o_key, key );
|
||||
block_copy( o_key + 16, key + 16 );
|
||||
}
|
||||
|
||||
copy_and_key( s1, in, o_key );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = 14 ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
if( ( r & 1 ) )
|
||||
{
|
||||
update_decrypt_key_256( o_key, &rc );
|
||||
add_round_key( s1, o_key + 16 );
|
||||
}
|
||||
else
|
||||
add_round_key( s1, o_key );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint8_t s2[N_BLOCK];
|
||||
if( ( r & 1 ) )
|
||||
{
|
||||
update_decrypt_key_256( o_key, &rc );
|
||||
copy_and_key( s2, s1, o_key + 16 );
|
||||
}
|
||||
else
|
||||
copy_and_key( s2, s1, o_key );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state.
|
||||
*/
|
||||
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if 1
|
||||
# define AES_ENC_PREKEYED /* AES encryption with a precomputed key schedule */
|
||||
#endif
|
||||
#if 0
|
||||
# define AES_DEC_PREKEYED /* AES decryption with a precomputed key schedule */
|
||||
#endif
|
||||
#if 0
|
||||
# define AES_ENC_128_OTFK /* AES encryption with 'on the fly' 128 bit keying */
|
||||
#endif
|
||||
#if 0
|
||||
# define AES_DEC_128_OTFK /* AES decryption with 'on the fly' 128 bit keying */
|
||||
#endif
|
||||
#if 0
|
||||
# define AES_ENC_256_OTFK /* AES encryption with 'on the fly' 256 bit keying */
|
||||
#endif
|
||||
#if 0
|
||||
# define AES_DEC_256_OTFK /* AES decryption with 'on the fly' 256 bit keying */
|
||||
#endif
|
||||
|
||||
#define N_ROW 4
|
||||
#define N_COL 4
|
||||
#define N_BLOCK (N_ROW * N_COL)
|
||||
#define N_MAX_ROUNDS 14
|
||||
|
||||
typedef uint8_t return_type;
|
||||
|
||||
/* Warning: The key length for 256 bit keys overflows a byte
|
||||
(see comment below)
|
||||
*/
|
||||
|
||||
typedef uint8_t length_type;
|
||||
|
||||
typedef struct
|
||||
{ uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
|
||||
uint8_t rnd;
|
||||
} aes_context;
|
||||
|
||||
/* The following calls are for a precomputed key schedule
|
||||
|
||||
NOTE: If the length_type used for the key length is an
|
||||
unsigned 8-bit character, a key length of 256 bits must
|
||||
be entered as a length in bytes (valid inputs are hence
|
||||
128, 192, 16, 24 and 32).
|
||||
*/
|
||||
|
||||
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
|
||||
|
||||
return_type aes_set_key( const uint8_t key[],
|
||||
length_type keylen,
|
||||
aes_context ctx[1] );
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_PREKEYED )
|
||||
|
||||
return_type aes_encrypt( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const aes_context ctx[1] );
|
||||
|
||||
return_type aes_cbc_encrypt( const uint8_t *in,
|
||||
uint8_t *out,
|
||||
int32_t n_block,
|
||||
uint8_t iv[N_BLOCK],
|
||||
const aes_context ctx[1] );
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
|
||||
return_type aes_decrypt( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const aes_context ctx[1] );
|
||||
|
||||
return_type aes_cbc_decrypt( const uint8_t *in,
|
||||
uint8_t *out,
|
||||
int32_t n_block,
|
||||
uint8_t iv[N_BLOCK],
|
||||
const aes_context ctx[1] );
|
||||
#endif
|
||||
|
||||
/* The following calls are for 'on the fly' keying. In this case the
|
||||
encryption and decryption keys are different.
|
||||
|
||||
The encryption subroutines take a key in an array of bytes in
|
||||
key[L] where L is 16, 24 or 32 bytes for key lengths of 128,
|
||||
192, and 256 bits respectively. They then encrypts the input
|
||||
data, in[] with this key and put the reult in the output array
|
||||
out[]. In addition, the second key array, o_key[L], is used
|
||||
to output the key that is needed by the decryption subroutine
|
||||
to reverse the encryption operation. The two key arrays can
|
||||
be the same array but in this case the original key will be
|
||||
overwritten.
|
||||
|
||||
In the same way, the decryption subroutines output keys that
|
||||
can be used to reverse their effect when used for encryption.
|
||||
|
||||
Only 128 and 256 bit keys are supported in these 'on the fly'
|
||||
modes.
|
||||
*/
|
||||
|
||||
#if defined( AES_ENC_128_OTFK )
|
||||
void aes_encrypt_128( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const uint8_t key[N_BLOCK],
|
||||
uint8_t o_key[N_BLOCK] );
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_128_OTFK )
|
||||
void aes_decrypt_128( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const uint8_t key[N_BLOCK],
|
||||
uint8_t o_key[N_BLOCK] );
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_256_OTFK )
|
||||
void aes_encrypt_256( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const uint8_t key[2 * N_BLOCK],
|
||||
uint8_t o_key[2 * N_BLOCK] );
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_256_OTFK )
|
||||
void aes_decrypt_256( const uint8_t in[N_BLOCK],
|
||||
uint8_t out[N_BLOCK],
|
||||
const uint8_t key[2 * N_BLOCK],
|
||||
uint8_t o_key[2 * N_BLOCK] );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/**************************************************************************
|
||||
Copyright (C) 2009 Lander Casado, Philippas Tsigas
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
(the "Software"), to deal with the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers. Redistributions in
|
||||
binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimers in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
In no event shall the authors or copyright holders be liable for any special,
|
||||
incidental, indirect or consequential damages of any kind, or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether or not
|
||||
advised of the possibility of damage, and on any theory of liability,
|
||||
arising out of or in connection with the use or performance of this software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS WITH THE SOFTWARE
|
||||
|
||||
*****************************************************************************/
|
||||
//#include <sys/param.h>
|
||||
//#include <sys/systm.h>
|
||||
#include <stdint.h>
|
||||
#include "aes.h"
|
||||
#include "cmac.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#define LSHIFT(v, r) do { \
|
||||
int32_t i; \
|
||||
for (i = 0; i < 15; i++) \
|
||||
(r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7; \
|
||||
(r)[15] = (v)[15] << 1; \
|
||||
} while (0)
|
||||
|
||||
#define XOR(v, r) do { \
|
||||
int32_t i; \
|
||||
for (i = 0; i < 16; i++) \
|
||||
{ \
|
||||
(r)[i] = (r)[i] ^ (v)[i]; \
|
||||
} \
|
||||
} while (0) \
|
||||
|
||||
|
||||
void AES_CMAC_Init(AES_CMAC_CTX *ctx)
|
||||
{
|
||||
memset1(ctx->X, 0, sizeof ctx->X);
|
||||
ctx->M_n = 0;
|
||||
memset1(ctx->rijndael.ksch, '\0', 240);
|
||||
}
|
||||
|
||||
void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const uint8_t key[AES_CMAC_KEY_LENGTH])
|
||||
{
|
||||
//rijndael_set_key_enc_only(&ctx->rijndael, key, 128);
|
||||
aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael);
|
||||
}
|
||||
|
||||
void AES_CMAC_Update(AES_CMAC_CTX *ctx, const uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t mlen;
|
||||
uint8_t in[16];
|
||||
|
||||
if (ctx->M_n > 0) {
|
||||
mlen = MIN(16 - ctx->M_n, len);
|
||||
memcpy1(ctx->M_last + ctx->M_n, data, mlen);
|
||||
ctx->M_n += mlen;
|
||||
if (ctx->M_n < 16 || len == mlen)
|
||||
return;
|
||||
XOR(ctx->M_last, ctx->X);
|
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
|
||||
aes_encrypt( ctx->X, ctx->X, &ctx->rijndael);
|
||||
data += mlen;
|
||||
len -= mlen;
|
||||
}
|
||||
while (len > 16) { /* not last block */
|
||||
|
||||
XOR(data, ctx->X);
|
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
|
||||
|
||||
memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
|
||||
aes_encrypt( in, in, &ctx->rijndael);
|
||||
memcpy1(&ctx->X[0], in, 16);
|
||||
|
||||
data += 16;
|
||||
len -= 16;
|
||||
}
|
||||
/* potential last block, save it */
|
||||
memcpy1(ctx->M_last, data, len);
|
||||
ctx->M_n = len;
|
||||
}
|
||||
|
||||
void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
|
||||
{
|
||||
uint8_t K[16];
|
||||
uint8_t in[16];
|
||||
/* generate subkey K1 */
|
||||
memset1(K, '\0', 16);
|
||||
|
||||
//rijndael_encrypt(&ctx->rijndael, K, K);
|
||||
|
||||
aes_encrypt( K, K, &ctx->rijndael);
|
||||
|
||||
if (K[0] & 0x80) {
|
||||
LSHIFT(K, K);
|
||||
K[15] ^= 0x87;
|
||||
} else
|
||||
LSHIFT(K, K);
|
||||
|
||||
|
||||
if (ctx->M_n == 16) {
|
||||
/* last block was a complete block */
|
||||
XOR(K, ctx->M_last);
|
||||
|
||||
} else {
|
||||
/* generate subkey K2 */
|
||||
if (K[0] & 0x80) {
|
||||
LSHIFT(K, K);
|
||||
K[15] ^= 0x87;
|
||||
} else
|
||||
LSHIFT(K, K);
|
||||
|
||||
/* padding(M_last) */
|
||||
ctx->M_last[ctx->M_n] = 0x80;
|
||||
while (++ctx->M_n < 16)
|
||||
ctx->M_last[ctx->M_n] = 0;
|
||||
|
||||
XOR(K, ctx->M_last);
|
||||
|
||||
|
||||
}
|
||||
XOR(ctx->M_last, ctx->X);
|
||||
|
||||
//rijndael_encrypt(&ctx->rijndael, ctx->X, digest);
|
||||
|
||||
memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
|
||||
aes_encrypt(in, digest, &ctx->rijndael);
|
||||
memset1(K, 0, sizeof K);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/**************************************************************************
|
||||
Copyright (C) 2009 Lander Casado, Philippas Tsigas
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files
|
||||
(the "Software"), to deal with the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers. Redistributions in
|
||||
binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimers in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
In no event shall the authors or copyright holders be liable for any special,
|
||||
incidental, indirect or consequential damages of any kind, or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether or not
|
||||
advised of the possibility of damage, and on any theory of liability,
|
||||
arising out of or in connection with the use or performance of this software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS WITH THE SOFTWARE
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _CMAC_H_
|
||||
#define _CMAC_H_
|
||||
|
||||
#include "aes.h"
|
||||
|
||||
#define AES_CMAC_KEY_LENGTH 16
|
||||
#define AES_CMAC_DIGEST_LENGTH 16
|
||||
|
||||
typedef struct _AES_CMAC_CTX {
|
||||
aes_context rijndael;
|
||||
uint8_t X[16];
|
||||
uint8_t M_last[16];
|
||||
uint32_t M_n;
|
||||
} AES_CMAC_CTX;
|
||||
|
||||
//#include <sys/cdefs.h>
|
||||
|
||||
//__BEGIN_DECLS
|
||||
void AES_CMAC_Init(AES_CMAC_CTX * ctx);
|
||||
void AES_CMAC_SetKey(AES_CMAC_CTX * ctx, const uint8_t key[AES_CMAC_KEY_LENGTH]);
|
||||
void AES_CMAC_Update(AES_CMAC_CTX * ctx, const uint8_t * data, uint32_t len);
|
||||
// __attribute__((__bounded__(__string__,2,3)));
|
||||
void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX * ctx);
|
||||
// __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
|
||||
//__END_DECLS
|
||||
|
||||
#endif /* _CMAC_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: Secure Element software implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
|
||||
Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
#include "secure-element.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "LoRaMacCrypto.h"
|
||||
#include "utilities.h"
|
||||
#include "aes.h"
|
||||
#include "cmac.h"
|
||||
#include "radio.h"
|
||||
|
||||
#define NUM_OF_KEYS 24
|
||||
#define KEY_SIZE 16
|
||||
|
||||
/*!
|
||||
* Identifier value pair type for Keys
|
||||
*/
|
||||
typedef struct sKey
|
||||
{
|
||||
/*
|
||||
* Key identifier
|
||||
*/
|
||||
KeyIdentifier_t KeyID;
|
||||
/*
|
||||
* Key value
|
||||
*/
|
||||
uint8_t KeyValue[KEY_SIZE];
|
||||
} Key_t;
|
||||
|
||||
/*
|
||||
* Secure Element Non Volatile Context structure
|
||||
*/
|
||||
typedef struct sSecureElementNvCtx
|
||||
{
|
||||
/*
|
||||
* DevEUI storage
|
||||
*/
|
||||
uint8_t DevEui[SE_EUI_SIZE];
|
||||
/*
|
||||
* Join EUI storage
|
||||
*/
|
||||
uint8_t JoinEui[SE_EUI_SIZE];
|
||||
/*
|
||||
* AES computation context variable
|
||||
*/
|
||||
aes_context AesContext;
|
||||
/*
|
||||
* CMAC computation context variable
|
||||
*/
|
||||
AES_CMAC_CTX AesCmacCtx[1];
|
||||
/*
|
||||
* Key List
|
||||
*/
|
||||
Key_t KeyList[NUM_OF_KEYS];
|
||||
}SecureElementNvCtx_t;
|
||||
|
||||
/*
|
||||
* Module context
|
||||
*/
|
||||
static SecureElementNvCtx_t SeNvmCtx;
|
||||
|
||||
static SecureElementNvmEvent SeNvmCtxChanged;
|
||||
|
||||
/*
|
||||
* Local functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Gets key item from key list.
|
||||
*
|
||||
* cmac = aes128_cmac(keyID, B0 | msg)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier
|
||||
* \param[OUT] keyItem - Key item reference
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static SecureElementStatus_t GetKeyByID( KeyIdentifier_t keyID, Key_t** keyItem )
|
||||
{
|
||||
for( uint8_t i = 0; i < NUM_OF_KEYS; i++ )
|
||||
{
|
||||
if( SeNvmCtx.KeyList[i].KeyID == keyID )
|
||||
{
|
||||
*keyItem = &( SeNvmCtx.KeyList[i] );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
}
|
||||
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy callback in case if the user provides NULL function pointer
|
||||
*/
|
||||
static void DummyCB( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes a CMAC of a message using provided initial Bx block
|
||||
*
|
||||
* cmac = aes128_cmac(keyID, blocks[i].Buffer)
|
||||
*
|
||||
* \param[IN] micBxBuffer - Buffer containing the initial Bx block
|
||||
* \param[IN] buffer - Data buffer
|
||||
* \param[IN] size - Data buffer size
|
||||
* \param[IN] keyID - Key identifier to determine the AES key to be used
|
||||
* \param[OUT] cmac - Computed cmac
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static SecureElementStatus_t ComputeCmac( uint8_t *micBxBuffer, uint8_t *buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac )
|
||||
{
|
||||
if( ( buffer == NULL ) || ( cmac == NULL ) )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint8_t Cmac[16];
|
||||
|
||||
AES_CMAC_Init( SeNvmCtx.AesCmacCtx );
|
||||
|
||||
Key_t* keyItem;
|
||||
SecureElementStatus_t retval = GetKeyByID( keyID, &keyItem );
|
||||
|
||||
if( retval == SECURE_ELEMENT_SUCCESS )
|
||||
{
|
||||
AES_CMAC_SetKey( SeNvmCtx.AesCmacCtx, keyItem->KeyValue );
|
||||
|
||||
if( micBxBuffer != NULL )
|
||||
{
|
||||
AES_CMAC_Update( SeNvmCtx.AesCmacCtx, micBxBuffer, 16 );
|
||||
}
|
||||
|
||||
AES_CMAC_Update( SeNvmCtx.AesCmacCtx, buffer, size );
|
||||
|
||||
AES_CMAC_Final( Cmac, SeNvmCtx.AesCmacCtx );
|
||||
|
||||
// Bring into the required format
|
||||
*cmac = ( uint32_t )( ( uint32_t ) Cmac[3] << 24 | ( uint32_t ) Cmac[2] << 16 | ( uint32_t ) Cmac[1] << 8 | ( uint32_t ) Cmac[0] );
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* API functions
|
||||
*/
|
||||
|
||||
SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged )
|
||||
{
|
||||
uint8_t itr = 0;
|
||||
uint8_t zeroKey[16] = { 0 };
|
||||
|
||||
// Initialize with defaults
|
||||
SeNvmCtx.KeyList[itr++].KeyID = APP_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = GEN_APP_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = NWK_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = J_S_INT_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = J_S_ENC_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = F_NWK_S_INT_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = S_NWK_S_INT_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = NWK_S_ENC_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = APP_S_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_ROOT_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_KE_KEY;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_0;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_0;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_0;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_1;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_1;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_1;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_2;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_2;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_2;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_KEY_3;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_APP_S_KEY_3;
|
||||
SeNvmCtx.KeyList[itr++].KeyID = MC_NWK_S_KEY_3;
|
||||
SeNvmCtx.KeyList[itr].KeyID = SLOT_RAND_ZERO_KEY;
|
||||
|
||||
// Set standard keys
|
||||
memcpy1( SeNvmCtx.KeyList[itr].KeyValue, zeroKey, KEY_SIZE );
|
||||
|
||||
memset1( SeNvmCtx.DevEui, 0, SE_EUI_SIZE );
|
||||
memset1( SeNvmCtx.JoinEui, 0, SE_EUI_SIZE );
|
||||
|
||||
// Assign callback
|
||||
if( seNvmCtxChanged != 0 )
|
||||
{
|
||||
SeNvmCtxChanged = seNvmCtxChanged;
|
||||
}
|
||||
else
|
||||
{
|
||||
SeNvmCtxChanged = DummyCB;
|
||||
}
|
||||
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx )
|
||||
{
|
||||
// Restore nvm context
|
||||
if( seNvmCtx != 0 )
|
||||
{
|
||||
memcpy1( ( uint8_t* ) &SeNvmCtx, ( uint8_t* ) seNvmCtx, sizeof( SeNvmCtx ) );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
}
|
||||
|
||||
void* SecureElementGetNvmCtx( size_t* seNvmCtxSize )
|
||||
{
|
||||
*seNvmCtxSize = sizeof( SeNvmCtx );
|
||||
return &SeNvmCtx;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key )
|
||||
{
|
||||
if( key == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
|
||||
for( uint8_t i = 0; i < NUM_OF_KEYS; i++ )
|
||||
{
|
||||
if( SeNvmCtx.KeyList[i].KeyID == keyID )
|
||||
{
|
||||
if( ( keyID == MC_KEY_0 ) || ( keyID == MC_KEY_1 ) || ( keyID == MC_KEY_2 ) || ( keyID == MC_KEY_3 ) )
|
||||
{ // Decrypt the key if its a Mckey
|
||||
SecureElementStatus_t retval = SECURE_ELEMENT_ERROR;
|
||||
uint8_t decryptedKey[16] = { 0 };
|
||||
|
||||
retval = SecureElementAesEncrypt( key, 16, MC_KE_KEY, decryptedKey );
|
||||
|
||||
memcpy1( SeNvmCtx.KeyList[i].KeyValue, decryptedKey, KEY_SIZE );
|
||||
SeNvmCtxChanged( );
|
||||
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy1( SeNvmCtx.KeyList[i].KeyValue, key, KEY_SIZE );
|
||||
SeNvmCtxChanged( );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementComputeAesCmac( uint8_t *micBxBuffer, uint8_t *buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac )
|
||||
{
|
||||
if( keyID >= LORAMAC_CRYPTO_MULTICAST_KEYS )
|
||||
{
|
||||
//Never accept multicast key identifier for cmac computation
|
||||
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
|
||||
}
|
||||
|
||||
return ComputeCmac( micBxBuffer, buffer, size, keyID, cmac );
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementVerifyAesCmac( uint8_t* buffer, uint16_t size, uint32_t expectedCmac, KeyIdentifier_t keyID )
|
||||
{
|
||||
if( buffer == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
|
||||
SecureElementStatus_t retval = SECURE_ELEMENT_ERROR;
|
||||
uint32_t compCmac = 0;
|
||||
retval = ComputeCmac( NULL, buffer, size, keyID, &compCmac );
|
||||
if( retval != SECURE_ELEMENT_SUCCESS )
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
if( expectedCmac != compCmac )
|
||||
{
|
||||
retval = SECURE_ELEMENT_FAIL_CMAC;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint8_t* encBuffer )
|
||||
{
|
||||
if( buffer == NULL || encBuffer == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
|
||||
// Check if the size is divisible by 16,
|
||||
if( ( size % 16 ) != 0 )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
memset1( SeNvmCtx.AesContext.ksch, '\0', 240 );
|
||||
|
||||
Key_t* pItem;
|
||||
SecureElementStatus_t retval = GetKeyByID( keyID, &pItem );
|
||||
|
||||
if( retval == SECURE_ELEMENT_SUCCESS )
|
||||
{
|
||||
aes_set_key( pItem->KeyValue, 16, &SeNvmCtx.AesContext );
|
||||
|
||||
uint8_t block = 0;
|
||||
|
||||
while( size != 0 )
|
||||
{
|
||||
aes_encrypt( &buffer[block], &encBuffer[block], &SeNvmCtx.AesContext );
|
||||
block = block + 16;
|
||||
size = size - 16;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID )
|
||||
{
|
||||
if( input == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
|
||||
SecureElementStatus_t retval = SECURE_ELEMENT_ERROR;
|
||||
uint8_t key[16] = { 0 };
|
||||
|
||||
// In case of MC_KE_KEY, prevent other keys than NwkKey or AppKey for LoRaWAN 1.1 or later
|
||||
if( targetKeyID == MC_KE_KEY )
|
||||
{
|
||||
if( ( ( rootKeyID == APP_KEY ) && ( version.Fields.Minor == 0 ) ) || ( rootKeyID == NWK_KEY ) )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_INVALID_KEY_ID;
|
||||
}
|
||||
}
|
||||
|
||||
// Derive key
|
||||
retval = SecureElementAesEncrypt( input, 16, rootKeyID, key );
|
||||
if( retval != SECURE_ELEMENT_SUCCESS )
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Store key
|
||||
retval = SecureElementSetKey( targetKeyID, key );
|
||||
if( retval != SECURE_ELEMENT_SUCCESS )
|
||||
{
|
||||
return retval;
|
||||
}
|
||||
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementRandomNumber( uint32_t* randomNum )
|
||||
{
|
||||
if( randomNum == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
*randomNum = Radio.Random( );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui )
|
||||
{
|
||||
if( devEui == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
memcpy1( SeNvmCtx.DevEui, devEui, SE_EUI_SIZE );
|
||||
SeNvmCtxChanged( );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t* SecureElementGetDevEui( void )
|
||||
{
|
||||
return SeNvmCtx.DevEui;
|
||||
}
|
||||
|
||||
SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui )
|
||||
{
|
||||
if( joinEui == NULL )
|
||||
{
|
||||
return SECURE_ELEMENT_ERROR_NPE;
|
||||
}
|
||||
memcpy1( SeNvmCtx.JoinEui, joinEui, SE_EUI_SIZE );
|
||||
SeNvmCtxChanged( );
|
||||
return SECURE_ELEMENT_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t* SecureElementGetJoinEui( void )
|
||||
{
|
||||
return SeNvmCtx.JoinEui;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
--- Revised BSD License ---
|
||||
Copyright (c) 2013, SEMTECH S.A.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the Semtech corporation nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,131 @@
|
|||
/*!
|
||||
* \file LoRaMacAdr.c
|
||||
*
|
||||
* \brief LoRa MAC ADR implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
|
||||
#include "utilities.h"
|
||||
#include "region/Region.h"
|
||||
#include "LoRaMacAdr.h"
|
||||
|
||||
static bool CalcNextV10X( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter )
|
||||
{
|
||||
bool adrAckReq = false;
|
||||
int8_t datarate = adrNext->Datarate;
|
||||
int8_t txPower = adrNext->TxPower;
|
||||
int8_t minTxDatarate;
|
||||
GetPhyParams_t getPhy;
|
||||
PhyParam_t phyParam;
|
||||
|
||||
// Report back the adr ack counter
|
||||
*adrAckCounter = adrNext->AdrAckCounter;
|
||||
|
||||
if( adrNext->AdrEnabled == true )
|
||||
{
|
||||
// Query minimum TX Datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR;
|
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime;
|
||||
phyParam = RegionGetPhyParam( adrNext->Region, &getPhy );
|
||||
minTxDatarate = phyParam.Value;
|
||||
datarate = MAX( datarate, minTxDatarate );
|
||||
|
||||
if( datarate == minTxDatarate )
|
||||
{
|
||||
*adrAckCounter = 0;
|
||||
adrAckReq = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( adrNext->AdrAckCounter >= adrNext->AdrAckLimit )
|
||||
{
|
||||
adrAckReq = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
adrAckReq = false;
|
||||
}
|
||||
if( adrNext->AdrAckCounter >= ( adrNext->AdrAckLimit + adrNext->AdrAckDelay ) )
|
||||
{
|
||||
// Set TX Power to maximum
|
||||
getPhy.Attribute = PHY_MAX_TX_POWER;
|
||||
phyParam = RegionGetPhyParam( adrNext->Region, &getPhy );
|
||||
txPower = phyParam.Value;
|
||||
|
||||
if( ( adrNext->AdrAckCounter % adrNext->AdrAckDelay ) == 1 )
|
||||
{
|
||||
// Decrease the datarate
|
||||
getPhy.Attribute = PHY_NEXT_LOWER_TX_DR;
|
||||
getPhy.Datarate = datarate;
|
||||
getPhy.UplinkDwellTime = adrNext->UplinkDwellTime;
|
||||
phyParam = RegionGetPhyParam( adrNext->Region, &getPhy );
|
||||
datarate = phyParam.Value;
|
||||
|
||||
if( datarate == minTxDatarate )
|
||||
{
|
||||
// We must set adrAckReq to false as soon as we reach the lowest datarate
|
||||
adrAckReq = false;
|
||||
if( adrNext->UpdateChanMask == true )
|
||||
{
|
||||
InitDefaultsParams_t params;
|
||||
params.Type = INIT_TYPE_RESTORE_DEFAULT_CHANNELS;
|
||||
RegionInitDefaults( adrNext->Region, ¶ms );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*drOut = datarate;
|
||||
*txPowOut = txPower;
|
||||
return adrAckReq;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [IN] adrNext Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [OUT] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval Returns true, if an ADR request should be performed.
|
||||
*/
|
||||
bool LoRaMacAdrCalcNext( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter )
|
||||
{
|
||||
if( adrNext->Version.Fields.Minor == 0 )
|
||||
{
|
||||
return CalcNextV10X( adrNext, drOut, txPowOut, adrAckCounter );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*!
|
||||
* \file LoRaMacAdr.h
|
||||
*
|
||||
* \brief LoRa MAC ADR implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMACADR LoRa MAC ADR implementation
|
||||
* Implementation of the ADR algorithm for LoRa.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __LORAMACADR_H__
|
||||
#define __LORAMACADR_H__
|
||||
|
||||
/*! \} defgroup LORAMACADR */
|
||||
|
||||
/*
|
||||
* Parameter structure for the function CalcNextAdr.
|
||||
*/
|
||||
typedef struct sCalcNextAdrParams
|
||||
{
|
||||
/*!
|
||||
* LoRaWAN Minor Version 1.X
|
||||
*/
|
||||
Version_t Version;
|
||||
/*!
|
||||
* Set to true, if the function should update the channels mask.
|
||||
*/
|
||||
bool UpdateChanMask;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool AdrEnabled;
|
||||
/*!
|
||||
* ADR ack counter.
|
||||
*/
|
||||
uint32_t AdrAckCounter;
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
uint16_t AdrAckLimit;
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
uint16_t AdrAckDelay;
|
||||
/*!
|
||||
* Datarate used currently.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* TX power used currently.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* UplinkDwellTime
|
||||
*/
|
||||
uint8_t UplinkDwellTime;
|
||||
/*!
|
||||
* Region
|
||||
*/
|
||||
LoRaMacRegion_t Region;
|
||||
}CalcNextAdrParams_t;
|
||||
|
||||
/*!
|
||||
* \brief Calculates the next datarate to set, when ADR is on or off.
|
||||
*
|
||||
* \param [IN] adrNext Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] drOut The calculated datarate for the next TX.
|
||||
*
|
||||
* \param [OUT] txPowOut The TX power for the next TX.
|
||||
*
|
||||
* \param [OUT] adrAckCounter The calculated ADR acknowledgement counter.
|
||||
*
|
||||
* \retval Returns true, if an ADR request should be performed.
|
||||
*/
|
||||
bool LoRaMacAdrCalcNext( CalcNextAdrParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter );
|
||||
|
||||
#endif // __LORAMACADR_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,670 @@
|
|||
/*!
|
||||
* \file LoRaMacClassB.h
|
||||
*
|
||||
* \brief LoRa MAC Class B layer implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMACCLASSB LoRa MAC Class B layer implementation
|
||||
* This module specifies the API implementation of the LoRaMAC Class B layer.
|
||||
* This is a placeholder for a detailed description of the LoRaMac
|
||||
* layer and the supported features.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __LORAMACCLASSB_H__
|
||||
#define __LORAMACCLASSB_H__
|
||||
|
||||
#include "systime.h"
|
||||
#include "LoRaMacTypes.h"
|
||||
|
||||
/*!
|
||||
* States of the class B beacon acquisition and tracking
|
||||
*/
|
||||
typedef enum eBeaconState
|
||||
{
|
||||
/*!
|
||||
* Initial state to acquire the beacon
|
||||
*/
|
||||
BEACON_STATE_ACQUISITION,
|
||||
/*!
|
||||
* Beacon acquisition state when a time reference is available
|
||||
*/
|
||||
BEACON_STATE_ACQUISITION_BY_TIME,
|
||||
/*!
|
||||
* Handles the state when the beacon reception fails
|
||||
*/
|
||||
BEACON_STATE_TIMEOUT,
|
||||
/*!
|
||||
* Handles the state when the beacon was missed due to an uplink
|
||||
*/
|
||||
BEACON_STATE_BEACON_MISSED,
|
||||
/*!
|
||||
* Reacquisition state which applies the algorithm to enlarge the reception
|
||||
* windows
|
||||
*/
|
||||
BEACON_STATE_REACQUISITION,
|
||||
/*!
|
||||
* The node has locked a beacon successfully
|
||||
*/
|
||||
BEACON_STATE_LOCKED,
|
||||
/*!
|
||||
* The beacon state machine is stopped due to operations with higher priority
|
||||
*/
|
||||
BEACON_STATE_HALT,
|
||||
/*!
|
||||
* The node currently operates in the beacon window and is idle. In this
|
||||
* state, the temperature measurement takes place
|
||||
*/
|
||||
BEACON_STATE_IDLE,
|
||||
/*!
|
||||
* The node operates in the guard time of class B
|
||||
*/
|
||||
BEACON_STATE_GUARD,
|
||||
/*!
|
||||
* The node is in receive mode to lock a beacon
|
||||
*/
|
||||
BEACON_STATE_RX,
|
||||
/*!
|
||||
* The nodes switches the device class
|
||||
*/
|
||||
BEACON_STATE_LOST,
|
||||
}BeaconState_t;
|
||||
|
||||
/*!
|
||||
* States of the class B ping slot mechanism
|
||||
*/
|
||||
typedef enum ePingSlotState
|
||||
{
|
||||
/*!
|
||||
* Calculation of the ping slot offset
|
||||
*/
|
||||
PINGSLOT_STATE_CALC_PING_OFFSET,
|
||||
/*!
|
||||
* State to set the timer to open the next ping slot
|
||||
*/
|
||||
PINGSLOT_STATE_SET_TIMER,
|
||||
/*!
|
||||
* The node is in idle state
|
||||
*/
|
||||
PINGSLOT_STATE_IDLE,
|
||||
/*!
|
||||
* The node opens up a ping slot window
|
||||
*/
|
||||
PINGSLOT_STATE_RX,
|
||||
}PingSlotState_t;
|
||||
|
||||
/*!
|
||||
* Class B ping slot context structure
|
||||
*/
|
||||
typedef struct sPingSlotContext
|
||||
{
|
||||
|
||||
/*!
|
||||
* Ping slot length time in ms
|
||||
*/
|
||||
uint32_t PingSlotWindow;
|
||||
/*!
|
||||
* Ping offset
|
||||
*/
|
||||
uint16_t PingOffset;
|
||||
/*!
|
||||
* Current symbol timeout. The node enlarges this variable in case of beacon
|
||||
* loss.
|
||||
*/
|
||||
uint16_t SymbolTimeout;
|
||||
/*!
|
||||
* The multicast channel which will be enabled next.
|
||||
*/
|
||||
MulticastCtx_t *NextMulticastChannel;
|
||||
}PingSlotContext_t;
|
||||
|
||||
|
||||
/*!
|
||||
* Class B beacon context structure
|
||||
*/
|
||||
typedef struct sBeaconContext
|
||||
{
|
||||
struct sBeaconCtrl
|
||||
{
|
||||
/*!
|
||||
* Set if the node receives beacons
|
||||
*/
|
||||
uint8_t BeaconMode : 1;
|
||||
/*!
|
||||
* Set if the node has acquired the beacon
|
||||
*/
|
||||
uint8_t BeaconAcquired : 1;
|
||||
/*!
|
||||
* Set if a beacon delay was set for the beacon acquisition
|
||||
*/
|
||||
uint8_t BeaconDelaySet : 1;
|
||||
/*!
|
||||
* Set if a beacon channel was set for the beacon acquisition
|
||||
*/
|
||||
uint8_t BeaconChannelSet : 1;
|
||||
/*!
|
||||
* Set if beacon acquisition is pending
|
||||
*/
|
||||
uint8_t AcquisitionPending : 1;
|
||||
/*!
|
||||
* Set if the beacon state machine will be resumed
|
||||
*/
|
||||
uint8_t ResumeBeaconing : 1;
|
||||
}Ctrl;
|
||||
|
||||
/*!
|
||||
* Current temperature
|
||||
*/
|
||||
float Temperature;
|
||||
/*!
|
||||
* Beacon time received with the beacon frame
|
||||
*/
|
||||
SysTime_t BeaconTime;
|
||||
/*!
|
||||
* Time when the last beacon was received
|
||||
*/
|
||||
SysTime_t LastBeaconRx;
|
||||
/*!
|
||||
* Time when the next beacon will be received
|
||||
*/
|
||||
SysTime_t NextBeaconRx;
|
||||
/*!
|
||||
* This is the time where the RX window will be opened.
|
||||
* Its base is NextBeaconRx with temperature compensations
|
||||
* and RX window movement.
|
||||
*/
|
||||
TimerTime_t NextBeaconRxAdjusted;
|
||||
/*!
|
||||
* Current symbol timeout. The node enlarges this variable in case of beacon
|
||||
* loss.
|
||||
*/
|
||||
uint16_t SymbolTimeout;
|
||||
/*!
|
||||
* Specifies how much time the beacon window will be moved.
|
||||
*/
|
||||
TimerTime_t BeaconWindowMovement;
|
||||
/*!
|
||||
* Beacon timing channel for next beacon
|
||||
*/
|
||||
uint8_t BeaconTimingChannel;
|
||||
/*!
|
||||
* Delay for next beacon in ms
|
||||
*/
|
||||
TimerTime_t BeaconTimingDelay;
|
||||
TimerTime_t TimeStamp;
|
||||
}BeaconContext_t;
|
||||
|
||||
/*!
|
||||
* Data structure which contains the callbacks
|
||||
*/
|
||||
typedef struct sLoRaMacClassBCallback
|
||||
{
|
||||
/*!
|
||||
* \brief Measures the temperature level
|
||||
*
|
||||
* \retval Temperature level
|
||||
*/
|
||||
uint16_t ( *GetTemperatureLevel )( void );
|
||||
/*!
|
||||
*\brief Will be called each time a Radio IRQ is handled by the MAC
|
||||
* layer.
|
||||
*
|
||||
*\warning Runs in a IRQ context. Should only change variables state.
|
||||
*/
|
||||
void ( *MacProcessNotify )( void );
|
||||
}LoRaMacClassBCallback_t;
|
||||
|
||||
/*!
|
||||
* Data structure which pointers to the properties LoRaMAC
|
||||
*/
|
||||
typedef struct sLoRaMacClassBParams
|
||||
{
|
||||
/*!
|
||||
* Pointer to the MlmeIndication structure
|
||||
*/
|
||||
MlmeIndication_t *MlmeIndication;
|
||||
/*!
|
||||
* Pointer to the McpsIndication structure
|
||||
*/
|
||||
McpsIndication_t *McpsIndication;
|
||||
/*!
|
||||
* Pointer to the MlmeConfirm structure
|
||||
*/
|
||||
MlmeConfirm_t *MlmeConfirm;
|
||||
/*!
|
||||
* Pointer to the LoRaMacFlags structure
|
||||
*/
|
||||
LoRaMacFlags_t *LoRaMacFlags;
|
||||
/*!
|
||||
* Pointer to the LoRaMac device address
|
||||
*/
|
||||
uint32_t *LoRaMacDevAddr;
|
||||
/*!
|
||||
* Pointer to the LoRaMac region definition
|
||||
*/
|
||||
LoRaMacRegion_t *LoRaMacRegion;
|
||||
/*!
|
||||
* Pointer to the LoRaMacParams structure
|
||||
*/
|
||||
LoRaMacParams_t *LoRaMacParams;
|
||||
/*!
|
||||
* Pointer to the multicast channel list
|
||||
*/
|
||||
MulticastCtx_t *MulticastChannels;
|
||||
}LoRaMacClassBParams_t;
|
||||
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *LoRaMacClassBNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialize LoRaWAN Class B
|
||||
*
|
||||
* \param [IN] classBParams Information and feedback parameter
|
||||
* \param [IN] callbacks Contains the callback which the Class B implementation needs
|
||||
* \param [IN] callback function which will be called when the non-volatile context needs to be saved.
|
||||
*/
|
||||
void LoRaMacClassBInit( LoRaMacClassBParams_t *classBParams, LoRaMacClassBCallback_t *callbacks, LoRaMacClassBNvmEvent classBNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
*
|
||||
* \param [IN] classBNvmCtx - Pointer to non-volatile class B module context to be restored.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
bool LoRaMacClassBRestoreNvmCtx( void* classBNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param [IN] classBNvmCtxSize - Size of the module non-volatile context
|
||||
*
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacClassBGetNvmCtx( size_t* classBNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* \brief Set the state of the beacon state machine
|
||||
*
|
||||
* \param [IN] beaconState Beacon state.
|
||||
*/
|
||||
void LoRaMacClassBSetBeaconState( BeaconState_t beaconState );
|
||||
|
||||
/*!
|
||||
* \brief Set the state of the ping slot state machine
|
||||
*
|
||||
* \param [IN] pingSlotState Ping slot state.
|
||||
*/
|
||||
void LoRaMacClassBSetPingSlotState( PingSlotState_t pingSlotState );
|
||||
|
||||
/*!
|
||||
* \brief Set the state of the multicast slot state machine
|
||||
*
|
||||
* \param [IN] pingSlotState multicast slot state.
|
||||
*/
|
||||
void LoRaMacClassBSetMulticastSlotState( PingSlotState_t multicastSlotState );
|
||||
|
||||
/*!
|
||||
* \brief Verifies if an acquisition procedure is in progress
|
||||
*
|
||||
* \retval [true, if the acquisition is in progress; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsAcquisitionInProgress( void );
|
||||
|
||||
/*!
|
||||
* \brief State machine of the Class B for beaconing
|
||||
*/
|
||||
void LoRaMacClassBBeaconTimerEvent( void* context );
|
||||
|
||||
/*!
|
||||
* \brief State machine of the Class B for ping slots
|
||||
*/
|
||||
void LoRaMacClassBPingSlotTimerEvent( void* context );
|
||||
|
||||
/*!
|
||||
* \brief State machine of the Class B for multicast slots
|
||||
*/
|
||||
void LoRaMacClassBMulticastSlotTimerEvent( void* context );
|
||||
|
||||
/*!
|
||||
* \brief Receives and decodes the beacon frame
|
||||
*
|
||||
* \param [IN] payload Pointer to the payload
|
||||
* \param [IN] size Size of the payload
|
||||
* \retval [true, if the node has received a beacon; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBRxBeacon( uint8_t *payload, uint16_t size );
|
||||
|
||||
/*!
|
||||
* \brief The function validates, if the node expects a beacon
|
||||
* at the current time.
|
||||
*
|
||||
* \retval [true, if the node expects a beacon; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsBeaconExpected( void );
|
||||
|
||||
/*!
|
||||
* \brief The function validates, if the node expects a ping slot
|
||||
* at the current time.
|
||||
*
|
||||
* \retval [true, if the node expects a ping slot; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsPingExpected( void );
|
||||
|
||||
/*!
|
||||
* \brief The function validates, if the node expects a multicast slot
|
||||
* at the current time.
|
||||
*
|
||||
* \retval [true, if the node expects a multicast slot; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsMulticastExpected( void );
|
||||
|
||||
/*!
|
||||
* \brief Verifies if the acquisition pending bit is set
|
||||
*
|
||||
* \retval [true, if the bit is set; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsAcquisitionPending( void );
|
||||
|
||||
/*!
|
||||
* \brief Verifies if the beacon mode active bit is set
|
||||
*
|
||||
* \retval [true, if the bit is set; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBIsBeaconModeActive( void );
|
||||
|
||||
/*!
|
||||
* \brief Stops the beacon and ping slot operation
|
||||
*/
|
||||
void LoRaMacClassBHaltBeaconing( void );
|
||||
|
||||
/*!
|
||||
* \brief Resumes the beacon and ping slot operation
|
||||
*/
|
||||
void LoRaMacClassBResumeBeaconing( void );
|
||||
|
||||
/*!
|
||||
* \brief Sets the periodicity of the ping slots
|
||||
*
|
||||
* \param [IN] periodicity Periodicity
|
||||
*/
|
||||
void LoRaMacClassBSetPingSlotInfo( uint8_t periodicity );
|
||||
|
||||
/*!
|
||||
* \brief Switches the device class
|
||||
*
|
||||
* \param [IN] nextClass Device class to switch to
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacClassBSwitchClass( DeviceClass_t nextClass );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC ClassB MIB-Get
|
||||
*
|
||||
* \details The mac information base service to get attributes of the LoRaMac
|
||||
* Class B layer.
|
||||
*
|
||||
* \param [IN] mibRequest - MIB-GET-Request to perform. Refer to \ref MibRequestConfirm_t.
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN,
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacClassBMibGetRequestConfirm( MibRequestConfirm_t *mibGet );
|
||||
|
||||
/*!
|
||||
* \brief LoRaMAC Class B MIB-Set
|
||||
*
|
||||
* \details The mac information base service to set attributes of the LoRaMac
|
||||
* Class B layer.
|
||||
*
|
||||
* \param [IN] mibRequest - MIB-SET-Request to perform. Refer to \ref MibRequestConfirm_t.
|
||||
*
|
||||
* \retval LoRaMacStatus_t Status of the operation. Possible returns are:
|
||||
* \ref LORAMAC_STATUS_OK,
|
||||
* \ref LORAMAC_STATUS_BUSY,
|
||||
* \ref LORAMAC_STATUS_SERVICE_UNKNOWN,
|
||||
* \ref LORAMAC_STATUS_PARAMETER_INVALID.
|
||||
*/
|
||||
LoRaMacStatus_t LoRaMacMibClassBSetRequestConfirm( MibRequestConfirm_t *mibSet );
|
||||
|
||||
/*!
|
||||
* \brief This function handles the PING_SLOT_FREQ_ANS
|
||||
*/
|
||||
void LoRaMacClassBPingSlotInfoAns( void );
|
||||
|
||||
/*!
|
||||
* \brief This function handles the PING_SLOT_CHANNEL_REQ
|
||||
*
|
||||
* \param [IN] datarate Device class to switch to
|
||||
* \param [IN] frequency Device class to switch to
|
||||
*
|
||||
* \retval Status for the MAC answer.
|
||||
*/
|
||||
uint8_t LoRaMacClassBPingSlotChannelReq( uint8_t datarate, uint32_t frequency );
|
||||
|
||||
/*!
|
||||
* \brief This function handles the BEACON_TIMING_ANS
|
||||
*
|
||||
* \param [IN] beaconTimingDelay The beacon timing delay
|
||||
* \param [IN] beaconTimingChannel The beacon timing channel
|
||||
* \param [IN] lastRxDone The time of the last frame reception
|
||||
*/
|
||||
void LoRaMacClassBBeaconTimingAns( uint16_t beaconTimingDelay, uint8_t beaconTimingChannel, TimerTime_t lastRxDone );
|
||||
|
||||
/*!
|
||||
* \brief This function handles the ClassB DEVICE_TIME_ANS
|
||||
*/
|
||||
void LoRaMacClassBDeviceTimeAns( void );
|
||||
|
||||
/*!
|
||||
* \brief This function handles the BEACON_FREQ_REQ
|
||||
*
|
||||
* \param [IN] frequency Frequency to set
|
||||
*
|
||||
* \retval [true, if MAC shall send an answer; false, if not]
|
||||
*/
|
||||
bool LoRaMacClassBBeaconFreqReq( uint32_t frequency );
|
||||
|
||||
/*!
|
||||
* \brief Queries the ping slot window time
|
||||
*
|
||||
* \param [IN] txTimeOnAir TX time on air for the next uplink
|
||||
*
|
||||
* \retval Returns the time the uplink should be delayed
|
||||
*/
|
||||
TimerTime_t LoRaMacClassBIsUplinkCollision( TimerTime_t txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief Stops the timers for the RX slots. This includes the
|
||||
* timers for ping and multicast slots.
|
||||
*/
|
||||
void LoRaMacClassBStopRxSlots( void );
|
||||
|
||||
/*!
|
||||
* \brief Starts the timers for the RX slots. This includes the
|
||||
* timers for ping and multicast slots.
|
||||
*/
|
||||
void LoRaMacClassBStartRxSlots( void );
|
||||
|
||||
/*!
|
||||
* \brief Starts the timers for the RX slots. This includes the
|
||||
* timers for ping and multicast slots.
|
||||
*
|
||||
* \param [IN] periodicity Downlink periodicity
|
||||
*
|
||||
* \param [IN] multicastChannel Related multicast channel
|
||||
*/
|
||||
void LoRaMacClassBSetMulticastPeriodicity( MulticastCtx_t* multicastChannel );
|
||||
|
||||
void LoRaMacClassBProcess( void );
|
||||
|
||||
|
||||
/*
|
||||
* LoRaMac Class B Context structure for NVM parameters
|
||||
* related to ping slots
|
||||
*/
|
||||
typedef struct sLoRaMacClassBPingSlotNvmCtx
|
||||
{
|
||||
struct sPingSlotCtrlNvm
|
||||
{
|
||||
/*!
|
||||
* Set when the server assigned a ping slot to the node
|
||||
*/
|
||||
uint8_t Assigned : 1;
|
||||
/*!
|
||||
* Set when a custom frequency is used
|
||||
*/
|
||||
uint8_t CustomFreq : 1;
|
||||
}Ctrl;
|
||||
/*!
|
||||
* Number of ping slots
|
||||
*/
|
||||
uint8_t PingNb;
|
||||
/*!
|
||||
* Period of the ping slots
|
||||
*/
|
||||
uint16_t PingPeriod;
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
} LoRaMacClassBPingSlotNvmCtx_t;
|
||||
|
||||
/*
|
||||
* LoRaMac Class B Context structure for NVM parameters
|
||||
* related to beaconing
|
||||
*/
|
||||
typedef struct sLoRaMacClassBBeaconNvmCtx
|
||||
{
|
||||
struct sBeaconCtrlNvm
|
||||
{
|
||||
/*!
|
||||
* Set if the node has a custom frequency for beaconing and ping slots
|
||||
*/
|
||||
uint8_t CustomFreq : 1;
|
||||
}Ctrl;
|
||||
/*!
|
||||
* Beacon reception frequency
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* State of the beaconing mechanism
|
||||
*/
|
||||
BeaconState_t BeaconState;
|
||||
/*!
|
||||
* Time when the last beacon was received
|
||||
*/
|
||||
SysTime_t LastBeaconRx;
|
||||
/*!
|
||||
* Data structure for the gateway specific part. The
|
||||
* content of the values may differ for each gateway
|
||||
*/
|
||||
struct sGwSpecific GwSpecific;
|
||||
} LoRaMacClassBBeaconNvmCtx_t;
|
||||
|
||||
/*
|
||||
* LoRaMac Class B Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacClassBNvmCtx
|
||||
{
|
||||
/*!
|
||||
* Class B ping slot context
|
||||
*/
|
||||
LoRaMacClassBPingSlotNvmCtx_t PingSlotCtx;
|
||||
/*!
|
||||
* Class B beacon context
|
||||
*/
|
||||
LoRaMacClassBBeaconNvmCtx_t BeaconCtx;
|
||||
} LoRaMacClassBNvmCtx_t;
|
||||
|
||||
/*
|
||||
* LoRaMac Class B Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacClassBCtx
|
||||
{
|
||||
/*!
|
||||
* Class B ping slot context
|
||||
*/
|
||||
PingSlotContext_t PingSlotCtx;
|
||||
/*!
|
||||
* Class B beacon context
|
||||
*/
|
||||
BeaconContext_t BeaconCtx;
|
||||
/*!
|
||||
* State of the beaconing mechanism
|
||||
*/
|
||||
BeaconState_t BeaconState;
|
||||
/*!
|
||||
* State of the ping slot mechanism
|
||||
*/
|
||||
PingSlotState_t PingSlotState;
|
||||
/*!
|
||||
* State of the multicast slot mechanism
|
||||
*/
|
||||
PingSlotState_t MulticastSlotState;
|
||||
/*!
|
||||
* Timer for CLASS B beacon acquisition and tracking.
|
||||
*/
|
||||
TimerEvent_t BeaconTimer;
|
||||
/*!
|
||||
* Timer for CLASS B ping slot timer.
|
||||
*/
|
||||
TimerEvent_t PingSlotTimer;
|
||||
/*!
|
||||
* Timer for CLASS B multicast ping slot timer.
|
||||
*/
|
||||
TimerEvent_t MulticastSlotTimer;
|
||||
/*!
|
||||
* Container for the callbacks related to class b.
|
||||
*/
|
||||
LoRaMacClassBCallback_t LoRaMacClassBCallbacks;
|
||||
/*!
|
||||
* Data structure which holds the parameters which needs to be set
|
||||
* in class b operation.
|
||||
*/
|
||||
LoRaMacClassBParams_t LoRaMacClassBParams;
|
||||
/*
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
LoRaMacClassBNvmEvent LoRaMacClassBNvmEvent;
|
||||
/*!
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
LoRaMacClassBNvmCtx_t* NvmCtx;
|
||||
} LoRaMacClassBCtx_t;
|
||||
|
||||
#endif // __LORAMACCLASSB_H__
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*!
|
||||
* \file LoRaMacClassBConfig.h
|
||||
*
|
||||
* \brief LoRa MAC Class B configuration
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMACCLASSB LoRa MAC Class B configuration
|
||||
* This header file contains parameters to configure the class b operation.
|
||||
* By default, all parameters are set according to the specification.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __LORAMACCLASSBCONFIG_H__
|
||||
#define __LORAMACCLASSBCONFIG_H__
|
||||
|
||||
/*!
|
||||
* Defines the beacon interval in ms
|
||||
*/
|
||||
#define CLASSB_BEACON_INTERVAL 128000
|
||||
|
||||
/*!
|
||||
* Beacon reserved time in ms
|
||||
*/
|
||||
#define CLASSB_BEACON_RESERVED 2120
|
||||
|
||||
/*!
|
||||
* Beacon guard time in ms
|
||||
*/
|
||||
#define CLASSB_BEACON_GUARD 3000
|
||||
|
||||
/*!
|
||||
* Beacon window time in ms
|
||||
*/
|
||||
#define CLASSB_BEACON_WINDOW 122880
|
||||
|
||||
/*!
|
||||
* Beacon window time in numer of slots
|
||||
*/
|
||||
#define CLASSB_BEACON_WINDOW_SLOTS 4096
|
||||
|
||||
/*!
|
||||
* Ping slot length time in ms
|
||||
*/
|
||||
#define CLASSB_PING_SLOT_WINDOW 30
|
||||
|
||||
/*!
|
||||
* Maximum allowed beacon less time in ms
|
||||
*/
|
||||
#define CLASSB_MAX_BEACON_LESS_PERIOD 7200000
|
||||
|
||||
/*!
|
||||
* Delay time for the BeaconTimingAns in ms
|
||||
*/
|
||||
#define CLASSB_BEACON_DELAY_BEACON_TIMING_ANS 30
|
||||
|
||||
/*!
|
||||
* Default symbol timeout for beacons and ping slot windows
|
||||
*/
|
||||
#define CLASSB_BEACON_SYMBOL_TO_DEFAULT 8
|
||||
|
||||
/*!
|
||||
* Maximum symbol timeout for beacons
|
||||
*/
|
||||
#define CLASSB_BEACON_SYMBOL_TO_EXPANSION_MAX 255
|
||||
|
||||
/*!
|
||||
* Maximum symbol timeout for ping slots
|
||||
*/
|
||||
#define CLASSB_PING_SLOT_SYMBOL_TO_EXPANSION_MAX 30
|
||||
|
||||
/*!
|
||||
* Symbol expansion value for beacon windows in case of beacon
|
||||
* loss in symbols
|
||||
*/
|
||||
#define CLASSB_BEACON_SYMBOL_TO_EXPANSION_FACTOR 2
|
||||
|
||||
/*!
|
||||
* Defines the default window movement time
|
||||
*/
|
||||
#define CLASSB_WINDOW_MOVE_DEFAULT 2
|
||||
|
||||
/*!
|
||||
* Defines the maximum time for the beacon movement
|
||||
*/
|
||||
#define CLASSB_WINDOW_MOVE_EXPANSION_MAX 256
|
||||
|
||||
/*!
|
||||
* Defines the expansion factor for the beacon movement
|
||||
*/
|
||||
#define CLASSB_WINDOW_MOVE_EXPANSION_FACTOR 2
|
||||
|
||||
#endif // __LORAMACCLASSBCONFIG_H__
|
||||
|
|
@ -0,0 +1,547 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC commands
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
|
||||
#include "utilities.h"
|
||||
#include "LoRaMacCommands.h"
|
||||
#include "LoRaMacConfirmQueue.h"
|
||||
|
||||
/*!
|
||||
* Number of MAC Command slots
|
||||
*/
|
||||
#define NUM_OF_MAC_COMMANDS 15
|
||||
|
||||
/*!
|
||||
* Size of the CID field of MAC commands
|
||||
*/
|
||||
#define CID_FIELD_SIZE 1
|
||||
|
||||
/*!
|
||||
* Mac Commands list structure
|
||||
*/
|
||||
typedef struct sMacCommandsList
|
||||
{
|
||||
/*
|
||||
* First element of MAC command list.
|
||||
*/
|
||||
MacCommand_t* First;
|
||||
/*
|
||||
* Last element of MAC command list.
|
||||
*/
|
||||
MacCommand_t* Last;
|
||||
} MacCommandsList_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac Commands Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacCommandsCtx
|
||||
{
|
||||
/*
|
||||
* List of MAC command elements
|
||||
*/
|
||||
MacCommandsList_t MacCommandList;
|
||||
/*
|
||||
* Buffer to store MAC command elements
|
||||
*/
|
||||
MacCommand_t MacCommandSlots[NUM_OF_MAC_COMMANDS];
|
||||
/*
|
||||
* Size of all MAC commands serialized as buffer
|
||||
*/
|
||||
size_t SerializedCmdsSize;
|
||||
} LoRaMacCommandsCtx_t;
|
||||
|
||||
/*!
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
static LoRaMacCommandsNvmEvent CommandsNvmCtxChanged;
|
||||
|
||||
/*!
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static LoRaMacCommandsCtx_t NvmCtx;
|
||||
|
||||
/* Memory management functions */
|
||||
|
||||
/*!
|
||||
* \brief Determines if a MAC command slot is free
|
||||
*
|
||||
* \param[IN] slot - Slot to check
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool IsSlotFree( const MacCommand_t* slot )
|
||||
{
|
||||
uint8_t* mem = ( uint8_t* )slot;
|
||||
|
||||
for( uint16_t size = 0; size < sizeof( MacCommand_t ); size++ )
|
||||
{
|
||||
if( mem[size] != 0x00 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Allocates a new MAC command memory slot
|
||||
*
|
||||
* \retval - Pointer to slot
|
||||
*/
|
||||
static MacCommand_t* MallocNewMacCommandSlot( void )
|
||||
{
|
||||
uint8_t itr = 0;
|
||||
|
||||
while( IsSlotFree( ( const MacCommand_t* )&NvmCtx.MacCommandSlots[itr] ) == false )
|
||||
{
|
||||
itr++;
|
||||
if( itr == NUM_OF_MAC_COMMANDS )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return &NvmCtx.MacCommandSlots[itr];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Free memory slot
|
||||
*
|
||||
* \param[IN] slot - Slot to free
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool FreeMacCommandSlot( MacCommand_t* slot )
|
||||
{
|
||||
if( slot == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset1( ( uint8_t* )slot, 0x00, sizeof( MacCommand_t ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Linked list functions */
|
||||
|
||||
/*!
|
||||
* \brief Initialize list
|
||||
*
|
||||
* \param[IN] list - List that shall be initialized
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool LinkedListInit( MacCommandsList_t* list )
|
||||
{
|
||||
if( list == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
list->First = 0;
|
||||
list->Last = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Add an element to the list
|
||||
*
|
||||
* \param[IN] list - List where the element shall be added.
|
||||
* \param[IN] element - Element to add
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool LinkedListAdd( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this is the first entry to enter the list.
|
||||
if( list->First == 0 )
|
||||
{
|
||||
list->First = element;
|
||||
}
|
||||
|
||||
// Check if the last entry exists and update its next point.
|
||||
if( list->Last )
|
||||
{
|
||||
list->Last->Next = element;
|
||||
}
|
||||
|
||||
// Update the next point of this entry.
|
||||
element->Next = 0;
|
||||
|
||||
// Update the last entry of the list.
|
||||
list->Last = element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Return the previous element in the list.
|
||||
*
|
||||
* \param[IN] list - List
|
||||
* \param[IN] element - Element where the previous element shall be searched
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static MacCommand_t* LinkedListGetPrevious( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MacCommand_t* curElement;
|
||||
|
||||
// Start at the head of the list
|
||||
curElement = list->First;
|
||||
|
||||
// When current element is the first of the list, there's no previous element so we can return NULL immediately.
|
||||
if( element != curElement )
|
||||
{
|
||||
// Loop through all elements until the end is reached or the next of current is the current element.
|
||||
while( ( curElement != NULL ) && ( curElement->Next != element ) )
|
||||
{
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curElement = NULL;
|
||||
}
|
||||
|
||||
return curElement;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Remove an element from the list
|
||||
*
|
||||
* \param[IN] list - List where the element shall be removed from.
|
||||
* \param[IN] element - Element to remove
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool LinkedListRemove( MacCommandsList_t* list, MacCommand_t* element )
|
||||
{
|
||||
if( ( list == 0 ) && ( element == 0 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MacCommand_t* PrevElement = LinkedListGetPrevious( list, element );
|
||||
|
||||
if( list->First == element )
|
||||
{
|
||||
list->First = element->Next;
|
||||
}
|
||||
|
||||
if( list->Last == element )
|
||||
{
|
||||
list->Last = PrevElement;
|
||||
}
|
||||
|
||||
if( PrevElement != NULL )
|
||||
{
|
||||
PrevElement->Next = element->Next;
|
||||
}
|
||||
|
||||
element->Next = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Determines if a MAC command is sticky or not
|
||||
*
|
||||
* \param[IN] cid - MAC command identifier
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
static bool IsSticky( uint8_t cid )
|
||||
{
|
||||
switch( cid )
|
||||
{
|
||||
case MOTE_MAC_DL_CHANNEL_ANS:
|
||||
case MOTE_MAC_RX_PARAM_SETUP_ANS:
|
||||
case MOTE_MAC_RX_TIMING_SETUP_ANS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Wrapper function for the NvmCtx
|
||||
*/
|
||||
static void NvmCtxCallback( void )
|
||||
{
|
||||
if( CommandsNvmCtxChanged != NULL )
|
||||
{
|
||||
CommandsNvmCtxChanged( );
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged )
|
||||
{
|
||||
// Initialize with default
|
||||
memset1( ( uint8_t* )&NvmCtx, 0, sizeof( NvmCtx ) );
|
||||
|
||||
LinkedListInit( &NvmCtx.MacCommandList );
|
||||
|
||||
// Assign callback
|
||||
CommandsNvmCtxChanged = commandsNvmCtxChanged;
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx )
|
||||
{
|
||||
// Restore module context
|
||||
if( commandsNvmCtx != NULL )
|
||||
{
|
||||
memcpy1( ( uint8_t* )&NvmCtx, ( uint8_t* )commandsNvmCtx, sizeof( NvmCtx ) );
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
}
|
||||
|
||||
void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize )
|
||||
{
|
||||
*commandsNvmCtxSize = sizeof( NvmCtx );
|
||||
return &NvmCtx;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize )
|
||||
{
|
||||
if( payload == 0 )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
MacCommand_t* newCmd;
|
||||
|
||||
// Allocate a memory slot
|
||||
newCmd = MallocNewMacCommandSlot( );
|
||||
|
||||
if( newCmd == 0 )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_MEMORY;
|
||||
}
|
||||
|
||||
// Add it to the list of Mac commands
|
||||
if( LinkedListAdd( &NvmCtx.MacCommandList, newCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR;
|
||||
}
|
||||
|
||||
// Set Values
|
||||
newCmd->CID = cid;
|
||||
newCmd->PayloadSize = payloadSize;
|
||||
memcpy1( ( uint8_t* )newCmd->Payload, payload, payloadSize );
|
||||
newCmd->IsSticky = IsSticky( cid );
|
||||
|
||||
NvmCtx.SerializedCmdsSize += ( CID_FIELD_SIZE + payloadSize );
|
||||
|
||||
NvmCtxCallback( );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd )
|
||||
{
|
||||
if( macCmd == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
|
||||
// Remove the Mac command element from MacCommandList
|
||||
if( LinkedListRemove( &NvmCtx.MacCommandList, macCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
|
||||
}
|
||||
|
||||
NvmCtx.SerializedCmdsSize -= ( CID_FIELD_SIZE + macCmd->PayloadSize );
|
||||
|
||||
// Free the MacCommand Slot
|
||||
if( FreeMacCommandSlot( macCmd ) == false )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR;
|
||||
}
|
||||
|
||||
NvmCtxCallback( );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd )
|
||||
{
|
||||
MacCommand_t* curElement;
|
||||
|
||||
// Start at the head of the list
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
// Loop through all elements until we find the element with the given CID
|
||||
while( ( curElement != NULL ) && ( curElement->CID != cid ) )
|
||||
{
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
|
||||
// Update the pointer anyway
|
||||
*macCmd = curElement;
|
||||
|
||||
// Handle error in case if we reached the end without finding it.
|
||||
if( curElement == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND;
|
||||
}
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void )
|
||||
{
|
||||
MacCommand_t* curElement;
|
||||
MacCommand_t* nexElement;
|
||||
|
||||
// Start at the head of the list
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement != NULL )
|
||||
{
|
||||
if( curElement->IsSticky == false )
|
||||
{
|
||||
nexElement = curElement->Next;
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
curElement = nexElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
}
|
||||
|
||||
NvmCtxCallback( );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void )
|
||||
{
|
||||
MacCommand_t* curElement;
|
||||
MacCommand_t* nexElement;
|
||||
|
||||
// Start at the head of the list
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement != NULL )
|
||||
{
|
||||
nexElement = curElement->Next;
|
||||
if( IsSticky( curElement->CID ) == true )
|
||||
{
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
}
|
||||
curElement = nexElement;
|
||||
}
|
||||
|
||||
NvmCtxCallback( );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size )
|
||||
{
|
||||
if( size == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
*size = NvmCtx.SerializedCmdsSize;
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer )
|
||||
{
|
||||
MacCommand_t* curElement = NvmCtx.MacCommandList.First;
|
||||
MacCommand_t* nextElement;
|
||||
uint8_t itr = 0;
|
||||
|
||||
if( ( buffer == NULL ) || ( effectiveSize == NULL ) )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
|
||||
// Loop through all elements which fits into the buffer
|
||||
while( curElement != NULL )
|
||||
{
|
||||
// If the next MAC command still fits into the buffer, add it.
|
||||
if( ( availableSize - itr ) >= ( CID_FIELD_SIZE + curElement->PayloadSize ) )
|
||||
{
|
||||
buffer[itr++] = curElement->CID;
|
||||
memcpy1( &buffer[itr], curElement->Payload, curElement->PayloadSize );
|
||||
itr += curElement->PayloadSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
|
||||
// Remove all commands which do not fit into the buffer
|
||||
while( curElement != NULL )
|
||||
{
|
||||
// Store the next element before removing the current one
|
||||
nextElement = curElement->Next;
|
||||
LoRaMacCommandsRemoveCmd( curElement );
|
||||
curElement = nextElement;
|
||||
}
|
||||
|
||||
// Fetch the effective size of the mac commands
|
||||
LoRaMacCommandsGetSizeSerializedCmds( effectiveSize );
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending )
|
||||
{
|
||||
if( cmdsPending == NULL )
|
||||
{
|
||||
return LORAMAC_COMMANDS_ERROR_NPE;
|
||||
}
|
||||
MacCommand_t* curElement;
|
||||
curElement = NvmCtx.MacCommandList.First;
|
||||
|
||||
*cmdsPending = false;
|
||||
|
||||
// Loop through all elements
|
||||
while( curElement != NULL )
|
||||
{
|
||||
if( curElement->IsSticky == true )
|
||||
{
|
||||
// Found one sticky MAC command
|
||||
*cmdsPending = true;
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
curElement = curElement->Next;
|
||||
}
|
||||
|
||||
return LORAMAC_COMMANDS_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/*!
|
||||
* \file LoRaMacCommands.h
|
||||
*
|
||||
* \brief LoRa MAC commands
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_COMMANDS_H__
|
||||
#define __LORAMAC_COMMANDS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "LoRaMacTypes.h"
|
||||
|
||||
|
||||
/*
|
||||
* Number of MAC Command slots
|
||||
*/
|
||||
#define LORAMAC_COMMADS_MAX_NUM_OF_PARAMS 2
|
||||
|
||||
/*!
|
||||
* LoRaWAN MAC Command element
|
||||
*/
|
||||
typedef struct sMacCommand MacCommand_t;
|
||||
|
||||
struct sMacCommand
|
||||
{
|
||||
/*!
|
||||
* The pointer to the next MAC Command element in the list
|
||||
*/
|
||||
MacCommand_t* Next;
|
||||
/*!
|
||||
* MAC command identifier
|
||||
*/
|
||||
uint8_t CID;
|
||||
/*!
|
||||
* MAC command payload
|
||||
*/
|
||||
uint8_t Payload[LORAMAC_COMMADS_MAX_NUM_OF_PARAMS];
|
||||
/*!
|
||||
* Size of MAC command payload
|
||||
*/
|
||||
size_t PayloadSize;
|
||||
/*!
|
||||
* Indicates if it's a sticky MAC command
|
||||
*/
|
||||
bool IsSticky;
|
||||
};
|
||||
|
||||
/*!
|
||||
* LoRaMac Commands Status
|
||||
*/
|
||||
typedef enum eLoRaMacCommandsStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_COMMANDS_SUCCESS = 0,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_COMMANDS_ERROR_NPE,
|
||||
/*!
|
||||
* There is no memory left to add a further MAC command
|
||||
*/
|
||||
LORAMAC_COMMANDS_ERROR_MEMORY,
|
||||
/*!
|
||||
* MAC command not found.
|
||||
*/
|
||||
LORAMAC_COMMANDS_ERROR_CMD_NOT_FOUND,
|
||||
/*!
|
||||
* Unknown or corrupted command error occurred.
|
||||
*/
|
||||
LORAMAC_COMMANDS_ERROR_UNKNOWN_CMD,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_COMMANDS_ERROR,
|
||||
}LoRaMacCommandStatus_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *LoRaMacCommandsNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialization of LoRaMac MAC commands module
|
||||
*
|
||||
* \param[IN] commandsNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context needs to be saved.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsInit( LoRaMacCommandsNvmEvent commandsNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
*
|
||||
* \param[IN] commandsNvmCtx - Pointer to non-volatile MAC commands module context to be restored.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRestoreNvmCtx( void* commandsNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param[IN] commandsNvmCtxSize - Size of the module non-volatile context
|
||||
*
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacCommandsGetNvmCtx( size_t* commandsNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* \brief Adds a new MAC command to be sent.
|
||||
*
|
||||
* \param[IN] cid - MAC command identifier
|
||||
* \param[IN] payload - MAC command payload containing parameters
|
||||
* \param[IN] payloadSize - Size of MAC command payload
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsAddCmd( uint8_t cid, uint8_t* payload, size_t payloadSize );
|
||||
|
||||
/*!
|
||||
* \brief Remove a MAC command.
|
||||
*
|
||||
* \param[OUT] cmd - MAC command
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveCmd( MacCommand_t* macCmd );
|
||||
|
||||
/*!
|
||||
* \brief Get the MAC command with corresponding CID.
|
||||
*
|
||||
* \param[IN] cid - MAC command identifier
|
||||
* \param[OUT] cmd - MAC command
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsGetCmd( uint8_t cid, MacCommand_t** macCmd );
|
||||
|
||||
/*!
|
||||
* \brief Remove all none sticky MAC commands.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveNoneStickyCmds( void );
|
||||
|
||||
/*!
|
||||
* \brief Remove all sticky answer MAC commands.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsRemoveStickyAnsCmds( void );
|
||||
|
||||
/*!
|
||||
* \brief Get size of all MAC commands serialized as buffer
|
||||
*
|
||||
* \param[out] size - Available size of memory for MAC commands
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsGetSizeSerializedCmds( size_t* size );
|
||||
|
||||
/*!
|
||||
* \brief Get as many as possible MAC commands serialized
|
||||
*
|
||||
* \param[IN] availableSize - Available size of memory for MAC commands
|
||||
* \param[out] effectiveSize - Size of memory which was effectively used for serializing.
|
||||
* \param[out] buffer - Destination data buffer
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsSerializeCmds( size_t availableSize, size_t* effectiveSize, uint8_t* buffer );
|
||||
|
||||
/*!
|
||||
* \brief Determines if there are sticky MAC commands pending.
|
||||
*
|
||||
* \param[IN] cmdsPending - Indicates if there are sticky MAC commands in the queue.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCommandStatus_t LoRaMacCommandsStickyCmdsPending( bool* cmdsPending );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_COMMANDS_H__
|
||||
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC confirm queue implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "timer.h"
|
||||
#include "utilities.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "LoRaMacConfirmQueue.h"
|
||||
|
||||
|
||||
/*
|
||||
* LoRaMac Confirm Queue Context NVM structure
|
||||
*/
|
||||
typedef struct sLoRaMacConfirmQueueNvmCtx
|
||||
{
|
||||
/*!
|
||||
* MlmeConfirm queue data structure
|
||||
*/
|
||||
MlmeConfirmQueue_t MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN];
|
||||
/*!
|
||||
* Counts the number of MlmeConfirms to process
|
||||
*/
|
||||
uint8_t MlmeConfirmQueueCnt;
|
||||
/*!
|
||||
* Variable which holds a common status
|
||||
*/
|
||||
LoRaMacEventInfoStatus_t CommonStatus;
|
||||
} LoRaMacConfirmQueueNvmCtx_t;
|
||||
|
||||
/*
|
||||
* LoRaMac Confirm Queue Context structure
|
||||
*/
|
||||
typedef struct sLoRaMacConfirmQueueCtx
|
||||
{
|
||||
/*!
|
||||
* LoRaMac callback function primitives
|
||||
*/
|
||||
LoRaMacPrimitives_t* Primitives;
|
||||
/*!
|
||||
* Pointer to the first element of the ring buffer
|
||||
*/
|
||||
MlmeConfirmQueue_t* BufferStart;
|
||||
/*!
|
||||
* Pointer to the last element of the ring buffer
|
||||
*/
|
||||
MlmeConfirmQueue_t* BufferEnd;
|
||||
/*
|
||||
* Callback function to notify the upper layer about context change
|
||||
*/
|
||||
LoRaMacConfirmQueueNvmEvent LoRaMacConfirmQueueNvmEvent;
|
||||
/*!
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
LoRaMacConfirmQueueNvmCtx_t* ConfirmQueueNvmCtx;
|
||||
} LoRaMacConfirmQueueCtx_t;
|
||||
|
||||
/*
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static LoRaMacConfirmQueueNvmCtx_t ConfirmQueueNvmCtx;
|
||||
|
||||
/*
|
||||
* Module context.
|
||||
*/
|
||||
static LoRaMacConfirmQueueCtx_t ConfirmQueueCtx;
|
||||
|
||||
static MlmeConfirmQueue_t* IncreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer )
|
||||
{
|
||||
if( bufferPointer == &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1] )
|
||||
{
|
||||
// Reset to the first element
|
||||
bufferPointer = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Increase
|
||||
bufferPointer++;
|
||||
}
|
||||
return bufferPointer;
|
||||
}
|
||||
|
||||
static MlmeConfirmQueue_t* DecreaseBufferPointer( MlmeConfirmQueue_t* bufferPointer )
|
||||
{
|
||||
if( bufferPointer == ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue )
|
||||
{
|
||||
// Reset to the last element
|
||||
bufferPointer = &ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue[LORA_MAC_MLME_CONFIRM_QUEUE_LEN - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferPointer--;
|
||||
}
|
||||
return bufferPointer;
|
||||
}
|
||||
|
||||
static MlmeConfirmQueue_t* GetElement( Mlme_t request, MlmeConfirmQueue_t* bufferStart, MlmeConfirmQueue_t* bufferEnd )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = bufferStart;
|
||||
|
||||
while( element != bufferEnd )
|
||||
{
|
||||
if( element->Request == request )
|
||||
{
|
||||
// We have found the element
|
||||
return element;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = IncreaseBufferPointer( element );
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged )
|
||||
{
|
||||
ConfirmQueueCtx.Primitives = primitives;
|
||||
|
||||
// Assign nvm context
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx = &ConfirmQueueNvmCtx;
|
||||
|
||||
// Init counter
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt = 0;
|
||||
|
||||
// Init buffer
|
||||
ConfirmQueueCtx.BufferStart = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue;
|
||||
ConfirmQueueCtx.BufferEnd = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue;
|
||||
|
||||
memset1( ( uint8_t* )ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue, 0xFF, sizeof( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueue ) );
|
||||
|
||||
// Common status
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
|
||||
// Assign callback
|
||||
ConfirmQueueCtx.LoRaMacConfirmQueueNvmEvent = confirmQueueNvmCtxChanged;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx )
|
||||
{
|
||||
// Restore module context
|
||||
if( confirmQueueNvmCtx != NULL )
|
||||
{
|
||||
memcpy1( ( uint8_t* )&ConfirmQueueNvmCtx, ( uint8_t* ) confirmQueueNvmCtx, sizeof( ConfirmQueueNvmCtx ) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize )
|
||||
{
|
||||
*confirmQueueNvmCtxSize = sizeof( ConfirmQueueNvmCtx );
|
||||
return &ConfirmQueueNvmCtx;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
|
||||
{
|
||||
// Protect the buffer against overwrites
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the element to the ring buffer
|
||||
ConfirmQueueCtx.BufferEnd->Request = mlmeConfirm->Request;
|
||||
ConfirmQueueCtx.BufferEnd->Status = mlmeConfirm->Status;
|
||||
ConfirmQueueCtx.BufferEnd->RestrictCommonReadyToHandle = mlmeConfirm->RestrictCommonReadyToHandle;
|
||||
ConfirmQueueCtx.BufferEnd->ReadyToHandle = false;
|
||||
// Increase counter
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt++;
|
||||
// Update end pointer
|
||||
ConfirmQueueCtx.BufferEnd = IncreaseBufferPointer( ConfirmQueueCtx.BufferEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueRemoveLast( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Increase counter
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--;
|
||||
// Update start pointer
|
||||
ConfirmQueueCtx.BufferEnd = DecreaseBufferPointer( ConfirmQueueCtx.BufferEnd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueRemoveFirst( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Increase counter
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt--;
|
||||
// Update start pointer
|
||||
ConfirmQueueCtx.BufferStart = IncreaseBufferPointer( ConfirmQueueCtx.BufferStart );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t request )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = NULL;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
{
|
||||
element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd );
|
||||
if( element != NULL )
|
||||
{
|
||||
element->Status = status;
|
||||
element->ReadyToHandle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = NULL;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
{
|
||||
element = GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd );
|
||||
if( element != NULL )
|
||||
{
|
||||
return element->Status;
|
||||
}
|
||||
}
|
||||
return LORAMAC_EVENT_INFO_STATUS_ERROR;
|
||||
}
|
||||
|
||||
void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status )
|
||||
{
|
||||
MlmeConfirmQueue_t* element = ConfirmQueueCtx.BufferStart;
|
||||
|
||||
ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus = status;
|
||||
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt > 0 )
|
||||
{
|
||||
do
|
||||
{
|
||||
element->Status = status;
|
||||
// Set the status if it is allowed to set it with a call to
|
||||
// LoRaMacConfirmQueueSetStatusCmn.
|
||||
if( element->RestrictCommonReadyToHandle == false )
|
||||
{
|
||||
element->ReadyToHandle = true;
|
||||
}
|
||||
element = IncreaseBufferPointer( element );
|
||||
}while( element != ConfirmQueueCtx.BufferEnd );
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void )
|
||||
{
|
||||
return ConfirmQueueCtx.ConfirmQueueNvmCtx->CommonStatus;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request )
|
||||
{
|
||||
if( GetElement( request, ConfirmQueueCtx.BufferStart, ConfirmQueueCtx.BufferEnd ) != NULL )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm )
|
||||
{
|
||||
uint8_t nbElements = ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt;
|
||||
bool readyToHandle = false;
|
||||
MlmeConfirmQueue_t mlmeConfirmToStore;
|
||||
|
||||
for( uint8_t i = 0; i < nbElements; i++ )
|
||||
{
|
||||
mlmeConfirm->MlmeRequest = ConfirmQueueCtx.BufferStart->Request;
|
||||
mlmeConfirm->Status = ConfirmQueueCtx.BufferStart->Status;
|
||||
readyToHandle = ConfirmQueueCtx.BufferStart->ReadyToHandle;
|
||||
|
||||
if( readyToHandle == true )
|
||||
{
|
||||
ConfirmQueueCtx.Primitives->MacMlmeConfirm( mlmeConfirm );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The request is not processed yet. Store the state.
|
||||
mlmeConfirmToStore.Request = ConfirmQueueCtx.BufferStart->Request;
|
||||
mlmeConfirmToStore.Status = ConfirmQueueCtx.BufferStart->Status;
|
||||
mlmeConfirmToStore.RestrictCommonReadyToHandle = ConfirmQueueCtx.BufferStart->RestrictCommonReadyToHandle;
|
||||
}
|
||||
|
||||
// Increase the pointer afterwards to prevent overwrites
|
||||
LoRaMacConfirmQueueRemoveFirst( );
|
||||
|
||||
if( readyToHandle == false )
|
||||
{
|
||||
// Add a request which has not been finished again to the queue
|
||||
LoRaMacConfirmQueueAdd( &mlmeConfirmToStore );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LoRaMacConfirmQueueGetCnt( void )
|
||||
{
|
||||
return ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt;
|
||||
}
|
||||
|
||||
bool LoRaMacConfirmQueueIsFull( void )
|
||||
{
|
||||
if( ConfirmQueueCtx.ConfirmQueueNvmCtx->MlmeConfirmQueueCnt >= LORA_MAC_MLME_CONFIRM_QUEUE_LEN )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/*!
|
||||
* \file LoRaMacConfirmQueue.h
|
||||
*
|
||||
* \brief LoRa MAC confirm queue implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMACCONFIRMQUEUE LoRa MAC confirm queue implementation
|
||||
* This module specifies the API implementation of the LoRaMAC confirm queue.
|
||||
* The confirm queue is implemented with as a ring buffer. The number of
|
||||
* elements can be defined with \ref LORA_MAC_MLME_CONFIRM_QUEUE_LEN. The
|
||||
* current implementation does not support multiple elements of the same
|
||||
* Mlme_t type.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __LORAMAC_CONFIRMQUEUE_H__
|
||||
#define __LORAMAC_CONFIRMQUEUE_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "LoRaMac.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac MLME-Confirm queue length
|
||||
*/
|
||||
#define LORA_MAC_MLME_CONFIRM_QUEUE_LEN 5
|
||||
|
||||
/*!
|
||||
* Structure to hold multiple MLME request confirm data
|
||||
*/
|
||||
typedef struct sMlmeConfirmQueue
|
||||
{
|
||||
/*!
|
||||
* Holds the previously performed MLME-Request
|
||||
*/
|
||||
Mlme_t Request;
|
||||
/*!
|
||||
* Status of the operation
|
||||
*/
|
||||
LoRaMacEventInfoStatus_t Status;
|
||||
/*!
|
||||
* Set to true, if the request is ready to be handled
|
||||
*/
|
||||
bool ReadyToHandle;
|
||||
/*!
|
||||
* Set to true, if it is not permitted to set the ReadyToHandle variable
|
||||
* with a function call to LoRaMacConfirmQueueSetStatusCmn.
|
||||
*/
|
||||
bool RestrictCommonReadyToHandle;
|
||||
}MlmeConfirmQueue_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *LoRaMacConfirmQueueNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the confirm queue
|
||||
*
|
||||
* \param [IN] primitives - Pointer to the LoRaMac primitives.
|
||||
*
|
||||
* \param [IN] confirmQueueNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context needs to be saved.
|
||||
*/
|
||||
void LoRaMacConfirmQueueInit( LoRaMacPrimitives_t* primitives, LoRaMacConfirmQueueNvmEvent confirmQueueNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
*
|
||||
* \param [IN] confirmQueueNvmCtx - Pointer to non-volatile class B module context to be restored.
|
||||
*
|
||||
* \retval [true - operation was successful, false - operation failed]
|
||||
*/
|
||||
bool LoRaMacConfirmQueueRestoreNvmCtx( void* confirmQueueNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param [IN] confirmQueueNvmCtxSize - Size of the module non-volatile context
|
||||
*
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacConfirmQueueGetNvmCtx( size_t* confirmQueueNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* \brief Adds an element to the confirm queue.
|
||||
*
|
||||
* \param [IN] mlmeConfirm - Pointer to the element to add.
|
||||
*
|
||||
* \retval [true - operation was successful, false - operation failed]
|
||||
*/
|
||||
bool LoRaMacConfirmQueueAdd( MlmeConfirmQueue_t* mlmeConfirm );
|
||||
|
||||
/*!
|
||||
* \brief Removes the last element which was added into the queue.
|
||||
*
|
||||
* \retval [true - operation was successful, false - operation failed]
|
||||
*/
|
||||
bool LoRaMacConfirmQueueRemoveLast( void );
|
||||
|
||||
/*!
|
||||
* \brief Removes the first element which was added to the confirm queue.
|
||||
*
|
||||
* \retval [true - operation was successful, false - operation failed]
|
||||
*/
|
||||
bool LoRaMacConfirmQueueRemoveFirst( void );
|
||||
|
||||
/*!
|
||||
* \brief Sets the status of an element.
|
||||
*
|
||||
* \param [IN] status - The status to set.
|
||||
*
|
||||
* \param [IN] request - The related request to set the status.
|
||||
*/
|
||||
void LoRaMacConfirmQueueSetStatus( LoRaMacEventInfoStatus_t status, Mlme_t request );
|
||||
|
||||
/*!
|
||||
* \brief Gets the status of an element.
|
||||
*
|
||||
* \param [IN] request - The request to query the status.
|
||||
*
|
||||
* \retval The status of the related MlmeRequest.
|
||||
*/
|
||||
LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatus( Mlme_t request );
|
||||
|
||||
/*!
|
||||
* \brief Sets a common status for all elements in the queue.
|
||||
*
|
||||
* \param [IN] status - The status to set.
|
||||
*/
|
||||
void LoRaMacConfirmQueueSetStatusCmn( LoRaMacEventInfoStatus_t status );
|
||||
|
||||
/*!
|
||||
* \brief Gets the common status of all elements.
|
||||
*
|
||||
* \retval The common status of all elements.
|
||||
*/
|
||||
LoRaMacEventInfoStatus_t LoRaMacConfirmQueueGetStatusCmn( void );
|
||||
|
||||
/*!
|
||||
* \brief Verifies if a request is in the queue and active.
|
||||
*
|
||||
* \param [IN] request - The request to verify.
|
||||
*
|
||||
* \retval [true - element is in the queue, false - element is not in the queue].
|
||||
*/
|
||||
bool LoRaMacConfirmQueueIsCmdActive( Mlme_t request );
|
||||
|
||||
/*!
|
||||
* \brief Handles all callbacks of active requests
|
||||
*
|
||||
* \param [IN] mlmeConfirm - Pointer to the generic mlmeConfirm structure.
|
||||
*/
|
||||
void LoRaMacConfirmQueueHandleCb( MlmeConfirm_t* mlmeConfirm );
|
||||
|
||||
/*!
|
||||
* \brief Query number of elements in the queue.
|
||||
*
|
||||
* \retval Number of elements.
|
||||
*/
|
||||
uint8_t LoRaMacConfirmQueueGetCnt( void );
|
||||
|
||||
/*!
|
||||
* \brief Verify if the confirm queue is full.
|
||||
*
|
||||
* \retval [true - queue is full, false - queue is not full].
|
||||
*/
|
||||
bool LoRaMacConfirmQueueIsFull( void );
|
||||
|
||||
#endif // __LORAMAC_CONFIRMQUEUE_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,320 @@
|
|||
/*!
|
||||
* \file LoRaMacCrypto.h
|
||||
*
|
||||
* \brief LoRa MAC layer cryptographic functionality implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_CRYPTO_H__
|
||||
#define __LORAMAC_CRYPTO_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "utilities.h"
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
/*
|
||||
* Initial value of the frame counters
|
||||
*/
|
||||
#define FCNT_DOWN_INITAL_VALUE 0xFFFFFFFF
|
||||
|
||||
/*!
|
||||
* LoRaMac Cryto Status
|
||||
*/
|
||||
typedef enum eLoRaMacCryptoStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_CRYPTO_SUCCESS = 0,
|
||||
/*!
|
||||
* MIC does not match
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_MIC,
|
||||
/*!
|
||||
* Address does not match
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_ADDRESS,
|
||||
/*!
|
||||
* JoinNonce was not greater than previous one.
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_JOIN_NONCE,
|
||||
/*!
|
||||
* RJcount0 reached 2^16-1
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW,
|
||||
/*!
|
||||
* FCNT_ID is not supported
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_ID,
|
||||
/*!
|
||||
* FCntUp/Down check failed (new FCnt is smaller than previous one)
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_SMALLER,
|
||||
/*!
|
||||
* FCntUp/Down check failed (duplicated)
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED,
|
||||
/*!
|
||||
* MAX_GAP_FCNT check failed
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_MAX_GAP_FCNT,
|
||||
/*!
|
||||
* Not allowed parameter value
|
||||
*/
|
||||
LORAMAC_CRYPTO_FAIL_PARAM,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_NPE,
|
||||
/*!
|
||||
* Invalid key identifier exception
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_INVALID_KEY_ID,
|
||||
/*!
|
||||
* Invalid address identifier exception
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_INVALID_ADDR_ID,
|
||||
/*!
|
||||
* Invalid LoRaWAN specification version
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_INVALID_VERSION,
|
||||
/*!
|
||||
* Incompatible buffer size
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_BUF_SIZE,
|
||||
/*!
|
||||
* The secure element reports an error
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC,
|
||||
/*!
|
||||
* Error from parser reported
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_PARSER,
|
||||
/*!
|
||||
* Error from serializer reported
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_SERIALIZER,
|
||||
/*!
|
||||
* RJcount1 reached 2^16-1 which should never happen
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR_RJCOUNT1_OVERFLOW,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_CRYPTO_ERROR,
|
||||
}LoRaMacCryptoStatus_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by the LoRaMac Crypto module when the
|
||||
* non-volatile context have to be stored. It is also possible to save the entire
|
||||
* crypto module context.
|
||||
*
|
||||
*/
|
||||
typedef void ( *LoRaMacCryptoNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* Initialization of LoRaMac Crypto module
|
||||
* It sets initial values of volatile variables and assigns the non-volatile context.
|
||||
*
|
||||
* \param[IN] cryptoNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context have to be stored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Sets the LoRaWAN specification version to be used.
|
||||
*
|
||||
* \warning This function should be used for ABP only. In case of OTA the version will be set automatically.
|
||||
*
|
||||
* \param[IN] version - LoRaWAN specification version to be used.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version );
|
||||
|
||||
/*!
|
||||
* Restores the internal nvm context from passed pointer.
|
||||
*
|
||||
* \param[IN] cryptoNmvCtx - Pointer to non-volatile crypto module context to be restored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param[IN] cryptoNvmCtxSize - Size of the module non-volatile context
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacCryptoGetNvmCtx( size_t* cryptoNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* Returns updated fCntID downlink counter value.
|
||||
*
|
||||
* \param[IN] fCntID - Frame counter identifier
|
||||
* \param[IN] maxFcntGap - Maximum allowed frame counter difference (only necessary for L2 LW1.0.x)
|
||||
* \param[IN] frameFcnt - Received frame counter (used to update current counter value)
|
||||
* \param[OUT] currentDown - Current downlink counter value
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_t maxFCntGap, uint32_t frameFcnt, uint32_t* currentDown );
|
||||
|
||||
/*!
|
||||
* Returns updated fCntUp uplink counter value.
|
||||
*
|
||||
* \param[IN] currentUp - Uplink counter value
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp );
|
||||
|
||||
/*!
|
||||
* Provides multicast context.
|
||||
*
|
||||
* \param[IN] multicastList - Pointer to the multicast context list
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multicastList );
|
||||
|
||||
/*!
|
||||
* Sets a key
|
||||
*
|
||||
* \param[IN] keyID - Key identifier
|
||||
* \param[IN] key - Key value (16 byte), if its a multicast key it must be encrypted with McKEKey
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoSetKey( KeyIdentifier_t keyID, uint8_t* key );
|
||||
|
||||
/*!
|
||||
* Prepares the join-request message.
|
||||
* It computes the mic and add it to the message.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Join-request message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Prepares a rejoin-request type 1 message.
|
||||
* It computes the mic and add it to the message.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Rejoin message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Prepares a rejoin-request type 0 or 2 message.
|
||||
* It computes the mic and add it to the message.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Rejoin message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinType0or2_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Handles the join-accept message.
|
||||
* It decrypts the message, verifies the MIC and if successful derives the session keys.
|
||||
*
|
||||
* \param[IN] joinReqType - Type of last join-request or rejoin which triggered the join-accept response
|
||||
* \param[IN] joinEUI - Join server EUI (8 byte)
|
||||
* \param[IN/OUT] macMsg - Join-accept message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEUI, LoRaMacMessageJoinAccept_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Secures a message (encryption + integrity).
|
||||
*
|
||||
* \param[IN] fCntUp - Uplink sequence counter
|
||||
* \param[IN] txDr - Data rate used for the transmission
|
||||
* \param[IN] txCh - Index of the channel used for the transmission
|
||||
* \param[IN/OUT] macMsg - Data message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, uint8_t txCh, LoRaMacMessageData_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Unsecures a message (decryption + integrity verification).
|
||||
*
|
||||
* \param[IN] addrID - Address identifier
|
||||
* \param[IN] address - Address
|
||||
* \param[IN] fCntID - Frame counter identifier
|
||||
* \param[IN] fCntDown - Downlink sequence counter
|
||||
* \param[IN/OUT] macMsg - Data message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, uint32_t address, FCntIdentifier_t fCntID, uint32_t fCntDown, LoRaMacMessageData_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Derives the McRootKey from the GenAppKey or AppKey.
|
||||
*
|
||||
* 1.0.x
|
||||
* McRootKey = aes128_encrypt(GenAppKey , 0x00 | pad16)
|
||||
*
|
||||
* 1.1.x
|
||||
* McRootKey = aes128_encrypt(AppKey , 0x20 | pad16)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( GenAppKey or AppKey )
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( KeyIdentifier_t keyID );
|
||||
|
||||
/*!
|
||||
* Derives the McKEKey from the McRootKey.
|
||||
*
|
||||
* McKEKey = aes128_encrypt(McRootKey , 0x00 | pad16)
|
||||
*
|
||||
* \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( McRootKey )
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID );
|
||||
|
||||
/*!
|
||||
* Derives a Multicast group key pair ( McAppSKey, McNwkSKey ) from McKey
|
||||
*
|
||||
* McAppSKey = aes128_encrypt(McKey, 0x01 | McAddr | pad16)
|
||||
* McNwkSKey = aes128_encrypt(McKey, 0x02 | McAddr | pad16)
|
||||
*
|
||||
* \param[IN] addrID - Address identifier to select the multicast group
|
||||
* \param[IN] mcAddr - Multicast group address (4 bytes)
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t addrID, uint32_t mcAddr );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_CRYPTO_H__
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/*!
|
||||
* \file LoRaMacFCntHandler.h
|
||||
*
|
||||
* \brief LoRa MAC layer frame counter handling
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_FCNT_HANDLER_H__
|
||||
#define __LORAMAC_FCNT_HANDLER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac FCnt Handler Status
|
||||
*/
|
||||
typedef enum eLoRaMacFCntHandlerStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_SUCCESS = 0,
|
||||
/*!
|
||||
* FCntUp/Down check failed
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_CHECK_FAIL,
|
||||
/*!
|
||||
* The status idicates that the node has lost MAX_FCNT_GAP or more frames
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_MAX_GAP_FAIL,
|
||||
/*!
|
||||
* Invalid frame counter identifier exception
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR_INVALID_FCNT_ID,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR_NPE,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_FCNT_HANDLER_ERROR,
|
||||
}LoRaMacFCntHandlerStatus_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by this module when the
|
||||
* non-volatile needs to be saved.
|
||||
*/
|
||||
typedef void ( *EventNvmCtxChanged )( void );
|
||||
|
||||
/*!
|
||||
* \brief Initialization of LoRaMac FCnt Handler module
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context needs to be saved.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerInit( EventNvmCtxChanged fCntHandlerNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal non-volatile context from passed pointer.
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtx - Pointer to non-volatile FCnt handler module context to be restored.
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerRestoreNvmCtx( void* fCntHandlerNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param[IN] fCntHandlerNvmCtxSize - Size of the module non-volatile context
|
||||
*
|
||||
* \retval - Points to a structure where the module store its non-volatile context
|
||||
*/
|
||||
void* LoRaMacFCntHandlerGetNvmCtx( size_t* fCntHandlerNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* Computes next 32 bit downlink counter value and determines the frame counter ID.
|
||||
*
|
||||
* \param[IN] addrID - Address identifier
|
||||
* \param[IN] fType - Frame type
|
||||
* \param[IN] macMsg - Data message object, holding the current 16 bit transmitted frame counter
|
||||
* \param[IN] lrWanVersion - LoRaWAN version
|
||||
* \param[IN] maxFCntGap - Maximum allowed frame counter difference (only for 1.0.X necessary)
|
||||
* \param[OUT] fCntID - Frame counter identifier
|
||||
* \param[OUT] currentDown - Current downlink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntDown( AddressIdentifier_t addrID, FType_t fType, LoRaMacMessageData_t* macMsg, Version_t lrWanVersion,
|
||||
uint16_t maxFCntGap, FCntIdentifier_t* fCntID, uint32_t* currentDown );
|
||||
|
||||
/*!
|
||||
* Sets the downlink counter value according to the counter ID.
|
||||
*
|
||||
* \param[IN] fCntID - Frame counter identifier
|
||||
* \param[IN] currentDown - Current downlink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntDown( FCntIdentifier_t fCntID, uint32_t currentDown );
|
||||
|
||||
/*!
|
||||
* Computes next uplink counter value.
|
||||
*
|
||||
* \param[OUT] currentUp - Current uplink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacGetFCntUp( uint32_t* currentUp );
|
||||
|
||||
/*!
|
||||
* Sets the uplink counter value according to the counter ID.
|
||||
*
|
||||
* \param[IN] currentUp - Current uplink counter value
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacSetFCntUp( uint32_t currentUp );
|
||||
|
||||
/*!
|
||||
* Resets the value of FCntUp, NFCntDown, AFCntDown and FCntDown to zero
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacResetFCnts( void );
|
||||
|
||||
/*!
|
||||
* Sets the reference to the multicast downlink counter
|
||||
*
|
||||
* \param[IN] multicastList Pointer to the multicast list
|
||||
*
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacFCntHandlerStatus_t LoRaMacFCntHandlerSetMulticastReference( MulticastCtx_t* multicastList );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_FCNT_HANDLER_H__
|
||||
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/*!
|
||||
* \file LoRaMacHeaderTypes.h
|
||||
*
|
||||
* \brief LoRa MAC layer header type definitions
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_HEADER_TYPES_H__
|
||||
#define __LORAMAC_HEADER_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*! Frame header (FHDR) maximum field size */
|
||||
#define LORAMAC_FHDR_MAX_FIELD_SIZE 22
|
||||
|
||||
/*! FHDR Device address field size */
|
||||
#define LORAMAC_FHDR_DEV_ADD_FIELD_SIZE 4
|
||||
|
||||
/*! FHDR Frame control field size */
|
||||
#define LORAMAC_FHDR_F_CTRL_FIELD_SIZE 1
|
||||
|
||||
/*! FHDR Frame control field size */
|
||||
#define LORAMAC_FHDR_F_CNT_FIELD_SIZE 2
|
||||
|
||||
/*! FOpts maximum field size */
|
||||
#define LORAMAC_FHDR_F_OPTS_MAX_FIELD_SIZE 15
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaMAC field definition of DLSettings
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 5.4
|
||||
*/
|
||||
typedef union uLoRaMacDLSettings
|
||||
{
|
||||
/*!
|
||||
* Byte-access to the bits
|
||||
*/
|
||||
uint8_t Value;
|
||||
/*!
|
||||
* Structure containing single access to header bits
|
||||
*/
|
||||
struct sDLSettingsBits
|
||||
{
|
||||
/*!
|
||||
* Data rate of a downlink using the second receive window
|
||||
*/
|
||||
uint8_t RX2DataRate : 4;
|
||||
/*!
|
||||
* Offset between up and downlink datarate of first reception slot
|
||||
*/
|
||||
uint8_t RX1DRoffset : 3;
|
||||
/*!
|
||||
* Indicates network server LoRaWAN implementation version 1.1 or later.
|
||||
*/
|
||||
uint8_t OptNeg : 1;
|
||||
}Bits;
|
||||
}LoRaMacDLSettings_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC header field definition (MHDR field)
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 4.2
|
||||
*/
|
||||
typedef union uLoRaMacHeader
|
||||
{
|
||||
/*!
|
||||
* Byte-access to the bits
|
||||
*/
|
||||
uint8_t Value;
|
||||
/*!
|
||||
* Structure containing single access to header bits
|
||||
*/
|
||||
struct sMacHeaderBits
|
||||
{
|
||||
/*!
|
||||
* Major version
|
||||
*/
|
||||
uint8_t Major : 2;
|
||||
/*!
|
||||
* RFU
|
||||
*/
|
||||
uint8_t RFU : 3;
|
||||
/*!
|
||||
* Message type
|
||||
*/
|
||||
uint8_t MType : 3;
|
||||
}Bits;
|
||||
}LoRaMacHeader_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC frame control field definition (FCtrl)
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 4.3.1
|
||||
*/
|
||||
typedef union uLoRaMacFrameCtrl
|
||||
{
|
||||
/*!
|
||||
* Byte-access to the bits
|
||||
*/
|
||||
uint8_t Value;
|
||||
/*!
|
||||
* Structure containing single access to bits
|
||||
*/
|
||||
struct sCtrlBits
|
||||
{
|
||||
/*!
|
||||
* Frame options length
|
||||
*/
|
||||
uint8_t FOptsLen : 4;
|
||||
/*!
|
||||
* Frame pending bit
|
||||
*/
|
||||
uint8_t FPending : 1;
|
||||
/*!
|
||||
* Message acknowledge bit
|
||||
*/
|
||||
uint8_t Ack : 1;
|
||||
/*!
|
||||
* ADR acknowledgment request bit
|
||||
*/
|
||||
uint8_t AdrAckReq : 1;
|
||||
/*!
|
||||
* ADR control in frame header
|
||||
*/
|
||||
uint8_t Adr : 1;
|
||||
}Bits;
|
||||
}LoRaMacFrameCtrl_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac Frame header (FHDR)
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 4.3.1
|
||||
*/
|
||||
typedef struct sLoRaMacFrameHeader
|
||||
{
|
||||
/*!
|
||||
* Device address
|
||||
*/
|
||||
uint32_t DevAddr;
|
||||
/*!
|
||||
* Frame control field
|
||||
*/
|
||||
LoRaMacFrameCtrl_t FCtrl;
|
||||
/*!
|
||||
* Frame counter
|
||||
*/
|
||||
uint16_t FCnt;
|
||||
/*!
|
||||
* FOpts field may transport MAC commands (opt. 0-15 Bytes)
|
||||
*/
|
||||
uint8_t FOpts[LORAMAC_FHDR_F_OPTS_MAX_FIELD_SIZE];
|
||||
}LoRaMacFrameHeader_t;
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_HEADER_TYPES_H__
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
/*!
|
||||
* \file LoRaMacMessageTypes.h
|
||||
*
|
||||
* \brief LoRa MAC layer message type definitions
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_MESSAGE_TYPES_H__
|
||||
#define __LORAMAC_MESSAGE_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacHeaderTypes.h"
|
||||
|
||||
|
||||
/*! MAC header field size */
|
||||
#define LORAMAC_MHDR_FIELD_SIZE 1
|
||||
|
||||
/*! Join EUI field size */
|
||||
#define LORAMAC_JOIN_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! Device EUI field size */
|
||||
#define LORAMAC_DEV_EUI_FIELD_SIZE 8
|
||||
|
||||
/*! Join-server nonce field size */
|
||||
#define LORAMAC_JOIN_NONCE_FIELD_SIZE 3
|
||||
|
||||
/*! Network ID field size */
|
||||
#define LORAMAC_NET_ID_FIELD_SIZE 3
|
||||
|
||||
/*! Port field size */
|
||||
#define LORAMAC_F_PORT_FIELD_SIZE 1
|
||||
|
||||
/*! CFList field size */
|
||||
#define LORAMAC_C_FLIST_FIELD_SIZE 16
|
||||
|
||||
/*! MIC field size */
|
||||
#define LORAMAC_MIC_FIELD_SIZE 4
|
||||
|
||||
/*! Join-request message size */
|
||||
#define LORAMAC_JOIN_REQ_MSG_SIZE 23
|
||||
|
||||
/*! ReJoin-request type 1 message size */
|
||||
#define LORAMAC_RE_JOIN_1_MSG_SIZE 24
|
||||
|
||||
/*! ReJoin-request type 0 or 2 message size */
|
||||
#define LORAMAC_RE_JOIN_0_2_MSG_SIZE 19
|
||||
|
||||
/*!
|
||||
* LoRaMac type for Join-request message
|
||||
*/
|
||||
typedef struct sLoRaMacMessageJoinRequest
|
||||
{
|
||||
/*!
|
||||
* Serialized message buffer
|
||||
*/
|
||||
uint8_t* Buffer;
|
||||
/*!
|
||||
* Size of serialized message buffer
|
||||
*/
|
||||
uint8_t BufSize;
|
||||
/*!
|
||||
* MAC header
|
||||
*/
|
||||
LoRaMacHeader_t MHDR;
|
||||
/*!
|
||||
* Join EUI
|
||||
*/
|
||||
uint8_t JoinEUI[LORAMAC_JOIN_EUI_FIELD_SIZE];
|
||||
/*!
|
||||
* Device EUI
|
||||
*/
|
||||
uint8_t DevEUI[LORAMAC_DEV_EUI_FIELD_SIZE];
|
||||
/*!
|
||||
* Device Nonce
|
||||
*/
|
||||
uint16_t DevNonce;
|
||||
/*!
|
||||
* Message integrity code (MIC)
|
||||
*/
|
||||
uint32_t MIC;
|
||||
}LoRaMacMessageJoinRequest_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac type for rejoin-request type 1 message
|
||||
*/
|
||||
typedef struct sLoRaMacMessageReJoinType1
|
||||
{
|
||||
/*!
|
||||
* Serialized message buffer
|
||||
*/
|
||||
uint8_t* Buffer;
|
||||
/*!
|
||||
* Size of serialized message buffer
|
||||
*/
|
||||
uint8_t BufSize;
|
||||
/*!
|
||||
* MAC header
|
||||
*/
|
||||
LoRaMacHeader_t MHDR;
|
||||
/*!
|
||||
* Rejoin-request type ( 1 )
|
||||
*/
|
||||
uint8_t ReJoinType;
|
||||
/*!
|
||||
* Join EUI
|
||||
*/
|
||||
uint8_t JoinEUI[LORAMAC_JOIN_EUI_FIELD_SIZE];
|
||||
/*!
|
||||
* Device EUI
|
||||
*/
|
||||
uint8_t DevEUI[LORAMAC_DEV_EUI_FIELD_SIZE];
|
||||
/*!
|
||||
* ReJoin Type 1 counter
|
||||
*/
|
||||
uint16_t RJcount1;
|
||||
/*!
|
||||
* Message integrity code (MIC)
|
||||
*/
|
||||
uint32_t MIC;
|
||||
}LoRaMacMessageReJoinType1_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac type for rejoin-request type 0 or 2 message
|
||||
*/
|
||||
typedef struct sLoRaMacMessageReJoinType0or2
|
||||
{
|
||||
/*!
|
||||
* Serialized message buffer
|
||||
*/
|
||||
uint8_t* Buffer;
|
||||
/*!
|
||||
* Size of serialized message buffer
|
||||
*/
|
||||
uint8_t BufSize;
|
||||
/*!
|
||||
* MAC header
|
||||
*/
|
||||
LoRaMacHeader_t MHDR;
|
||||
/*!
|
||||
* Rejoin-request type ( 0 or 2 )
|
||||
*/
|
||||
uint8_t ReJoinType;
|
||||
/*!
|
||||
* Network ID ( 3 bytes )
|
||||
*/
|
||||
uint8_t NetID[LORAMAC_NET_ID_FIELD_SIZE];
|
||||
/*!
|
||||
* Device EUI
|
||||
*/
|
||||
uint8_t DevEUI[LORAMAC_DEV_EUI_FIELD_SIZE];
|
||||
/*!
|
||||
* ReJoin Type 0 and 2 frame counter
|
||||
*/
|
||||
uint16_t RJcount0;
|
||||
/*!
|
||||
* Message integrity code (MIC)
|
||||
*/
|
||||
uint32_t MIC;
|
||||
}LoRaMacMessageReJoinType0or2_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac type for Join-accept message
|
||||
*/
|
||||
typedef struct sLoRaMacMessageJoinAccept
|
||||
{
|
||||
/*!
|
||||
* Serialized message buffer
|
||||
*/
|
||||
uint8_t* Buffer;
|
||||
/*!
|
||||
* Size of serialized message buffer
|
||||
*/
|
||||
uint8_t BufSize;
|
||||
/*!
|
||||
* MAC header
|
||||
*/
|
||||
LoRaMacHeader_t MHDR;
|
||||
/*!
|
||||
* Server Nonce ( 3 bytes )
|
||||
*/
|
||||
uint8_t JoinNonce[LORAMAC_JOIN_NONCE_FIELD_SIZE];
|
||||
/*!
|
||||
* Network ID ( 3 bytes )
|
||||
*/
|
||||
uint8_t NetID[LORAMAC_NET_ID_FIELD_SIZE];
|
||||
/*!
|
||||
* Device address
|
||||
*/
|
||||
uint32_t DevAddr;
|
||||
/*!
|
||||
* Device address
|
||||
*/
|
||||
LoRaMacDLSettings_t DLSettings;
|
||||
/*!
|
||||
* Delay between TX and RX
|
||||
*/
|
||||
uint8_t RxDelay;
|
||||
/*!
|
||||
* List of channel frequencies (opt.)
|
||||
*/
|
||||
uint8_t CFList[16];
|
||||
/*!
|
||||
* Message integrity code (MIC)
|
||||
*/
|
||||
uint32_t MIC;
|
||||
}LoRaMacMessageJoinAccept_t;
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaMac type for Data MAC messages
|
||||
* (Unconfirmed Data Up, Confirmed Data Up, Unconfirmed Data Down, Confirmed Data Down)
|
||||
*/
|
||||
typedef struct sLoRaMacMessageData
|
||||
{
|
||||
/*!
|
||||
* Serialized message buffer
|
||||
*/
|
||||
uint8_t* Buffer;
|
||||
/*!
|
||||
* Size of serialized message buffer
|
||||
*/
|
||||
uint8_t BufSize;
|
||||
/*!
|
||||
* MAC header
|
||||
*/
|
||||
LoRaMacHeader_t MHDR;
|
||||
/*!
|
||||
* Frame header (FHDR)
|
||||
*/
|
||||
LoRaMacFrameHeader_t FHDR;
|
||||
/*!
|
||||
* Port field (opt.)
|
||||
*/
|
||||
uint8_t FPort;
|
||||
/*!
|
||||
* Frame payload may contain MAC commands or data (opt.)
|
||||
*/
|
||||
uint8_t* FRMPayload;
|
||||
/*!
|
||||
* Size of frame payload (not included in LoRaMac messages)
|
||||
*/
|
||||
uint8_t FRMPayloadSize;
|
||||
/*!
|
||||
* Message integrity code (MIC)
|
||||
*/
|
||||
uint32_t MIC;
|
||||
}LoRaMacMessageData_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac message type enumerator
|
||||
*/
|
||||
typedef enum eLoRaMacMessageType
|
||||
{
|
||||
/*!
|
||||
* Join-request message
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_JOIN_REQUEST,
|
||||
/*!
|
||||
* Rejoin-request type 1 message
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_RE_JOIN_1,
|
||||
/*!
|
||||
* Rejoin-request type 1 message
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_RE_JOIN_0_2,
|
||||
/*!
|
||||
* Join-accept message
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_JOIN_ACCEPT,
|
||||
/*!
|
||||
* Data MAC messages
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_DATA,
|
||||
/*!
|
||||
* Undefined message type
|
||||
*/
|
||||
LORAMAC_MSG_TYPE_UNDEF,
|
||||
}LoRaMacMessageType_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac general message type
|
||||
*/
|
||||
typedef struct sLoRaMacMessage
|
||||
{
|
||||
LoRaMacMessageType_t Type;
|
||||
union uMessage
|
||||
{
|
||||
LoRaMacMessageJoinRequest_t JoinReq;
|
||||
LoRaMacMessageReJoinType1_t ReJoin1;
|
||||
LoRaMacMessageReJoinType0or2_t ReJoin0or2;
|
||||
LoRaMacMessageJoinAccept_t JoinAccept;
|
||||
LoRaMacMessageData_t Data;
|
||||
}Message;
|
||||
}LoRaMacMessage_t;
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_MESSAGE_TYPES_H__
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC layer message parser functionality implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
|
||||
Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
#include "LoRaMacParser.h"
|
||||
#include "utilities.h"
|
||||
|
||||
LoRaMacParserStatus_t LoRaMacParserJoinAccept( LoRaMacMessageJoinAccept_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_PARSER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
|
||||
|
||||
memcpy1( macMsg->JoinNonce, &macMsg->Buffer[bufItr], 3 );
|
||||
bufItr = bufItr + 3;
|
||||
|
||||
memcpy1( macMsg->NetID, &macMsg->Buffer[bufItr], 3 );
|
||||
bufItr = bufItr + 3;
|
||||
|
||||
macMsg->DevAddr = ( uint32_t ) macMsg->Buffer[bufItr++];
|
||||
macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
|
||||
macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
|
||||
macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
|
||||
|
||||
macMsg->DLSettings.Value = macMsg->Buffer[bufItr++];
|
||||
|
||||
macMsg->RxDelay = macMsg->Buffer[bufItr++];
|
||||
|
||||
if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) == LORAMAC_C_FLIST_FIELD_SIZE )
|
||||
{
|
||||
memcpy1( macMsg->CFList, &macMsg->Buffer[bufItr], LORAMAC_C_FLIST_FIELD_SIZE );
|
||||
bufItr = bufItr + LORAMAC_C_FLIST_FIELD_SIZE;
|
||||
}
|
||||
else if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) > 0 )
|
||||
{
|
||||
return LORAMAC_PARSER_FAIL;
|
||||
}
|
||||
|
||||
macMsg->MIC = ( uint32_t ) macMsg->Buffer[bufItr++];
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
|
||||
|
||||
return LORAMAC_PARSER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacParserStatus_t LoRaMacParserData( LoRaMacMessageData_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_PARSER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
|
||||
|
||||
macMsg->FHDR.DevAddr = macMsg->Buffer[bufItr++];
|
||||
macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
|
||||
macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
|
||||
macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
|
||||
|
||||
macMsg->FHDR.FCtrl.Value = macMsg->Buffer[bufItr++];
|
||||
|
||||
macMsg->FHDR.FCnt = macMsg->Buffer[bufItr++];
|
||||
macMsg->FHDR.FCnt |= macMsg->Buffer[bufItr++] << 8;
|
||||
|
||||
if( macMsg->FHDR.FCtrl.Bits.FOptsLen <= 15 )
|
||||
{
|
||||
memcpy1( macMsg->FHDR.FOpts, &macMsg->Buffer[bufItr], macMsg->FHDR.FCtrl.Bits.FOptsLen );
|
||||
bufItr = bufItr + macMsg->FHDR.FCtrl.Bits.FOptsLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LORAMAC_PARSER_FAIL;
|
||||
}
|
||||
|
||||
// Initialize anyway with zero.
|
||||
macMsg->FPort = 0;
|
||||
macMsg->FRMPayloadSize = 0;
|
||||
|
||||
if( ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE ) > 0 )
|
||||
{
|
||||
macMsg->FPort = macMsg->Buffer[bufItr++];
|
||||
|
||||
macMsg->FRMPayloadSize = ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE );
|
||||
memcpy1( macMsg->FRMPayload, &macMsg->Buffer[bufItr], macMsg->FRMPayloadSize );
|
||||
bufItr = bufItr + macMsg->FRMPayloadSize;
|
||||
}
|
||||
|
||||
macMsg->MIC = ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE )];
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 1] << 8 );
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 2] << 16 );
|
||||
macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 3] << 24 );
|
||||
|
||||
return LORAMAC_PARSER_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*!
|
||||
* \file LoRaMacParser.h
|
||||
*
|
||||
* \brief LoRa MAC layer message parser functionality implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_PARSER_H__
|
||||
#define __LORAMAC_PARSER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac Parser Status
|
||||
*/
|
||||
typedef enum eLoRaMacParserStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_PARSER_SUCCESS = 0,
|
||||
/*!
|
||||
* Failure during parsing occurred
|
||||
*/
|
||||
LORAMAC_PARSER_FAIL,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_PARSER_ERROR_NPE,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_PARSER_ERROR,
|
||||
}LoRaMacParserStatus_t;
|
||||
|
||||
|
||||
/*!
|
||||
* Parse a serialized join-accept message and fills the structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Join-accept message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacParserStatus_t LoRaMacParserJoinAccept( LoRaMacMessageJoinAccept_t *macMsg );
|
||||
|
||||
/*!
|
||||
* Parse a serialized data message and fills the structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Data message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacParserStatus_t LoRaMacParserData( LoRaMacMessageData_t *macMsg );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_PARSER_H__
|
||||
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
Description: LoRa MAC layer message serializer functionality implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
|
||||
Daniel Jaeckle ( STACKFORCE ), Johannes Bruder ( STACKFORCE )
|
||||
*/
|
||||
#include "LoRaMacSerializer.h"
|
||||
#include "utilities.h"
|
||||
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerJoinRequest( LoRaMacMessageJoinRequest_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
// Check macMsg->BufSize
|
||||
if( macMsg->BufSize < LORAMAC_JOIN_REQ_MSG_SIZE )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MHDR.Value;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->JoinEUI, LORAMAC_JOIN_EUI_FIELD_SIZE );
|
||||
bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->DevEUI, LORAMAC_DEV_EUI_FIELD_SIZE );
|
||||
bufItr += LORAMAC_DEV_EUI_FIELD_SIZE;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->DevNonce & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->DevNonce >> 8 ) & 0xFF;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MIC & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 8 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 16 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 24 ) & 0xFF;
|
||||
|
||||
macMsg->BufSize = bufItr;
|
||||
|
||||
return LORAMAC_SERIALIZER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerReJoinType1( LoRaMacMessageReJoinType1_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
// Check macMsg->BufSize
|
||||
if( macMsg->BufSize < LORAMAC_RE_JOIN_1_MSG_SIZE )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MHDR.Value;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->ReJoinType;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->JoinEUI, LORAMAC_JOIN_EUI_FIELD_SIZE );
|
||||
bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->DevEUI, LORAMAC_DEV_EUI_FIELD_SIZE );
|
||||
bufItr += LORAMAC_DEV_EUI_FIELD_SIZE;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->RJcount1 & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->RJcount1 >> 8 ) & 0xFF;
|
||||
|
||||
return LORAMAC_SERIALIZER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerReJoinType0or2( LoRaMacMessageReJoinType0or2_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
// Check macMsg->BufSize
|
||||
if( macMsg->BufSize < LORAMAC_RE_JOIN_0_2_MSG_SIZE )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MHDR.Value;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->ReJoinType;
|
||||
|
||||
memcpy1( &macMsg->Buffer[bufItr], macMsg->NetID, LORAMAC_NET_ID_FIELD_SIZE );
|
||||
bufItr += LORAMAC_NET_ID_FIELD_SIZE;
|
||||
|
||||
memcpyr( &macMsg->Buffer[bufItr], macMsg->DevEUI, LORAMAC_DEV_EUI_FIELD_SIZE );
|
||||
bufItr += LORAMAC_DEV_EUI_FIELD_SIZE;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->RJcount0 & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->RJcount0 >> 8 ) & 0xFF;
|
||||
|
||||
return LORAMAC_SERIALIZER_SUCCESS;
|
||||
}
|
||||
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerData( LoRaMacMessageData_t* macMsg )
|
||||
{
|
||||
if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_NPE;
|
||||
}
|
||||
|
||||
uint16_t bufItr = 0;
|
||||
|
||||
// Check macMsg->BufSize
|
||||
uint16_t computedBufSize = LORAMAC_MHDR_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_DEV_ADD_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_F_CTRL_FIELD_SIZE
|
||||
+ LORAMAC_FHDR_F_CNT_FIELD_SIZE;
|
||||
|
||||
computedBufSize += macMsg->FHDR.FCtrl.Bits.FOptsLen;
|
||||
|
||||
if( macMsg->FRMPayloadSize > 0 )
|
||||
{
|
||||
computedBufSize += LORAMAC_F_PORT_FIELD_SIZE;
|
||||
}
|
||||
|
||||
computedBufSize += macMsg->FRMPayloadSize;
|
||||
computedBufSize += LORAMAC_MIC_FIELD_SIZE;
|
||||
|
||||
if( macMsg->BufSize < computedBufSize )
|
||||
{
|
||||
return LORAMAC_SERIALIZER_ERROR_BUF_SIZE;
|
||||
}
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MHDR.Value;
|
||||
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->FHDR.DevAddr ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->FHDR.DevAddr >> 8 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->FHDR.DevAddr >> 16 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->FHDR.DevAddr >> 24 ) & 0xFF;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->FHDR.FCtrl.Value;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->FHDR.FCnt & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->FHDR.FCnt >> 8 ) & 0xFF;
|
||||
|
||||
memcpy1( &macMsg->Buffer[bufItr], macMsg->FHDR.FOpts, macMsg->FHDR.FCtrl.Bits.FOptsLen );
|
||||
bufItr = bufItr + macMsg->FHDR.FCtrl.Bits.FOptsLen;
|
||||
|
||||
if( macMsg->FRMPayloadSize > 0 )
|
||||
{
|
||||
macMsg->Buffer[bufItr++] = macMsg->FPort;
|
||||
}
|
||||
|
||||
memcpy1( &macMsg->Buffer[bufItr], macMsg->FRMPayload, macMsg->FRMPayloadSize );
|
||||
bufItr = bufItr + macMsg->FRMPayloadSize;
|
||||
|
||||
macMsg->Buffer[bufItr++] = macMsg->MIC & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 8 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 16 ) & 0xFF;
|
||||
macMsg->Buffer[bufItr++] = ( macMsg->MIC >> 24 ) & 0xFF;
|
||||
|
||||
macMsg->BufSize = bufItr;
|
||||
|
||||
return LORAMAC_SERIALIZER_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*!
|
||||
* \file LoRaMacSerializer.h
|
||||
*
|
||||
* \brief LoRa MAC layer message serializer functionality implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_SERIALIZER_H__
|
||||
#define __LORAMAC_SERIALIZER_H__
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacMessageTypes.h"
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaMac Serializer Status
|
||||
*/
|
||||
typedef enum eLoRaMacSerializerStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
LORAMAC_SERIALIZER_SUCCESS = 0,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
LORAMAC_SERIALIZER_ERROR_NPE,
|
||||
/*!
|
||||
* Incompatible buffer size
|
||||
*/
|
||||
LORAMAC_SERIALIZER_ERROR_BUF_SIZE,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
LORAMAC_SERIALIZER_ERROR,
|
||||
}LoRaMacSerializerStatus_t;
|
||||
|
||||
/*!
|
||||
* Creates serialized MAC message of structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Join-request message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerJoinRequest( LoRaMacMessageJoinRequest_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Creates serialized MAC message of structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Join-request message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerReJoinType1( LoRaMacMessageReJoinType1_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Creates serialized MAC message of structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Join-request message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerReJoinType0or2( LoRaMacMessageReJoinType0or2_t* macMsg );
|
||||
|
||||
/*!
|
||||
* Creates serialized MAC message of structured object.
|
||||
*
|
||||
* \param[IN/OUT] macMsg - Data message object
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
LoRaMacSerializerStatus_t LoRaMacSerializerData( LoRaMacMessageData_t* macMsg );
|
||||
|
||||
/*! \} addtogroup LORAMAC */
|
||||
|
||||
#endif // __LORAMAC_SERIALIZER_H__
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*!
|
||||
* \file LoRaMacTest.h
|
||||
*
|
||||
* \brief LoRa MAC layer test function implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup LORAMACTEST LoRa MAC layer test function implementation
|
||||
* This module specifies the API implementation of test function of the LoRaMAC layer.
|
||||
* The functions in this file are only for testing purposes only.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __LORAMACTEST_H__
|
||||
#define __LORAMACTEST_H__
|
||||
|
||||
/*!
|
||||
* \brief Enabled or disables the duty cycle
|
||||
*
|
||||
* \details This is a test function. It shall be used for testing purposes only.
|
||||
* Changing this attribute may lead to a non-conformance LoRaMac operation.
|
||||
*
|
||||
* \param [IN] enable - Enabled or disables the duty cycle
|
||||
*/
|
||||
void LoRaMacTestSetDutyCycleOn( bool enable );
|
||||
|
||||
/*! \} defgroup LORAMACTEST */
|
||||
|
||||
#endif // __LORAMACTEST_H__
|
||||
|
|
@ -0,0 +1,655 @@
|
|||
/*!
|
||||
* \file LoRaMacTypes.h
|
||||
*
|
||||
* \brief LoRa MAC layer internal types definition. Please do not include in application sources.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* addtogroup LORAMAC
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __LORAMAC_TYPES_H__
|
||||
#define __LORAMAC_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "timer.h"
|
||||
|
||||
/*!
|
||||
* Start value for unicast keys enumeration
|
||||
*/
|
||||
#define LORAMAC_CRYPTO_UNICAST_KEYS 0
|
||||
|
||||
/*!
|
||||
* Start value for multicast keys enumeration
|
||||
*/
|
||||
#define LORAMAC_CRYPTO_MULTICAST_KEYS 127
|
||||
|
||||
typedef union Version_u
|
||||
{
|
||||
struct Version_s
|
||||
{
|
||||
uint8_t Rfu;
|
||||
uint8_t Revision;
|
||||
uint8_t Minor;
|
||||
uint8_t Major;
|
||||
}Fields;
|
||||
uint32_t Value;
|
||||
}Version_t;
|
||||
|
||||
/*!
|
||||
* LoRaWAN devices classes definition
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 2.1
|
||||
*/
|
||||
typedef enum DeviceClass_e
|
||||
{
|
||||
/*!
|
||||
* LoRaWAN device class A
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 3
|
||||
*/
|
||||
CLASS_A = 0x00,
|
||||
/*!
|
||||
* LoRaWAN device class B
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 8
|
||||
*/
|
||||
CLASS_B = 0x01,
|
||||
/*!
|
||||
* LoRaWAN device class C
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 17
|
||||
*/
|
||||
CLASS_C = 0x02,
|
||||
}DeviceClass_t;
|
||||
|
||||
/*!
|
||||
* LoRaWAN Frame type enumeration to differ between the possible data up/down frame configurations.
|
||||
*
|
||||
* Note: The naming is implementation specific since there is no definition
|
||||
* in the LoRaWAN specification included.
|
||||
*/
|
||||
typedef enum eFType
|
||||
{
|
||||
/*!
|
||||
* Frame type A
|
||||
*
|
||||
* FOptsLen > 0, Fopt present, FPort > 0, FRMPayload present
|
||||
*/
|
||||
FRAME_TYPE_A,
|
||||
/*!
|
||||
* Frame type B
|
||||
*
|
||||
* FOptsLen > 0, Fopt present, FPort not present, FRMPayload not present
|
||||
*/
|
||||
FRAME_TYPE_B,
|
||||
/*!
|
||||
* Frame type C
|
||||
*
|
||||
* FOptsLen = 0, Fopt not present, FPort = 0 , FRMPayload containing MAC commands
|
||||
*/
|
||||
FRAME_TYPE_C,
|
||||
/*!
|
||||
* Frame type D
|
||||
*
|
||||
* FOptsLen = 0, Fopt not present, FPort > 0 , FRMPayload present
|
||||
*/
|
||||
FRAME_TYPE_D,
|
||||
}FType_t;
|
||||
|
||||
/*!
|
||||
* LoRaWAN Frame counter identifier.
|
||||
*/
|
||||
typedef enum eFCntIdentifier
|
||||
{
|
||||
/*!
|
||||
* Uplink frame counter which is incremented with each uplink.
|
||||
*/
|
||||
FCNT_UP = 0,
|
||||
/*!
|
||||
* Network downlink frame counter which is incremented with each downlink on FPort 0
|
||||
* or when the FPort field is missing.
|
||||
*/
|
||||
N_FCNT_DOWN,
|
||||
/*!
|
||||
* Application downlink frame counter which is incremented with each downlink
|
||||
* on a port different than 0.
|
||||
*/
|
||||
A_FCNT_DOWN,
|
||||
/*!
|
||||
* In case if the device is connected to a LoRaWAN 1.0 Server,
|
||||
* this counter is used for every kind of downlink frame.
|
||||
*/
|
||||
FCNT_DOWN,
|
||||
/*!
|
||||
* Multicast downlink counter for index 0
|
||||
*/
|
||||
MC_FCNT_DOWN_0,
|
||||
/*!
|
||||
* Multicast downlink counter for index 1
|
||||
*/
|
||||
MC_FCNT_DOWN_1,
|
||||
/*!
|
||||
* Multicast downlink counter for index 2
|
||||
*/
|
||||
MC_FCNT_DOWN_2,
|
||||
/*!
|
||||
* Multicast downlink counter for index 3
|
||||
*/
|
||||
MC_FCNT_DOWN_3,
|
||||
}FCntIdentifier_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac Key identifier
|
||||
*/
|
||||
typedef enum eKeyIdentifier
|
||||
{
|
||||
/*!
|
||||
* Application root key
|
||||
*/
|
||||
APP_KEY = 0,
|
||||
/*!
|
||||
* Application root key
|
||||
* Used to derive McRootKey for 1.0.x devices
|
||||
*/
|
||||
GEN_APP_KEY,
|
||||
/*!
|
||||
* Network root key
|
||||
*/
|
||||
NWK_KEY,
|
||||
/*!
|
||||
* Join session integrity key
|
||||
*/
|
||||
J_S_INT_KEY,
|
||||
/*!
|
||||
* Join session encryption key
|
||||
*/
|
||||
J_S_ENC_KEY,
|
||||
/*!
|
||||
* Forwarding Network session integrity key
|
||||
*/
|
||||
F_NWK_S_INT_KEY,
|
||||
/*!
|
||||
* Serving Network session integrity key
|
||||
*/
|
||||
S_NWK_S_INT_KEY,
|
||||
/*!
|
||||
* Network session encryption key
|
||||
*/
|
||||
NWK_S_ENC_KEY,
|
||||
/*!
|
||||
* Application session key
|
||||
*/
|
||||
APP_S_KEY,
|
||||
/*!
|
||||
* Multicast root key
|
||||
*/
|
||||
MC_ROOT_KEY,
|
||||
/*!
|
||||
* Multicast key encryption key
|
||||
*/
|
||||
MC_KE_KEY = LORAMAC_CRYPTO_MULTICAST_KEYS,
|
||||
/*!
|
||||
* Multicast root key index 0
|
||||
*/
|
||||
MC_KEY_0,
|
||||
/*!
|
||||
* Multicast Application session key index 0
|
||||
*/
|
||||
MC_APP_S_KEY_0,
|
||||
/*!
|
||||
* Multicast Network session key index 0
|
||||
*/
|
||||
MC_NWK_S_KEY_0,
|
||||
/*!
|
||||
* Multicast root key index 1
|
||||
*/
|
||||
MC_KEY_1,
|
||||
/*!
|
||||
* Multicast Application session key index 1
|
||||
*/
|
||||
MC_APP_S_KEY_1,
|
||||
/*!
|
||||
* Multicast Network session key index 1
|
||||
*/
|
||||
MC_NWK_S_KEY_1,
|
||||
/*!
|
||||
* Multicast root key index 2
|
||||
*/
|
||||
MC_KEY_2,
|
||||
/*!
|
||||
* Multicast Application session key index 2
|
||||
*/
|
||||
MC_APP_S_KEY_2,
|
||||
/*!
|
||||
* Multicast Network session key index 2
|
||||
*/
|
||||
MC_NWK_S_KEY_2,
|
||||
/*!
|
||||
* Multicast root key index 3
|
||||
*/
|
||||
MC_KEY_3,
|
||||
/*!
|
||||
* Multicast Application session key index 3
|
||||
*/
|
||||
MC_APP_S_KEY_3,
|
||||
/*!
|
||||
* Multicast Network session key index 3
|
||||
*/
|
||||
MC_NWK_S_KEY_3,
|
||||
/*!
|
||||
* Zero key for slot randomization in class B
|
||||
*/
|
||||
SLOT_RAND_ZERO_KEY,
|
||||
/*!
|
||||
* No Key
|
||||
*/
|
||||
NO_KEY,
|
||||
}KeyIdentifier_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac Crypto address identifier
|
||||
*/
|
||||
typedef enum eAddressIdentifier
|
||||
{
|
||||
/*!
|
||||
* Multicast Address for index 0
|
||||
*/
|
||||
MULTICAST_0_ADDR = 0,
|
||||
/*!
|
||||
* Multicast Address for index 1
|
||||
*/
|
||||
MULTICAST_1_ADDR = 1,
|
||||
/*!
|
||||
* Multicast Address for index 2
|
||||
*/
|
||||
MULTICAST_2_ADDR = 2,
|
||||
/*!
|
||||
* Multicast Address for index 3
|
||||
*/
|
||||
MULTICAST_3_ADDR = 3,
|
||||
/*!
|
||||
* Unicast End-device address
|
||||
*/
|
||||
UNICAST_DEV_ADDR = 4,
|
||||
}AddressIdentifier_t;
|
||||
|
||||
/*
|
||||
* Multicast Rx window parameters
|
||||
*/
|
||||
typedef union uMcRxParams
|
||||
{
|
||||
struct
|
||||
{
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* This parameter is necessary for class B operation. It defines the
|
||||
* periodicity of the multicast downlink slots
|
||||
*/
|
||||
uint16_t Periodicity;
|
||||
}ClassB;
|
||||
struct
|
||||
{
|
||||
/*!
|
||||
* Reception frequency of the ping slot windows
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* Datarate of the ping slot
|
||||
*/
|
||||
int8_t Datarate;
|
||||
}ClassC;
|
||||
}McRxParams_t;
|
||||
|
||||
/*!
|
||||
* Multicast channel
|
||||
*/
|
||||
typedef struct sMcChannelParams
|
||||
{
|
||||
/*!
|
||||
* Multicats channel LoRaWAN class B or C
|
||||
*/
|
||||
DeviceClass_t Class;
|
||||
/*!
|
||||
* True if the entry is active
|
||||
*/
|
||||
bool IsEnabled;
|
||||
/*
|
||||
* Address identifier
|
||||
*/
|
||||
AddressIdentifier_t GroupID;
|
||||
/*!
|
||||
* Address
|
||||
*/
|
||||
uint32_t Address;
|
||||
/*!
|
||||
* Encrypted multicast key
|
||||
*/
|
||||
uint8_t *McKeyE;
|
||||
/*!
|
||||
* Minimum multicast frame counter value
|
||||
*/
|
||||
uint32_t FCountMin;
|
||||
/*!
|
||||
* Maximum multicast frame counter value
|
||||
*/
|
||||
uint32_t FCountMax;
|
||||
/*!
|
||||
* Multicast reception parameters
|
||||
*/
|
||||
McRxParams_t RxParams;
|
||||
}McChannelParams_t;
|
||||
|
||||
/*!
|
||||
* Multicast context
|
||||
*/
|
||||
typedef struct sMulticastCtx
|
||||
{
|
||||
/*!
|
||||
* Multicast channel parameters
|
||||
*/
|
||||
McChannelParams_t ChannelParams;
|
||||
/*!
|
||||
* Downlink counter
|
||||
*/
|
||||
uint32_t* DownLinkCounter;
|
||||
/*
|
||||
* Following parameters are only used for ClassB multicast channels
|
||||
*/
|
||||
/*!
|
||||
* Number of multicast slots. The variable can be
|
||||
* calculated as follows:
|
||||
* PingNb = 128 / ( 1 << periodicity ), where
|
||||
* 0 <= periodicity <= 7
|
||||
*/
|
||||
uint8_t PingNb;
|
||||
/*!
|
||||
* Period of the multicast slots. The variable can be
|
||||
* calculated as follows:
|
||||
* PingPeriod = 4096 / PingNb
|
||||
*/
|
||||
uint16_t PingPeriod;
|
||||
/*!
|
||||
* Ping offset of the multicast channel for Class B
|
||||
*/
|
||||
uint16_t PingOffset;
|
||||
}MulticastCtx_t;
|
||||
|
||||
/*!
|
||||
* LoRaMac join-request / rejoin type identifier
|
||||
*/
|
||||
typedef enum eJoinReqIdentifier
|
||||
{
|
||||
/*!
|
||||
* Rejoin type 0
|
||||
*/
|
||||
REJOIN_REQ_0 = 0x00,
|
||||
/*!
|
||||
* Rejoin type 1
|
||||
*/
|
||||
REJOIN_REQ_1 = 0x01,
|
||||
/*!
|
||||
* Rejoin type 2
|
||||
*/
|
||||
REJOIN_REQ_2 = 0x02,
|
||||
/*!
|
||||
* Join-request
|
||||
*/
|
||||
JOIN_REQ = 0xFF,
|
||||
}JoinReqIdentifier_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC mote MAC commands
|
||||
*
|
||||
* LoRaWAN Specification V1.1.0, chapter 5, table 4
|
||||
*/
|
||||
typedef enum eLoRaMacMoteCmd
|
||||
{
|
||||
/*!
|
||||
* LinkCheckReq
|
||||
*/
|
||||
MOTE_MAC_LINK_CHECK_REQ = 0x02,
|
||||
/*!
|
||||
* LinkADRAns
|
||||
*/
|
||||
MOTE_MAC_LINK_ADR_ANS = 0x03,
|
||||
/*!
|
||||
* DutyCycleAns
|
||||
*/
|
||||
MOTE_MAC_DUTY_CYCLE_ANS = 0x04,
|
||||
/*!
|
||||
* RXParamSetupAns
|
||||
*/
|
||||
MOTE_MAC_RX_PARAM_SETUP_ANS = 0x05,
|
||||
/*!
|
||||
* DevStatusAns
|
||||
*/
|
||||
MOTE_MAC_DEV_STATUS_ANS = 0x06,
|
||||
/*!
|
||||
* NewChannelAns
|
||||
*/
|
||||
MOTE_MAC_NEW_CHANNEL_ANS = 0x07,
|
||||
/*!
|
||||
* RXTimingSetupAns
|
||||
*/
|
||||
MOTE_MAC_RX_TIMING_SETUP_ANS = 0x08,
|
||||
/*!
|
||||
* TXParamSetupAns
|
||||
*/
|
||||
MOTE_MAC_TX_PARAM_SETUP_ANS = 0x09,
|
||||
/*!
|
||||
* DlChannelAns
|
||||
*/
|
||||
MOTE_MAC_DL_CHANNEL_ANS = 0x0A,
|
||||
/*!
|
||||
* DeviceTimeReq
|
||||
*/
|
||||
MOTE_MAC_DEVICE_TIME_REQ = 0x0D,
|
||||
/*!
|
||||
* PingSlotInfoReq
|
||||
*/
|
||||
MOTE_MAC_PING_SLOT_INFO_REQ = 0x10,
|
||||
/*!
|
||||
* PingSlotFreqAns
|
||||
*/
|
||||
MOTE_MAC_PING_SLOT_FREQ_ANS = 0x11,
|
||||
/*!
|
||||
* BeaconTimingReq
|
||||
*/
|
||||
MOTE_MAC_BEACON_TIMING_REQ = 0x12,
|
||||
/*!
|
||||
* BeaconFreqAns
|
||||
*/
|
||||
MOTE_MAC_BEACON_FREQ_ANS = 0x13,
|
||||
}LoRaMacMoteCmd_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC server MAC commands
|
||||
*
|
||||
* LoRaWAN Specification V1.1.0 chapter 5, table 4
|
||||
*/
|
||||
typedef enum eLoRaMacSrvCmd
|
||||
{
|
||||
/*!
|
||||
* ResetInd
|
||||
*/
|
||||
SRV_MAC_RESET_CONF = 0x01,
|
||||
/*!
|
||||
* LinkCheckAns
|
||||
*/
|
||||
SRV_MAC_LINK_CHECK_ANS = 0x02,
|
||||
/*!
|
||||
* LinkADRReq
|
||||
*/
|
||||
SRV_MAC_LINK_ADR_REQ = 0x03,
|
||||
/*!
|
||||
* DutyCycleReq
|
||||
*/
|
||||
SRV_MAC_DUTY_CYCLE_REQ = 0x04,
|
||||
/*!
|
||||
* RXParamSetupReq
|
||||
*/
|
||||
SRV_MAC_RX_PARAM_SETUP_REQ = 0x05,
|
||||
/*!
|
||||
* DevStatusReq
|
||||
*/
|
||||
SRV_MAC_DEV_STATUS_REQ = 0x06,
|
||||
/*!
|
||||
* NewChannelReq
|
||||
*/
|
||||
SRV_MAC_NEW_CHANNEL_REQ = 0x07,
|
||||
/*!
|
||||
* RXTimingSetupReq
|
||||
*/
|
||||
SRV_MAC_RX_TIMING_SETUP_REQ = 0x08,
|
||||
/*!
|
||||
* NewChannelReq
|
||||
*/
|
||||
SRV_MAC_TX_PARAM_SETUP_REQ = 0x09,
|
||||
/*!
|
||||
* DlChannelReq
|
||||
*/
|
||||
SRV_MAC_DL_CHANNEL_REQ = 0x0A,
|
||||
/*!
|
||||
* DeviceTimeAns
|
||||
*/
|
||||
SRV_MAC_DEVICE_TIME_ANS = 0x0D,
|
||||
/*!
|
||||
* PingSlotInfoAns
|
||||
*/
|
||||
SRV_MAC_PING_SLOT_INFO_ANS = 0x10,
|
||||
/*!
|
||||
* PingSlotChannelReq
|
||||
*/
|
||||
SRV_MAC_PING_SLOT_CHANNEL_REQ = 0x11,
|
||||
/*!
|
||||
* BeaconTimingAns
|
||||
*/
|
||||
SRV_MAC_BEACON_TIMING_ANS = 0x12,
|
||||
/*!
|
||||
* BeaconFreqReq
|
||||
*/
|
||||
SRV_MAC_BEACON_FREQ_REQ = 0x13,
|
||||
}LoRaMacSrvCmd_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC band parameters definition
|
||||
*/
|
||||
typedef struct sBand
|
||||
{
|
||||
/*!
|
||||
* Duty cycle
|
||||
*/
|
||||
uint16_t DCycle;
|
||||
/*!
|
||||
* Maximum Tx power
|
||||
*/
|
||||
int8_t TxMaxPower;
|
||||
/*!
|
||||
* Time stamp of the last JoinReq Tx frame.
|
||||
*/
|
||||
TimerTime_t LastJoinTxDoneTime;
|
||||
/*!
|
||||
* Time stamp of the last Tx frame
|
||||
*/
|
||||
TimerTime_t LastTxDoneTime;
|
||||
/*!
|
||||
* Holds the time where the device is off
|
||||
*/
|
||||
TimerTime_t TimeOff;
|
||||
}Band_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC frame types
|
||||
*
|
||||
* LoRaWAN Specification V1.0.2, chapter 4.2.1, table 1
|
||||
*/
|
||||
typedef enum eLoRaMacFrameType
|
||||
{
|
||||
/*!
|
||||
* LoRaMAC join request frame
|
||||
*/
|
||||
FRAME_TYPE_JOIN_REQ = 0x00,
|
||||
/*!
|
||||
* LoRaMAC join accept frame
|
||||
*/
|
||||
FRAME_TYPE_JOIN_ACCEPT = 0x01,
|
||||
/*!
|
||||
* LoRaMAC unconfirmed up-link frame
|
||||
*/
|
||||
FRAME_TYPE_DATA_UNCONFIRMED_UP = 0x02,
|
||||
/*!
|
||||
* LoRaMAC unconfirmed down-link frame
|
||||
*/
|
||||
FRAME_TYPE_DATA_UNCONFIRMED_DOWN = 0x03,
|
||||
/*!
|
||||
* LoRaMAC confirmed up-link frame
|
||||
*/
|
||||
FRAME_TYPE_DATA_CONFIRMED_UP = 0x04,
|
||||
/*!
|
||||
* LoRaMAC confirmed down-link frame
|
||||
*/
|
||||
FRAME_TYPE_DATA_CONFIRMED_DOWN = 0x05,
|
||||
/*!
|
||||
* LoRaMAC proprietary frame
|
||||
*/
|
||||
FRAME_TYPE_PROPRIETARY = 0x07,
|
||||
}LoRaMacFrameType_t;
|
||||
|
||||
/*!
|
||||
* LoRaMAC Battery level indicator
|
||||
*/
|
||||
typedef enum eLoRaMacBatteryLevel
|
||||
{
|
||||
/*!
|
||||
* External power source
|
||||
*/
|
||||
BAT_LEVEL_EXT_SRC = 0x00,
|
||||
/*!
|
||||
* Battery level empty
|
||||
*/
|
||||
BAT_LEVEL_EMPTY = 0x01,
|
||||
/*!
|
||||
* Battery level full
|
||||
*/
|
||||
BAT_LEVEL_FULL = 0xFE,
|
||||
/*!
|
||||
* Battery level - no measurement available
|
||||
*/
|
||||
BAT_LEVEL_NO_MEASURE = 0xFF,
|
||||
}LoRaMacBatteryLevel_t;
|
||||
|
||||
#endif // __LORAMAC_TYPES_H__
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lora_mac_version.h
|
||||
* @author MCD Application Team
|
||||
* @brief Identifies the version of loramac on github
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __LORA_MAC_VERSION_H__
|
||||
#define __LORA_MAC_VERSION_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/*the 4 MSBs define the version based on Github version */
|
||||
/*https://github.com/Lora-net/LoRaMac-node/wiki/LoRaMAC-node-Wiki*/
|
||||
/* version 4.4.2-rc.5 from develop branch */
|
||||
/*#define LORA_MAC_VERSION (uint32_t) 0x44250000*/
|
||||
#define __LORA_MAC_VERSION_MAIN (0x04U) /*!< [31:24] main version */
|
||||
#define __LORA_MAC_VERSION_SUB1 (0x04U) /*!< [23:16] sub1 version */
|
||||
#define __LORA_MAC_VERSION_SUB2 (0x02U) /*!< [15:8] sub2 version */
|
||||
#define __LORA_MAC_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __LORA_MAC_VERSION ((__LORA_MAC_VERSION_MAIN <<24)\
|
||||
|(__LORA_MAC_VERSION_SUB1 << 16)\
|
||||
|(__LORA_MAC_VERSION_SUB2 << 8 )\
|
||||
|(__LORA_MAC_VERSION_RC))
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__LORA_MAC_VERSION_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,546 @@
|
|||
/*!
|
||||
* \file RegionAS923.h
|
||||
*
|
||||
* \brief Region definition for AS923
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONAS923 Region AS923
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_AS923_H__
|
||||
#define __REGION_AS923_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define AS923_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define AS923_NUMB_DEFAULT_CHANNELS 2
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define AS923_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define AS923_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define AS923_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define AS923_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define AS923_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define AS923_DEFAULT_DATARATE DR_2
|
||||
|
||||
/*!
|
||||
* The minimum datarate which is used when the
|
||||
* dwell time is limited.
|
||||
*/
|
||||
#define AS923_DWELL_LIMIT_DATARATE DR_2
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define AS923_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define AS923_MAX_RX1_DR_OFFSET 7
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define AS923_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define AS923_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define AS923_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define AS923_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default uplink dwell time configuration
|
||||
*/
|
||||
#define AS923_DEFAULT_UPLINK_DWELL_TIME 1
|
||||
|
||||
/*!
|
||||
* Default downlink dwell time configuration
|
||||
*/
|
||||
#define AS923_DEFAULT_DOWNLINK_DWELL_TIME 1
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define AS923_DEFAULT_MAX_EIRP 16.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define AS923_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define AS923_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define AS923_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define AS923_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define AS923_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define AS923_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define AS923_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define AS923_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define AS923_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define AS923_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define AS923_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define AS923_ACK_TIMEOUT_RND 1000
|
||||
|
||||
#if ( AS923_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define AS923_RX_WND_2_FREQ 923200000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define AS923_RX_WND_2_DR DR_2
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define AS923_BEACON_CHANNEL_FREQ 923400000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define AS923_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define AS923_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define AS923_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define AS923_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define AS923_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define AS923_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define AS923_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define AS923_BAND0 { 100, AS923_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define AS923_LC1 { 923200000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define AS923_LC2 { 923400000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define AS923_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) )
|
||||
|
||||
/*!
|
||||
* RSSI threshold for a free channel [dBm]
|
||||
*/
|
||||
#define AS923_RSSI_FREE_TH -85
|
||||
|
||||
/*!
|
||||
* Specifies the time the node performs a carrier sense
|
||||
*/
|
||||
#define AS923_CARRIER_SENSE_TIME 6
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesAS923[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsAS923[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell0AS923[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks and downlinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AS923[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater.
|
||||
* The table proides repeater support. The table is only valid for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1UpAS923[] = { 0, 0, 11, 53, 125, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without repeater.
|
||||
* The table proides repeater support. The table is only valid for downlinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1DownAS923[] = { 0, 0, 11, 53, 126, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Effective datarate offsets for receive window 1.
|
||||
*/
|
||||
static const int8_t EffectiveRx1DrOffsetAS923[] = { 0, 1, 2, 3, 4, 5, -1, -2 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionAS923InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionAS923GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionAS923Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAS923ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionAS923ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionAS923ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionAS923RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionAS923TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAS923LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAS923RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAS923NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionAS923TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAS923DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionAS923AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAS923CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionAS923ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionAS923ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAS923SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionAS923ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionAS923RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONAS923 */
|
||||
|
||||
#endif // __REGION_AS923_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,540 @@
|
|||
/*!
|
||||
* \file RegionAU915.h
|
||||
*
|
||||
* \brief Region definition for AU915
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONAU915 Region AU915
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_AU915_H__
|
||||
#define __REGION_AU915_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define AU915_MAX_NB_CHANNELS 72
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define AU915_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define AU915_TX_MAX_DATARATE DR_13
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define AU915_RX_MIN_DATARATE DR_8
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define AU915_RX_MAX_DATARATE DR_13
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define AU915_DEFAULT_DATARATE DR_2
|
||||
|
||||
/*!
|
||||
* The minimum datarate which is used when the
|
||||
* dwell time is limited.
|
||||
*/
|
||||
#define AU915_DWELL_LIMIT_DATARATE DR_2
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define AU915_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define AU915_MAX_RX1_DR_OFFSET 6
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define AU915_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define AU915_MIN_TX_POWER TX_POWER_14
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define AU915_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define AU915_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default uplink dwell time configuration
|
||||
*/
|
||||
#define AU915_DEFAULT_UPLINK_DWELL_TIME 1
|
||||
|
||||
/*!
|
||||
* Default downlink dwell time configuration
|
||||
*/
|
||||
#define AU915_DEFAULT_DOWNLINK_DWELL_TIME 0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define AU915_DEFAULT_MAX_EIRP 30.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define AU915_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define AU915_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define AU915_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define AU915_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define AU915_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define AU915_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define AU915_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define AU915_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define AU915_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define AU915_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define AU915_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define AU915_ACK_TIMEOUT_RND 1000
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define AU915_RX_WND_2_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define AU915_RX_WND_2_DR DR_8
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Beacon frequency channel stepwidth
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_STEPWIDTH 600000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
#define AU915_BEACON_NB_CHANNELS 8
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define AU915_BEACON_SIZE 19
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define AU915_RFU1_SIZE 3
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define AU915_RFU2_SIZE 1
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_DR DR_10
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define AU915_BEACON_CHANNEL_BW 2
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define AU915_PING_SLOT_CHANNEL_DR DR_10
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define AU915_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band
|
||||
*/
|
||||
#define AU915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 )
|
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for US band
|
||||
*/
|
||||
#define AU915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 )
|
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1
|
||||
*/
|
||||
#define AU915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesAU915[] = { 12, 11, 10, 9, 8, 7, 8, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsAU915[] = { 125000, 125000, 125000, 125000, 125000, 125000, 500000, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Up/Down link data rates offset definition
|
||||
*/
|
||||
static const int8_t DatarateOffsetsAU915[7][6] =
|
||||
{
|
||||
{ DR_8 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_0
|
||||
{ DR_9 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_1
|
||||
{ DR_10, DR_9 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_2
|
||||
{ DR_11, DR_10, DR_9 , DR_8 , DR_8 , DR_8 }, // DR_3
|
||||
{ DR_12, DR_11, DR_10, DR_9 , DR_8 , DR_8 }, // DR_4
|
||||
{ DR_13, DR_12, DR_11, DR_10, DR_9 , DR_8 }, // DR_5
|
||||
{ DR_13, DR_13, DR_12, DR_11, DR_10, DR_9 }, // DR_6
|
||||
};
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell0AU915[] = { 51, 51, 51, 115, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 0 for uplinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AU915[] = { 51, 51, 51, 115, 222, 222, 222, 0, 33, 109, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 1 for uplinks.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 53, 129, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
* The table is valid for the dwell time configuration of 1 for uplinks. The table provides
|
||||
* repeater support.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 33, 109, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionAU915InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionAU915GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionAU915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONAU915 */
|
||||
|
||||
#endif // __REGION_AU915_H__
|
||||
|
|
@ -0,0 +1,845 @@
|
|||
/*!
|
||||
* \file RegionCN470.c
|
||||
*
|
||||
* \brief Region implementation for CN470
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*/
|
||||
#include "utilities.h"
|
||||
|
||||
#include "RegionCommon.h"
|
||||
#include "RegionCN470.h"
|
||||
#include "lorawan_conf.h"
|
||||
#include "mw_log_conf.h"
|
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6
|
||||
|
||||
/*!
|
||||
* Region specific context
|
||||
*/
|
||||
typedef struct sRegionCN470NvmCtx
|
||||
{
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[ CN470_MAX_NB_CHANNELS ];
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[ CN470_MAX_NB_BANDS ];
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
*/
|
||||
uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ];
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ];
|
||||
}RegionCN470NvmCtx_t;
|
||||
|
||||
/*
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static RegionCN470NvmCtx_t NvmCtx;
|
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr )
|
||||
{
|
||||
uint8_t nextLowerDr = 0;
|
||||
|
||||
if( dr == minDr )
|
||||
{
|
||||
nextLowerDr = minDr;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLowerDr = dr - 1;
|
||||
}
|
||||
return nextLowerDr;
|
||||
}
|
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex )
|
||||
{
|
||||
switch( BandwidthsCN470[drIndex] )
|
||||
{
|
||||
default:
|
||||
case 125000:
|
||||
return 0;
|
||||
case 250000:
|
||||
return 1;
|
||||
case 500000:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask )
|
||||
{
|
||||
int8_t txPowerResult = txPower;
|
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower );
|
||||
|
||||
return txPowerResult;
|
||||
}
|
||||
|
||||
static bool VerifyRfFreq( uint32_t freq )
|
||||
{
|
||||
// Check radio driver support
|
||||
if( Radio.CheckRfFrequency( freq ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rx frequencies
|
||||
if( ( freq < CN470_FIRST_RX1_CHANNEL ) ||
|
||||
( freq > CN470_LAST_RX1_CHANNEL ) ||
|
||||
( ( ( freq - ( uint32_t ) CN470_FIRST_RX1_CHANNEL ) % ( uint32_t ) CN470_STEPWIDTH_RX1_CHANNEL ) != 0 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test for frequency range - take RX and TX freqencies into account
|
||||
if( ( freq < 470300000 ) || ( freq > 509700000 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < CN470_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
}
|
||||
|
||||
PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
|
||||
{
|
||||
PhyParam_t phyParam = { 0 };
|
||||
|
||||
switch( getPhy->Attribute )
|
||||
{
|
||||
case PHY_MIN_RX_DR:
|
||||
{
|
||||
phyParam.Value = CN470_RX_MIN_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_MIN_TX_DR:
|
||||
{
|
||||
phyParam.Value = CN470_TX_MIN_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
phyParam.Value = CN470_DEFAULT_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_NEXT_LOWER_TX_DR:
|
||||
{
|
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, CN470_TX_MIN_DATARATE );
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_TX_POWER:
|
||||
{
|
||||
phyParam.Value = CN470_MAX_TX_POWER;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_TX_POWER:
|
||||
{
|
||||
phyParam.Value = CN470_DEFAULT_TX_POWER;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ADR_ACK_LIMIT:
|
||||
{
|
||||
phyParam.Value = CN470_ADR_ACK_LIMIT;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ADR_ACK_DELAY:
|
||||
{
|
||||
phyParam.Value = CN470_ADR_ACK_DELAY;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateCN470[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterCN470[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = CN470_DUTY_CYCLE_ENABLED;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_RX_WINDOW:
|
||||
{
|
||||
phyParam.Value = CN470_MAX_RX_WINDOW;
|
||||
break;
|
||||
}
|
||||
case PHY_RECEIVE_DELAY1:
|
||||
{
|
||||
phyParam.Value = CN470_RECEIVE_DELAY1;
|
||||
break;
|
||||
}
|
||||
case PHY_RECEIVE_DELAY2:
|
||||
{
|
||||
phyParam.Value = CN470_RECEIVE_DELAY2;
|
||||
break;
|
||||
}
|
||||
case PHY_JOIN_ACCEPT_DELAY1:
|
||||
{
|
||||
phyParam.Value = CN470_JOIN_ACCEPT_DELAY1;
|
||||
break;
|
||||
}
|
||||
case PHY_JOIN_ACCEPT_DELAY2:
|
||||
{
|
||||
phyParam.Value = CN470_JOIN_ACCEPT_DELAY2;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_FCNT_GAP:
|
||||
{
|
||||
phyParam.Value = CN470_MAX_FCNT_GAP;
|
||||
break;
|
||||
}
|
||||
case PHY_ACK_TIMEOUT:
|
||||
{
|
||||
phyParam.Value = ( CN470_ACKTIMEOUT + randr( -CN470_ACK_TIMEOUT_RND, CN470_ACK_TIMEOUT_RND ) );
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_DR1_OFFSET:
|
||||
{
|
||||
phyParam.Value = CN470_DEFAULT_RX1_DR_OFFSET;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_RX2_FREQUENCY:
|
||||
{
|
||||
phyParam.Value = CN470_RX_WND_2_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_RX2_DR:
|
||||
{
|
||||
phyParam.Value = CN470_RX_WND_2_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS_MASK:
|
||||
{
|
||||
phyParam.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_NB_CHANNELS:
|
||||
{
|
||||
phyParam.Value = CN470_MAX_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS:
|
||||
{
|
||||
phyParam.Channels = NvmCtx.Channels;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_UPLINK_DWELL_TIME:
|
||||
case PHY_DEF_DOWNLINK_DWELL_TIME:
|
||||
{
|
||||
phyParam.Value = 0;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_MAX_EIRP:
|
||||
{
|
||||
phyParam.fValue = CN470_DEFAULT_MAX_EIRP;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ANTENNA_GAIN:
|
||||
{
|
||||
phyParam.fValue = CN470_DEFAULT_ANTENNA_GAIN;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_FORMAT:
|
||||
{
|
||||
phyParam.BeaconFormat.BeaconSize = CN470_BEACON_SIZE;
|
||||
phyParam.BeaconFormat.Rfu1Size = CN470_RFU1_SIZE;
|
||||
phyParam.BeaconFormat.Rfu2Size = CN470_RFU2_SIZE;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN470_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_STEPWIDTH:
|
||||
{
|
||||
phyParam.Value = CN470_BEACON_CHANNEL_STEPWIDTH;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_NB_CHANNELS:
|
||||
{
|
||||
phyParam.Value = CN470_BEACON_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN470_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return phyParam;
|
||||
}
|
||||
|
||||
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
}
|
||||
|
||||
void RegionCN470InitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
Band_t bands[CN470_MAX_NB_BANDS] =
|
||||
{
|
||||
CN470_BAND0
|
||||
};
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470_MAX_NB_BANDS );
|
||||
|
||||
// Channels
|
||||
// 125 kHz channels
|
||||
for( uint8_t i = 0; i < CN470_MAX_NB_CHANNELS; i++ )
|
||||
{
|
||||
NvmCtx.Channels[i].Frequency = 470300000 + i * 200000;
|
||||
NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
|
||||
NvmCtx.Channels[i].Band = 0;
|
||||
}
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0xFFFF;
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_CTX:
|
||||
{
|
||||
if( params->NvmCtx != 0 )
|
||||
{
|
||||
memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_DEFAULT_CHANNELS:
|
||||
{
|
||||
// Restore channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params )
|
||||
{
|
||||
params->nvmCtxSize = sizeof( RegionCN470NvmCtx_t );
|
||||
return &NvmCtx;
|
||||
}
|
||||
|
||||
bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470_TX_MIN_DATARATE, CN470_TX_MAX_DATARATE );
|
||||
}
|
||||
case PHY_RX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE );
|
||||
}
|
||||
case PHY_DEF_TX_POWER:
|
||||
case PHY_TX_POWER:
|
||||
{
|
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, CN470_MAX_TX_POWER, CN470_MIN_TX_POWER );
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
return CN470_DUTY_CYCLE_ENABLED;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList )
|
||||
{
|
||||
// Size of the optional CF list must be 16 byte
|
||||
if( applyCFList->Size != 16 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Last byte CFListType must be 0x01 to indicate the CFList contains a series of ChMask fields
|
||||
if( applyCFList->Payload[15] != 0x01 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ChMask0 - ChMask5 must be set (every ChMask has 16 bit)
|
||||
for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 5; chMaskItr++, cntPayload+=2 )
|
||||
{
|
||||
NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]);
|
||||
NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8);
|
||||
}
|
||||
}
|
||||
|
||||
bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet )
|
||||
{
|
||||
switch( chanMaskSet->ChannelsMaskType )
|
||||
{
|
||||
case CHANNELS_MASK:
|
||||
{
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 );
|
||||
break;
|
||||
}
|
||||
case CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams )
|
||||
{
|
||||
double tSymbol = 0.0;
|
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, CN470_RX_MAX_DATARATE );
|
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate );
|
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN470[rxConfigParams->Datarate], BandwidthsCN470[rxConfigParams->Datarate] );
|
||||
|
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset );
|
||||
}
|
||||
|
||||
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
const char *slotStrings[] = { "1", "2", "C", "Multi_C", "P", "Multi_P" };
|
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( rxConfig->RxSlot == RX_SLOT_WIN_1 )
|
||||
{
|
||||
// Apply window 1 frequency
|
||||
frequency = CN470_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 48 ) * CN470_STEPWIDTH_RX1_CHANNEL;
|
||||
}
|
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesCN470[dr];
|
||||
|
||||
Radio.SetChannel( frequency );
|
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterCN470[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateCN470[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
if ( rxConfig->RxSlot < RX_SLOT_NONE )
|
||||
{
|
||||
MW_LOG( "RX_%s on freq %d Hz at DR %d\n\r", slotStrings[rxConfig->RxSlot], frequency, dr );
|
||||
}
|
||||
else
|
||||
{
|
||||
MW_LOG( "RX on freq %d Hz at DR %d\n\r", frequency, dr );
|
||||
}
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir )
|
||||
{
|
||||
int8_t phyDr = DataratesCN470[txConfig->Datarate];
|
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask );
|
||||
int8_t phyTxPower = 0;
|
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain );
|
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
MW_LOG( "TX on freq %d Hz at DR %d\n\r", NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate );
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
*txPower = txPowerLimited;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed )
|
||||
{
|
||||
uint8_t status = 0x07;
|
||||
RegionCommonLinkAdrParams_t linkAdrParams;
|
||||
uint8_t nextIndex = 0;
|
||||
uint8_t bytesProcessed = 0;
|
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
GetPhyParams_t getPhy;
|
||||
PhyParam_t phyParam;
|
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams;
|
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 );
|
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize )
|
||||
{
|
||||
// Get ADR request parameters
|
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams );
|
||||
|
||||
if( nextIndex == 0 )
|
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex;
|
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07;
|
||||
|
||||
if( linkAdrParams.ChMaskCtrl == 6 )
|
||||
{
|
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF;
|
||||
channelsMask[1] = 0xFFFF;
|
||||
channelsMask[2] = 0xFFFF;
|
||||
channelsMask[3] = 0xFFFF;
|
||||
channelsMask[4] = 0xFFFF;
|
||||
channelsMask[5] = 0xFFFF;
|
||||
}
|
||||
else if( linkAdrParams.ChMaskCtrl == 7 )
|
||||
{
|
||||
status &= 0xFE; // Channel mask KO
|
||||
}
|
||||
else
|
||||
{
|
||||
for( uint8_t i = 0; i < 16; i++ )
|
||||
{
|
||||
if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) &&
|
||||
( NvmCtx.Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) )
|
||||
{// Trying to enable an undefined channel
|
||||
status &= 0xFE; // Channel mask KO
|
||||
}
|
||||
}
|
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR;
|
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime;
|
||||
phyParam = RegionCN470GetPhyParam( &getPhy );
|
||||
|
||||
linkAdrVerifyParams.Status = status;
|
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled;
|
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate;
|
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower;
|
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep;
|
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate;
|
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower;
|
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep;
|
||||
linkAdrVerifyParams.NbChannels = CN470_MAX_NB_CHANNELS;
|
||||
linkAdrVerifyParams.ChannelsMask = channelsMask;
|
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value;
|
||||
linkAdrVerifyParams.MaxDatarate = CN470_TX_MAX_DATARATE;
|
||||
linkAdrVerifyParams.Channels = NvmCtx.Channels;
|
||||
linkAdrVerifyParams.MinTxPower = CN470_MIN_TX_POWER;
|
||||
linkAdrVerifyParams.MaxTxPower = CN470_MAX_TX_POWER;
|
||||
linkAdrVerifyParams.Version = linkAdrReq->Version;
|
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep );
|
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 )
|
||||
{
|
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 );
|
||||
}
|
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate;
|
||||
*txPowOut = linkAdrParams.TxPower;
|
||||
*nbRepOut = linkAdrParams.NbRep;
|
||||
*nbBytesParsed = bytesProcessed;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq )
|
||||
{
|
||||
uint8_t status = 0x07;
|
||||
|
||||
// Verify radio frequency
|
||||
if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false )
|
||||
{
|
||||
status &= 0xFE; // Channel frequency KO
|
||||
}
|
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, CN470_RX_MIN_DATARATE, CN470_RX_MAX_DATARATE ) == false )
|
||||
{
|
||||
status &= 0xFD; // Datarate KO
|
||||
}
|
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, CN470_MIN_RX1_DR_OFFSET, CN470_MAX_RX1_DR_OFFSET ) == false )
|
||||
{
|
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq )
|
||||
{
|
||||
// Datarate and frequency KO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
{
|
||||
return currentDr;
|
||||
}
|
||||
|
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t enabledChannels[CN470_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 6 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[4] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[5] = 0xFFFF;
|
||||
}
|
||||
|
||||
TimerTime_t elapsed = TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
if( ( nextChanParams->LastAggrTx == 0 ) || ( nextChanParams->AggrTimeOff <= elapsed ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, CN470_MAX_NB_BANDS );
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - elapsed;
|
||||
}
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
{
|
||||
return LORAMAC_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove )
|
||||
{
|
||||
return LORAMAC_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave )
|
||||
{
|
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask );
|
||||
int8_t phyTxPower = 0;
|
||||
uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency;
|
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain );
|
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout );
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset )
|
||||
{
|
||||
int8_t datarate = dr - drOffset;
|
||||
|
||||
if( datarate < 0 )
|
||||
{
|
||||
datarate = DR_0;
|
||||
}
|
||||
return datarate;
|
||||
}
|
||||
|
||||
void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr )
|
||||
{
|
||||
RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup;
|
||||
|
||||
regionCommonRxBeaconSetup.Datarates = DataratesCN470;
|
||||
regionCommonRxBeaconSetup.Frequency = rxBeaconSetup->Frequency;
|
||||
regionCommonRxBeaconSetup.BeaconSize = CN470_BEACON_SIZE;
|
||||
regionCommonRxBeaconSetup.BeaconDatarate = CN470_BEACON_CHANNEL_DR;
|
||||
regionCommonRxBeaconSetup.BeaconChannelBW = CN470_BEACON_CHANNEL_BW;
|
||||
regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime;
|
||||
regionCommonRxBeaconSetup.SymbolTimeout = rxBeaconSetup->SymbolTimeout;
|
||||
|
||||
RegionCommonRxBeaconSetup( ®ionCommonRxBeaconSetup );
|
||||
|
||||
// Store downlink datarate
|
||||
*outDr = CN470_BEACON_CHANNEL_DR;
|
||||
}
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
/*!
|
||||
* \file RegionCN470.h
|
||||
*
|
||||
* \brief Region definition for CN470
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONCN470 Region CN470
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_CN470_H__
|
||||
#define __REGION_CN470_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define CN470_MAX_NB_CHANNELS 96
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470_TX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470_RX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define CN470_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470_MAX_RX1_DR_OFFSET 3
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN470_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN470_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define CN470_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define CN470_DEFAULT_MAX_EIRP 19.15f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define CN470_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define CN470_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define CN470_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define CN470_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define CN470_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define CN470_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define CN470_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define CN470_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define CN470_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define CN470_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define CN470_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define CN470_ACK_TIMEOUT_RND 1000
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define CN470_RX_WND_2_FREQ 505300000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define CN470_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define CN470_BEACON_CHANNEL_FREQ 508300000
|
||||
|
||||
/*!
|
||||
* Beacon frequency channel stepwidth
|
||||
*/
|
||||
#define CN470_BEACON_CHANNEL_STEPWIDTH 200000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
#define CN470_BEACON_NB_CHANNELS 8
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define CN470_BEACON_SIZE 19
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define CN470_RFU1_SIZE 3
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define CN470_RFU2_SIZE 1
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define CN470_BEACON_CHANNEL_DR DR_2
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define CN470_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define CN470_PING_SLOT_CHANNEL_DR DR_2
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define CN470_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define CN470_BAND0 { 1, CN470_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for CN470 band
|
||||
*/
|
||||
#define CN470_FIRST_RX1_CHANNEL ( (uint32_t) 500300000 )
|
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for CN470 band
|
||||
*/
|
||||
#define CN470_LAST_RX1_CHANNEL ( (uint32_t) 509700000 )
|
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1
|
||||
*/
|
||||
#define CN470_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200000 )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesCN470[] = { 12, 11, 10, 9, 8, 7 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsCN470[] = { 125000, 125000, 125000, 125000, 125000, 125000 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateCN470[] = { 51, 51, 51, 115, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN470[] = { 51, 51, 51, 115, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionCN470InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionCN470GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionCN470Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionCN470ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionCN470ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN470RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN470TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionCN470TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionCN470AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN470ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionCN470ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionCN470ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionCN470RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONCN470 */
|
||||
|
||||
#endif // __REGION_CN470_H__
|
||||
|
|
@ -0,0 +1,895 @@
|
|||
/*!
|
||||
* \file RegionCN470ALIALI.c
|
||||
*
|
||||
* \brief Region implementation for CN470ALIALI
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*/
|
||||
#include "utilities.h"
|
||||
|
||||
#include "RegionCommon.h"
|
||||
#include "RegionCN470ALI.h"
|
||||
#include "lorawan_conf.h"
|
||||
#include "mw_log_conf.h"
|
||||
|
||||
// Definitions
|
||||
#define CHANNELS_MASK_SIZE 6
|
||||
|
||||
/*!
|
||||
* Region specific context
|
||||
*/
|
||||
typedef struct sRegionCN470ALINvmCtx
|
||||
{
|
||||
/*!
|
||||
* LoRaMAC channels
|
||||
*/
|
||||
ChannelParams_t Channels[ CN470ALI_MAX_NB_CHANNELS ];
|
||||
/*!
|
||||
* LoRaMac bands
|
||||
*/
|
||||
Band_t Bands[ CN470ALI_MAX_NB_BANDS ];
|
||||
/*!
|
||||
* LoRaMac channels mask
|
||||
*/
|
||||
uint16_t ChannelsMask[ CHANNELS_MASK_SIZE ];
|
||||
/*!
|
||||
* LoRaMac channels default mask
|
||||
*/
|
||||
uint16_t ChannelsDefaultMask[ CHANNELS_MASK_SIZE ];
|
||||
}RegionCN470ALINvmCtx_t;
|
||||
|
||||
/*
|
||||
* Non-volatile module context.
|
||||
*/
|
||||
static RegionCN470ALINvmCtx_t NvmCtx;
|
||||
|
||||
// Static functions
|
||||
static int8_t GetNextLowerTxDr( int8_t dr, int8_t minDr )
|
||||
{
|
||||
uint8_t nextLowerDr = 0;
|
||||
|
||||
if( dr == minDr )
|
||||
{
|
||||
nextLowerDr = minDr;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextLowerDr = dr - 1;
|
||||
}
|
||||
return nextLowerDr;
|
||||
}
|
||||
|
||||
static uint32_t GetBandwidth( uint32_t drIndex )
|
||||
{
|
||||
switch( BandwidthsCN470ALI[drIndex] )
|
||||
{
|
||||
default:
|
||||
case 125000:
|
||||
return 0;
|
||||
case 250000:
|
||||
return 1;
|
||||
case 500000:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t LimitTxPower( int8_t txPower, int8_t maxBandTxPower, int8_t datarate, uint16_t* channelsMask )
|
||||
{
|
||||
int8_t txPowerResult = txPower;
|
||||
|
||||
// Limit tx power to the band max
|
||||
txPowerResult = MAX( txPower, maxBandTxPower );
|
||||
|
||||
return txPowerResult;
|
||||
}
|
||||
|
||||
static bool VerifyRfFreq( uint32_t freq )
|
||||
{
|
||||
// Check radio driver support
|
||||
if( Radio.CheckRfFrequency( freq ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if ((ALI_DOWNLINK_FREQ == ALI_FREQ470_S) || (ALI_DOWNLINK_FREQ == ALI_FREQ480_D))
|
||||
// Rx frequencies
|
||||
if((freq < 503500000) && (freq >476500000))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Rx frequencies
|
||||
if( ( freq < CN470ALI_FIRST_RX1_CHANNEL ) ||
|
||||
( freq > CN470ALI_LAST_RX1_CHANNEL ) ||
|
||||
( ( ( freq - ( uint32_t ) CN470ALI_FIRST_RX1_CHANNEL ) % ( uint32_t ) CN470ALI_STEPWIDTH_RX1_CHANNEL ) != 0 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test for frequency range - take RX and TX freqencies into account
|
||||
if( ( freq < 470300000 ) || ( freq > 509700000 ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8_t CountNbOfEnabledChannels( uint8_t datarate, uint16_t* channelsMask, ChannelParams_t* channels, Band_t* bands, uint8_t* enabledChannels, uint8_t* delayTx )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTransmission = 0;
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < CN470ALI_MAX_NB_CHANNELS; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( channelsMask[k] & ( 1 << j ) ) != 0 )
|
||||
{
|
||||
if( channels[i + j].Frequency == 0 )
|
||||
{ // Check if the channel is enabled
|
||||
continue;
|
||||
}
|
||||
if( RegionCommonValueInRange( datarate, channels[i + j].DrRange.Fields.Min,
|
||||
channels[i + j].DrRange.Fields.Max ) == false )
|
||||
{ // Check if the current channel selection supports the given datarate
|
||||
continue;
|
||||
}
|
||||
if( bands[channels[i + j].Band].TimeOff > 0 )
|
||||
{ // Check if the band is available for transmission
|
||||
delayTransmission++;
|
||||
continue;
|
||||
}
|
||||
enabledChannels[nbEnabledChannels++] = i + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*delayTx = delayTransmission;
|
||||
return nbEnabledChannels;
|
||||
}
|
||||
|
||||
PhyParam_t RegionCN470ALIGetPhyParam( GetPhyParams_t* getPhy )
|
||||
{
|
||||
PhyParam_t phyParam = { 0 };
|
||||
|
||||
switch( getPhy->Attribute )
|
||||
{
|
||||
case PHY_MIN_RX_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_RX_MIN_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_MIN_TX_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_TX_MIN_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_DEFAULT_DATARATE;
|
||||
break;
|
||||
}
|
||||
case PHY_NEXT_LOWER_TX_DR:
|
||||
{
|
||||
/*next low speed*/
|
||||
|
||||
phyParam.Value = GetNextLowerTxDr( getPhy->Datarate, DR_0);
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_TX_POWER:
|
||||
{
|
||||
phyParam.Value = CN470ALI_MAX_TX_POWER;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_TX_POWER:
|
||||
{
|
||||
phyParam.Value = CN470ALI_DEFAULT_TX_POWER;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ADR_ACK_LIMIT:
|
||||
{
|
||||
phyParam.Value = CN470ALI_ADR_ACK_LIMIT;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ADR_ACK_DELAY:
|
||||
{
|
||||
phyParam.Value = CN470ALI_ADR_ACK_DELAY;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateCN470ALI[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_PAYLOAD_REPEATER:
|
||||
{
|
||||
phyParam.Value = MaxPayloadOfDatarateRepeaterCN470ALI[getPhy->Datarate];
|
||||
break;
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
phyParam.Value = CN470ALI_DUTY_CYCLE_ENABLED;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_RX_WINDOW:
|
||||
{
|
||||
phyParam.Value = CN470ALI_MAX_RX_WINDOW;
|
||||
break;
|
||||
}
|
||||
case PHY_RECEIVE_DELAY1:
|
||||
{
|
||||
phyParam.Value = CN470ALI_RECEIVE_DELAY1;
|
||||
break;
|
||||
}
|
||||
case PHY_RECEIVE_DELAY2:
|
||||
{
|
||||
phyParam.Value = CN470ALI_RECEIVE_DELAY2;
|
||||
break;
|
||||
}
|
||||
case PHY_JOIN_ACCEPT_DELAY1:
|
||||
{
|
||||
phyParam.Value = CN470ALI_JOIN_ACCEPT_DELAY1;
|
||||
break;
|
||||
}
|
||||
case PHY_JOIN_ACCEPT_DELAY2:
|
||||
{
|
||||
phyParam.Value = CN470ALI_JOIN_ACCEPT_DELAY2;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_FCNT_GAP:
|
||||
{
|
||||
phyParam.Value = CN470ALI_MAX_FCNT_GAP;
|
||||
break;
|
||||
}
|
||||
case PHY_ACK_TIMEOUT:
|
||||
{
|
||||
/*===============================ALI_Region==============================================*/
|
||||
phyParam.Value = ( CN470ALI_ACKTIMEOUT)+ randr( -CN470ALI_ACK_TIMEOUT_RND, CN470ALI_ACK_TIMEOUT_RND );
|
||||
/*=======================================================================================*/
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_DR1_OFFSET:
|
||||
{
|
||||
phyParam.Value = CN470ALI_DEFAULT_RX1_DR_OFFSET;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_RX2_FREQUENCY:
|
||||
{
|
||||
phyParam.Value = CN470ALI_RX_WND_2_FREQ;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_RX2_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_RX_WND_2_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS_MASK:
|
||||
{
|
||||
phyParam.ChannelsMask = NvmCtx.ChannelsMask;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
phyParam.ChannelsMask = NvmCtx.ChannelsDefaultMask;
|
||||
break;
|
||||
}
|
||||
case PHY_MAX_NB_CHANNELS:
|
||||
{
|
||||
phyParam.Value = CN470ALI_MAX_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_CHANNELS:
|
||||
{
|
||||
phyParam.Channels = NvmCtx.Channels;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_UPLINK_DWELL_TIME:
|
||||
case PHY_DEF_DOWNLINK_DWELL_TIME:
|
||||
{
|
||||
phyParam.Value = 0;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_MAX_EIRP:
|
||||
{
|
||||
phyParam.fValue = CN470ALI_DEFAULT_MAX_EIRP;
|
||||
break;
|
||||
}
|
||||
case PHY_DEF_ANTENNA_GAIN:
|
||||
{
|
||||
phyParam.fValue = CN470ALI_DEFAULT_ANTENNA_GAIN;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_FORMAT:
|
||||
{
|
||||
phyParam.BeaconFormat.BeaconSize = CN470ALI_BEACON_SIZE;
|
||||
phyParam.BeaconFormat.Rfu1Size = CN470ALI_RFU1_SIZE;
|
||||
phyParam.BeaconFormat.Rfu2Size = CN470ALI_RFU2_SIZE;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_BEACON_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_CHANNEL_STEPWIDTH:
|
||||
{
|
||||
phyParam.Value = CN470ALI_BEACON_CHANNEL_STEPWIDTH;
|
||||
break;
|
||||
}
|
||||
case PHY_BEACON_NB_CHANNELS:
|
||||
{
|
||||
phyParam.Value = CN470ALI_BEACON_NB_CHANNELS;
|
||||
break;
|
||||
}
|
||||
case PHY_PING_SLOT_CHANNEL_DR:
|
||||
{
|
||||
phyParam.Value = CN470ALI_PING_SLOT_CHANNEL_DR;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return phyParam;
|
||||
}
|
||||
|
||||
void RegionCN470ALISetBandTxDone( SetBandTxDoneParams_t* txDone )
|
||||
{
|
||||
RegionCommonSetBandTxDone( txDone->Joined, &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxDoneTime );
|
||||
}
|
||||
|
||||
void RegionCN470ALIInitDefaults( InitDefaultsParams_t* params )
|
||||
{
|
||||
Band_t bands[CN470ALI_MAX_NB_BANDS] =
|
||||
{
|
||||
CN470ALI_BAND0
|
||||
};
|
||||
|
||||
switch( params->Type )
|
||||
{
|
||||
case INIT_TYPE_INIT:
|
||||
{
|
||||
// Initialize bands
|
||||
memcpy1( ( uint8_t* )NvmCtx.Bands, ( uint8_t* )bands, sizeof( Band_t ) * CN470ALI_MAX_NB_BANDS );
|
||||
/*===============================ALI_Region==============================================*/
|
||||
|
||||
// Channels
|
||||
// 125 kHz channels
|
||||
|
||||
#if (ALI_DOWNLINK_FREQ == ALI_FREQ470_S)||(ALI_DOWNLINK_FREQ == ALI_FREQ470_D)
|
||||
|
||||
for( uint8_t i = 0; i < 32; i++ )
|
||||
{
|
||||
NvmCtx.Channels[i].Frequency = 470300000 + i * 200000;
|
||||
NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
|
||||
NvmCtx.Channels[i].Band = 0;
|
||||
}
|
||||
for( uint8_t i = 32; i < CN470ALI_MAX_NB_CHANNELS; i++ )
|
||||
{
|
||||
NvmCtx.Channels[i].Frequency = 470300000 + (i + (166-32)) * 200000;
|
||||
NvmCtx.Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
|
||||
NvmCtx.Channels[i].Band = 0;
|
||||
}
|
||||
#else
|
||||
for(i=0; i<CN470ALI_MAX_NB_CHANNELS; i++)
|
||||
{
|
||||
Channels[i].Frequency = 470300000 + (i + 68) * 200000;
|
||||
Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;
|
||||
Channels[i].Band = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Initialize the channels default mask
|
||||
NvmCtx.ChannelsDefaultMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsDefaultMask[4] = 0;
|
||||
NvmCtx.ChannelsDefaultMask[5] = 0;
|
||||
/*=======================================================================================*/
|
||||
|
||||
// Update the channels mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_CTX:
|
||||
{
|
||||
if( params->NvmCtx != 0 )
|
||||
{
|
||||
memcpy1( (uint8_t*) &NvmCtx, (uint8_t*) params->NvmCtx, sizeof( NvmCtx ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INIT_TYPE_RESTORE_DEFAULT_CHANNELS:
|
||||
{
|
||||
// Restore channels default mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, NvmCtx.ChannelsDefaultMask, 6 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* RegionCN470ALIGetNvmCtx( GetNvmCtxParams_t* params )
|
||||
{
|
||||
params->nvmCtxSize = sizeof( RegionCN470ALINvmCtx_t );
|
||||
return &NvmCtx;
|
||||
}
|
||||
|
||||
bool RegionCN470ALIVerify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||
{
|
||||
switch( phyAttribute )
|
||||
{
|
||||
case PHY_FREQUENCY:
|
||||
{
|
||||
return VerifyRfFreq( verify->Frequency );
|
||||
}
|
||||
case PHY_TX_DR:
|
||||
case PHY_DEF_TX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470ALI_TX_MIN_DATARATE, CN470ALI_TX_MAX_DATARATE );
|
||||
}
|
||||
case PHY_RX_DR:
|
||||
{
|
||||
return RegionCommonValueInRange( verify->DatarateParams.Datarate, CN470ALI_RX_MIN_DATARATE, CN470ALI_RX_MAX_DATARATE );
|
||||
}
|
||||
case PHY_DEF_TX_POWER:
|
||||
case PHY_TX_POWER:
|
||||
{
|
||||
// Remark: switched min and max!
|
||||
return RegionCommonValueInRange( verify->TxPower, CN470ALI_MAX_TX_POWER, CN470ALI_MIN_TX_POWER );
|
||||
}
|
||||
case PHY_DUTY_CYCLE:
|
||||
{
|
||||
return CN470ALI_DUTY_CYCLE_ENABLED;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void RegionCN470ALIApplyCFList( ApplyCFListParams_t* applyCFList )
|
||||
{
|
||||
// Size of the optional CF list must be 16 byte
|
||||
if( applyCFList->Size != 16 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Last byte CFListType must be 0x01 to indicate the CFList contains a series of ChMask fields
|
||||
if( applyCFList->Payload[15] != 0x01 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// ChMask0 - ChMask5 must be set (every ChMask has 16 bit)
|
||||
for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 5; chMaskItr++, cntPayload+=2 )
|
||||
{
|
||||
NvmCtx.ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]);
|
||||
NvmCtx.ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8);
|
||||
}
|
||||
}
|
||||
|
||||
bool RegionCN470ALIChanMaskSet( ChanMaskSetParams_t* chanMaskSet )
|
||||
{
|
||||
switch( chanMaskSet->ChannelsMaskType )
|
||||
{
|
||||
case CHANNELS_MASK:
|
||||
{
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, chanMaskSet->ChannelsMaskIn, 6 );
|
||||
break;
|
||||
}
|
||||
case CHANNELS_DEFAULT_MASK:
|
||||
{
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, 6 );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegionCN470ALIComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams )
|
||||
{
|
||||
double tSymbol = 0.0;
|
||||
|
||||
// Get the datarate, perform a boundary check
|
||||
rxConfigParams->Datarate = MIN( datarate, CN470ALI_RX_MAX_DATARATE );
|
||||
rxConfigParams->Bandwidth = GetBandwidth( rxConfigParams->Datarate );
|
||||
|
||||
tSymbol = RegionCommonComputeSymbolTimeLoRa( DataratesCN470ALI[rxConfigParams->Datarate], BandwidthsCN470ALI[rxConfigParams->Datarate] );
|
||||
|
||||
RegionCommonComputeRxWindowParameters( tSymbol, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset );
|
||||
}
|
||||
|
||||
bool RegionCN470ALIRxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
|
||||
{
|
||||
int8_t dr = rxConfig->Datarate;
|
||||
uint8_t maxPayload = 0;
|
||||
int8_t phyDr = 0;
|
||||
uint32_t frequency = rxConfig->Frequency;
|
||||
const char *slotStrings[] = { "1", "2", "C", "Multi_C", "P", "Multi_P" };
|
||||
|
||||
if( Radio.GetStatus( ) != RF_IDLE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( rxConfig->RxSlot == RX_SLOT_WIN_1 )
|
||||
{
|
||||
#if (ALI_DOWNLINK_FREQ == ALI_FREQ470_S || ALI_DOWNLINK_FREQ == ALI_FREQ480_D)
|
||||
if(rxConfig->Channel <32)
|
||||
frequency = CN470ALI_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 64 ) * CN470ALI_STEPWIDTH_RX1_CHANNEL;
|
||||
else
|
||||
frequency = (uint32_t)503500000 + ((rxConfig->Channel-32) % 64 ) * CN470ALI_STEPWIDTH_RX1_CHANNEL;
|
||||
|
||||
#else
|
||||
// Apply window 1 frequency
|
||||
frequency = CN470ALI_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 64 ) * CN470ALI_STEPWIDTH_RX1_CHANNEL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Read the physical datarate from the datarates table
|
||||
phyDr = DataratesCN470ALI[dr];
|
||||
|
||||
Radio.SetChannel( frequency );
|
||||
|
||||
// Radio configuration
|
||||
Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
|
||||
|
||||
if( rxConfig->RepeaterSupport == true )
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateRepeaterCN470ALI[dr];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPayload = MaxPayloadOfDatarateCN470ALI[dr];
|
||||
}
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
|
||||
if ( rxConfig->RxSlot < RX_SLOT_NONE )
|
||||
{
|
||||
MW_LOG( "RX_%s on freq %d Hz at DR %d\n\r", slotStrings[rxConfig->RxSlot], frequency, dr );
|
||||
}
|
||||
else
|
||||
{
|
||||
MW_LOG( "RX on freq %d Hz at DR %d\n\r", frequency, dr );
|
||||
}
|
||||
|
||||
*datarate = (uint8_t) dr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RegionCN470ALITxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir )
|
||||
{
|
||||
int8_t phyDr = DataratesCN470ALI[txConfig->Datarate];
|
||||
int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask );
|
||||
int8_t phyTxPower = 0;
|
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain );
|
||||
|
||||
// Setup the radio frequency
|
||||
Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
|
||||
|
||||
Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, 0, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
|
||||
MW_LOG( "TX on freq %d Hz at DR %d,TxPower %d\n\r", NvmCtx.Channels[txConfig->Channel].Frequency, txConfig->Datarate ,phyTxPower);
|
||||
|
||||
// Setup maximum payload lenght of the radio driver
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );
|
||||
// Get the time-on-air of the next tx frame
|
||||
*txTimeOnAir = Radio.TimeOnAir( MODEM_LORA, txConfig->PktLen );
|
||||
*txPower = txPowerLimited;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ALILinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed )
|
||||
{
|
||||
uint8_t status = 0x07;
|
||||
RegionCommonLinkAdrParams_t linkAdrParams;
|
||||
uint8_t nextIndex = 0;
|
||||
uint8_t bytesProcessed = 0;
|
||||
uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
GetPhyParams_t getPhy;
|
||||
PhyParam_t phyParam;
|
||||
RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams;
|
||||
|
||||
// Initialize local copy of channels mask
|
||||
RegionCommonChanMaskCopy( channelsMask, NvmCtx.ChannelsMask, 6 );
|
||||
|
||||
while( bytesProcessed < linkAdrReq->PayloadSize )
|
||||
{
|
||||
// Get ADR request parameters
|
||||
nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams );
|
||||
|
||||
if( nextIndex == 0 )
|
||||
break; // break loop, since no more request has been found
|
||||
|
||||
// Update bytes processed
|
||||
bytesProcessed += nextIndex;
|
||||
|
||||
// Revert status, as we only check the last ADR request for the channel mask KO
|
||||
status = 0x07;
|
||||
|
||||
/*===============================ALI_Region==============================================*/
|
||||
if( linkAdrParams.ChMaskCtrl >4 )
|
||||
{
|
||||
status &= 0xFE; // Channel mask KO
|
||||
}
|
||||
else if( linkAdrParams.ChMaskCtrl == 4)
|
||||
{
|
||||
// Enable all 125 kHz channels
|
||||
channelsMask[0] = 0xFFFF;
|
||||
channelsMask[1] = 0xFFFF;
|
||||
channelsMask[2] = 0xFFFF;
|
||||
channelsMask[3] = 0xFFFF;
|
||||
channelsMask[4] = 0;
|
||||
channelsMask[5] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( uint8_t i = 0; i < 16; i++ )
|
||||
{
|
||||
if( ( ( linkAdrParams.ChMask & ( 1 << i ) ) != 0 ) &&
|
||||
( NvmCtx.Channels[linkAdrParams.ChMaskCtrl * 16 + i].Frequency == 0 ) )
|
||||
{// Trying to enable an undefined channel
|
||||
status &= 0xFE; // Channel mask KO
|
||||
}
|
||||
}
|
||||
channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask;
|
||||
}
|
||||
}
|
||||
/*========================================================================================*/
|
||||
|
||||
// Get the minimum possible datarate
|
||||
getPhy.Attribute = PHY_MIN_TX_DR;
|
||||
getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime;
|
||||
phyParam = RegionCN470ALIGetPhyParam( &getPhy );
|
||||
|
||||
linkAdrVerifyParams.Status = status;
|
||||
linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled;
|
||||
linkAdrVerifyParams.Datarate = linkAdrParams.Datarate;
|
||||
linkAdrVerifyParams.TxPower = linkAdrParams.TxPower;
|
||||
linkAdrVerifyParams.NbRep = linkAdrParams.NbRep;
|
||||
linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate;
|
||||
linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower;
|
||||
linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep;
|
||||
linkAdrVerifyParams.NbChannels = CN470ALI_MAX_NB_CHANNELS;
|
||||
linkAdrVerifyParams.ChannelsMask = channelsMask;
|
||||
linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value;
|
||||
linkAdrVerifyParams.MaxDatarate = CN470ALI_TX_MAX_DATARATE;
|
||||
linkAdrVerifyParams.Channels = NvmCtx.Channels;
|
||||
linkAdrVerifyParams.MinTxPower = CN470ALI_MIN_TX_POWER;
|
||||
linkAdrVerifyParams.MaxTxPower = CN470ALI_MAX_TX_POWER;
|
||||
linkAdrVerifyParams.Version = linkAdrReq->Version;
|
||||
|
||||
// Verify the parameters and update, if necessary
|
||||
status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep );
|
||||
|
||||
// Update channelsMask if everything is correct
|
||||
if( status == 0x07 )
|
||||
{
|
||||
// Copy Mask
|
||||
RegionCommonChanMaskCopy( NvmCtx.ChannelsMask, channelsMask, 6 );
|
||||
}
|
||||
|
||||
// Update status variables
|
||||
*drOut = linkAdrParams.Datarate;
|
||||
*txPowOut = linkAdrParams.TxPower;
|
||||
*nbRepOut = linkAdrParams.NbRep;
|
||||
*nbBytesParsed = bytesProcessed;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ALIRxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq )
|
||||
{
|
||||
uint8_t status = 0x07;
|
||||
|
||||
// Verify radio frequency
|
||||
if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false )
|
||||
{
|
||||
status &= 0xFE; // Channel frequency KO
|
||||
}
|
||||
|
||||
// Verify datarate
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->Datarate, CN470ALI_RX_MIN_DATARATE, CN470ALI_RX_MAX_DATARATE ) == false )
|
||||
{
|
||||
status &= 0xFD; // Datarate KO
|
||||
}
|
||||
|
||||
// Verify datarate offset
|
||||
if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, CN470ALI_MIN_RX1_DR_OFFSET, CN470ALI_MAX_RX1_DR_OFFSET ) == false )
|
||||
{
|
||||
status &= 0xFB; // Rx1DrOffset range KO
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ALINewChannelReq( NewChannelReqParams_t* newChannelReq )
|
||||
{
|
||||
// Datarate and frequency KO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t RegionCN470ALITxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ALIDlChannelReq( DlChannelReqParams_t* dlChannelReq )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*===============================ALI_Region==============================================*/
|
||||
int8_t RegionCN470ALIAlternateDr( int8_t currentDr, AlternateDrType_t type )
|
||||
{
|
||||
static uint16_t JoinRequestTrials;
|
||||
if(ALTERNATE_DR == type)
|
||||
{
|
||||
++JoinRequestTrials;
|
||||
return ((JoinRequestTrials%2) ? DR_2 : DR_3);
|
||||
}
|
||||
return currentDr;
|
||||
}
|
||||
/*=======================================================================================*/
|
||||
|
||||
void RegionCN470ALICalcBackOff( CalcBackOffParams_t* calcBackOff )
|
||||
{
|
||||
RegionCommonCalcBackOffParams_t calcBackOffParams;
|
||||
|
||||
calcBackOffParams.Channels = NvmCtx.Channels;
|
||||
calcBackOffParams.Bands = NvmCtx.Bands;
|
||||
calcBackOffParams.LastTxIsJoinRequest = calcBackOff->LastTxIsJoinRequest;
|
||||
calcBackOffParams.Joined = calcBackOff->Joined;
|
||||
calcBackOffParams.DutyCycleEnabled = calcBackOff->DutyCycleEnabled;
|
||||
calcBackOffParams.Channel = calcBackOff->Channel;
|
||||
calcBackOffParams.ElapsedTime = calcBackOff->ElapsedTime;
|
||||
calcBackOffParams.TxTimeOnAir = calcBackOff->TxTimeOnAir;
|
||||
|
||||
RegionCommonCalcBackOff( &calcBackOffParams );
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470ALINextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )
|
||||
{
|
||||
uint8_t nbEnabledChannels = 0;
|
||||
uint8_t delayTx = 0;
|
||||
uint8_t enabledChannels[CN470ALI_MAX_NB_CHANNELS] = { 0 };
|
||||
TimerTime_t nextTxDelay = 0;
|
||||
|
||||
// Count 125kHz channels
|
||||
if( RegionCommonCountChannels( NvmCtx.ChannelsMask, 0, 6 ) == 0 )
|
||||
{ // Reactivate default channels
|
||||
NvmCtx.ChannelsMask[0] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[1] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[2] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[3] = 0xFFFF;
|
||||
NvmCtx.ChannelsMask[4] = 0;
|
||||
NvmCtx.ChannelsMask[5] = 0;
|
||||
}
|
||||
|
||||
TimerTime_t elapsed = TimerGetElapsedTime( nextChanParams->LastAggrTx );
|
||||
if( ( nextChanParams->LastAggrTx == 0 ) || ( nextChanParams->AggrTimeOff <= elapsed ) )
|
||||
{
|
||||
// Reset Aggregated time off
|
||||
*aggregatedTimeOff = 0;
|
||||
|
||||
// Update bands Time OFF
|
||||
nextTxDelay = RegionCommonUpdateBandTimeOff( nextChanParams->Joined, nextChanParams->DutyCycleEnabled, NvmCtx.Bands, CN470ALI_MAX_NB_BANDS );
|
||||
|
||||
// Search how many channels are enabled
|
||||
nbEnabledChannels = CountNbOfEnabledChannels( nextChanParams->Datarate,
|
||||
NvmCtx.ChannelsMask, NvmCtx.Channels,
|
||||
NvmCtx.Bands, enabledChannels, &delayTx );
|
||||
}
|
||||
else
|
||||
{
|
||||
delayTx++;
|
||||
nextTxDelay = nextChanParams->AggrTimeOff - elapsed;
|
||||
}
|
||||
|
||||
if( nbEnabledChannels > 0 )
|
||||
{
|
||||
// We found a valid channel
|
||||
*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];
|
||||
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( delayTx > 0 )
|
||||
{
|
||||
// Delay transmission due to AggregatedTimeOff or to a band time off
|
||||
*time = nextTxDelay;
|
||||
return LORAMAC_STATUS_DUTYCYCLE_RESTRICTED;
|
||||
}
|
||||
// Datarate not supported by any channel
|
||||
*time = 0;
|
||||
return LORAMAC_STATUS_NO_CHANNEL_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacStatus_t RegionCN470ALIChannelAdd( ChannelAddParams_t* channelAdd )
|
||||
{
|
||||
return LORAMAC_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
bool RegionCN470ALIChannelsRemove( ChannelRemoveParams_t* channelRemove )
|
||||
{
|
||||
return LORAMAC_STATUS_PARAMETER_INVALID;
|
||||
}
|
||||
|
||||
void RegionCN470ALISetContinuousWave( ContinuousWaveParams_t* continuousWave )
|
||||
{
|
||||
int8_t txPowerLimited = LimitTxPower( continuousWave->TxPower, NvmCtx.Bands[NvmCtx.Channels[continuousWave->Channel].Band].TxMaxPower, continuousWave->Datarate, NvmCtx.ChannelsMask );
|
||||
int8_t phyTxPower = 0;
|
||||
uint32_t frequency = NvmCtx.Channels[continuousWave->Channel].Frequency;
|
||||
|
||||
// Calculate physical TX power
|
||||
phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain );
|
||||
|
||||
Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout );
|
||||
}
|
||||
|
||||
uint8_t RegionCN470ALIApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset )
|
||||
{
|
||||
int8_t datarate = dr - drOffset;
|
||||
|
||||
if( datarate < 0 )
|
||||
{
|
||||
datarate = DR_0;
|
||||
}
|
||||
return datarate;
|
||||
}
|
||||
|
||||
void RegionCN470ALIRxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr )
|
||||
{
|
||||
RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup;
|
||||
|
||||
regionCommonRxBeaconSetup.Datarates = DataratesCN470ALI;
|
||||
regionCommonRxBeaconSetup.Frequency = rxBeaconSetup->Frequency;
|
||||
regionCommonRxBeaconSetup.BeaconSize = CN470ALI_BEACON_SIZE;
|
||||
regionCommonRxBeaconSetup.BeaconDatarate = CN470ALI_BEACON_CHANNEL_DR;
|
||||
regionCommonRxBeaconSetup.BeaconChannelBW = CN470ALI_BEACON_CHANNEL_BW;
|
||||
regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime;
|
||||
regionCommonRxBeaconSetup.SymbolTimeout = rxBeaconSetup->SymbolTimeout;
|
||||
|
||||
RegionCommonRxBeaconSetup( ®ionCommonRxBeaconSetup );
|
||||
|
||||
// Store downlink datarate
|
||||
*outDr = CN470ALI_BEACON_CHANNEL_DR;
|
||||
}
|
||||
|
|
@ -0,0 +1,594 @@
|
|||
/*!
|
||||
* \file RegionCN470ALI.h
|
||||
*
|
||||
* \brief Region definition for CN470ALI
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONCN470ALI Region CN470ALI
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_CN470ALI_H__
|
||||
#define __REGION_CN470ALI_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
#define ALI_FREQ470_S (0)
|
||||
#define ALI_FREQ470_D (1)
|
||||
|
||||
#define ALI_FREQ480_S (3)
|
||||
#define ALI_FREQ480_D (4)
|
||||
|
||||
/*table[1] for CN470ALID and CN480ALIS*/
|
||||
#define ALI_RX_WND_2_FREQ_1A1D_1B1S 485300000
|
||||
#define ALI_RX_WND_2_FREQ_1A2D_1B2S 486900000
|
||||
#define ALI_RX_WND_2_FREQ_2A1D_2B1S 488500000
|
||||
#define ALI_RX_WND_2_FREQ_2A2D_2B2S 490100000
|
||||
#define ALI_RX_WND_2_FREQ_3B1D_3A1S 491700000
|
||||
#define ALI_RX_WND_2_FREQ_3B2D_3A2S 493300000
|
||||
#define ALI_RX_WND_2_FREQ_4B1D_4A1S 494900000
|
||||
#define ALI_RX_WND_2_FREQ_4B2D_4A2S 496500000
|
||||
|
||||
/*table[2] for CN470ALIS and CN480ALID*/
|
||||
#define ALI_RX_WND_2_FREQ_1A1S_1B1D 471700000
|
||||
#define ALI_RX_WND_2_FREQ_1A2S_1B2D 473300000
|
||||
#define ALI_RX_WND_2_FREQ_2A1S_2B1D 474900000
|
||||
#define ALI_RX_WND_2_FREQ_2A2S_2B2D 476500000
|
||||
#define ALI_RX_WND_2_FREQ_3B1S_3A1D 504900000
|
||||
#define ALI_RX_WND_2_FREQ_3B2S_3A2D 506500000
|
||||
#define ALI_RX_WND_2_FREQ_4B1S_4A1D 508100000
|
||||
#define ALI_RX_WND_2_FREQ_4B2S_4A2D 509700000
|
||||
|
||||
|
||||
|
||||
/*TODO: add beacon freq*/
|
||||
|
||||
|
||||
|
||||
#define ALI_DOWNLINK_FREQ ALI_FREQ470_S
|
||||
#define ALI_RX2WIN_FREQ ALI_RX_WND_2_FREQ_1A2S_1B2D
|
||||
#define ALI_BEACON_FREQ
|
||||
|
||||
|
||||
/*error msg*/
|
||||
#if ((ALI_DOWNLINK_FREQ == ALI_FREQ470_D)||(ALI_DOWNLINK_FREQ == ALI_FREQ480_S))
|
||||
#if (ALI_RX2WIN_FREQ < ALI_RX_WND_2_FREQ_1A1D_1B1S) ||((ALI_RX2WIN_FREQ > ALI_RX_WND_2_FREQ_4B2D_4A2S))
|
||||
#error ======>Incorrect ALI_RX2WIN_FREQ , you should use the value in table[1]
|
||||
#endif
|
||||
#else
|
||||
#if ((ALI_RX2WIN_FREQ < ALI_RX_WND_2_FREQ_1A1S_1B1D)||(ALI_RX2WIN_FREQ > ALI_RX_WND_2_FREQ_4B2S_4A2D))
|
||||
#error ======>Incorrect ALI_RX2WIN_FREQ , you should use the value in table[2]
|
||||
#endif
|
||||
#if ((ALI_RX2WIN_FREQ > ALI_RX_WND_2_FREQ_2A2S_2B2D) && (ALI_RX2WIN_FREQ < ALI_RX_WND_2_FREQ_3B1S_3A1D))
|
||||
##error ======>Incorrect ALI_RX2WIN_FREQ , you should use the value in table[2]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ALI_DOWNLINK_FREQ
|
||||
#error ALI_DOWNLINK_FREQ not defined
|
||||
#endif
|
||||
#ifndef ALI_RX2WIN_FREQ
|
||||
#erorr ALI_RX2WIN_FREQ not defined
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define CN470ALI_MAX_NB_CHANNELS 64
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_TX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_RX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
|
||||
/*===============================ALI_Region==============================================*/
|
||||
#define CN470ALI_DEFAULT_DATARATE DR_2//primitive_cn470 DR_0
|
||||
/*=======================================================================================*/
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470ALI_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470ALI_MAX_RX1_DR_OFFSET 3
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN470ALI_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN470ALI_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define CN470ALI_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define CN470ALI_DEFAULT_MAX_EIRP 19.15f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define CN470ALI_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define CN470ALI_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define CN470ALI_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define CN470ALI_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define CN470ALI_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define CN470ALI_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define CN470ALI_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define CN470ALI_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define CN470ALI_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define CN470ALI_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define CN470ALI_ACKTIMEOUT 5500
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define CN470ALI_ACK_TIMEOUT_RND 500
|
||||
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define CN470ALI_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define CN470ALI_BEACON_CHANNEL_FREQ 485500000
|
||||
|
||||
/*!
|
||||
* Beacon frequency channel stepwidth
|
||||
*/
|
||||
#define CN470ALI_BEACON_CHANNEL_STEPWIDTH 200000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
#define CN470ALI_BEACON_NB_CHANNELS 8
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define CN470ALI_BEACON_SIZE 19
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define CN470ALI_RFU1_SIZE 3
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define CN470ALI_RFU2_SIZE 1
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define CN470ALI_BEACON_CHANNEL_DR DR_2
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define CN470ALI_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define CN470ALI_PING_SLOT_CHANNEL_DR DR_2
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define CN470ALI_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define CN470ALI_BAND0 { 1, CN470ALI_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
#ifdef ALI_DOWNLINK_FREQ
|
||||
|
||||
#if (ALI_DOWNLINK_FREQ == ALI_FREQ470_S || ALI_DOWNLINK_FREQ == ALI_FREQ480_D)
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for CN470ALI band
|
||||
*/
|
||||
#define CN470ALI_FIRST_RX1_CHANNEL ( (uint32_t) 470300000 )
|
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for CN470ALI band
|
||||
*/
|
||||
#define CN470ALI_LAST_RX1_CHANNEL ( (uint32_t) 509700000 )
|
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1
|
||||
*/
|
||||
#define CN470ALI_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200000 )
|
||||
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define CN470ALI_RX_WND_2_FREQ ((uint32_t)ALI_RX2WIN_FREQ)
|
||||
|
||||
|
||||
#elif (ALI_DOWNLINK_FREQ == ALI_FREQ470_D || ALI_DOWNLINK_FREQ == ALI_FREQ480_S)
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for CN470ALI band
|
||||
*/
|
||||
#define CN470ALI_FIRST_RX1_CHANNEL ( (uint32_t) 483900000 )
|
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for CN470ALI band
|
||||
*/
|
||||
#define CN470ALI_LAST_RX1_CHANNEL ( (uint32_t) 496500000 )
|
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1
|
||||
*/
|
||||
#define CN470ALI_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 200000 )
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define CN470ALI_RX_WND_2_FREQ ((uint32_t)ALI_RX2WIN_FREQ)
|
||||
|
||||
|
||||
#else
|
||||
#error ALI_DOWNLINK_FREQ not existed
|
||||
|
||||
|
||||
#endif //===============================================================================>
|
||||
#else
|
||||
#error ALI_DOWNLINK_FREQ not define
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesCN470ALI[] = { 12, 11, 10, 9, 8, 7 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsCN470ALI[] = { 125000, 125000, 125000, 125000, 125000, 125000 };
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
|
||||
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateCN470ALI[] = { 51+1, 51+1, 51+1, 115+1, 242+1, 242+1 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN470ALI[] = { 51+1, 51+1, 51+1, 115+1, 222+1, 222+1 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionCN470ALIGetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470ALISetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionCN470ALIInitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionCN470ALIGetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionCN470ALIVerify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470ALIApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionCN470ALIChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionCN470ALIComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN470ALIRxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN470ALITxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470ALILinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470ALIRxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470ALINewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionCN470ALITxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN470ALIDlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionCN470ALIAlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470ALICalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN470ALINextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN470ALIChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionCN470ALIChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN470ALISetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionCN470ALIApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionCN470ALIRxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONCN470ALI */
|
||||
|
||||
#endif // __REGION_CN470ALI_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,508 @@
|
|||
/*!
|
||||
* \file RegionCN779.h
|
||||
*
|
||||
* \brief Region definition for CN779
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONCN779 Region CN779
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_CN779_H__
|
||||
#define __REGION_CN779_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define CN779_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define CN779_NUMB_DEFAULT_CHANNELS 3
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define CN779_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN779_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN779_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define CN779_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define CN779_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define CN779_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN779_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN779_MAX_RX1_DR_OFFSET 5
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define CN779_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN779_MIN_TX_POWER TX_POWER_5
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define CN779_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define CN779_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define CN779_DEFAULT_MAX_EIRP 12.15f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define CN779_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define CN779_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define CN779_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define CN779_DUTY_CYCLE_ENABLED 1
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define CN779_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define CN779_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define CN779_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define CN779_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define CN779_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define CN779_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define CN779_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define CN779_ACK_TIMEOUT_RND 1000
|
||||
|
||||
/*!
|
||||
* Verification of default datarate
|
||||
*/
|
||||
#if ( CN779_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define CN779_RX_WND_2_FREQ 786000000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define CN779_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define CN779_BEACON_CHANNEL_FREQ 785000000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define CN779_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define CN779_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define CN779_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define CN779_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define CN779_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define CN779_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define CN779_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define CN779_BAND0 { 100, CN779_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define CN779_LC1 { 779500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define CN779_LC2 { 779700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define CN779_LC3 { 779900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define CN779_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesCN779[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsCN779[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateCN779[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterCN779[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionCN779InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionCN779GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionCN779Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN779ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionCN779ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionCN779ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN779RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionCN779TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN779LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN779RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN779NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionCN779TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionCN779DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionCN779AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN779CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionCN779ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionCN779ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionCN779SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionCN779ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionCN779RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONCN779 */
|
||||
|
||||
#endif // __REGION_CN779_H__
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
/*!
|
||||
* \file RegionCommon.c
|
||||
*
|
||||
* \brief LoRa MAC common region implementation
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*/
|
||||
#include <math.h>
|
||||
#include "radio.h"
|
||||
#include "utilities.h"
|
||||
#include "RegionCommon.h"
|
||||
|
||||
#define BACKOFF_DC_1_HOUR 100
|
||||
#define BACKOFF_DC_10_HOURS 1000
|
||||
#define BACKOFF_DC_24_HOURS 10000
|
||||
|
||||
static uint8_t CountChannels( uint16_t mask, uint8_t nbBits )
|
||||
{
|
||||
uint8_t nbActiveBits = 0;
|
||||
|
||||
for( uint8_t j = 0; j < nbBits; j++ )
|
||||
{
|
||||
if( ( mask & ( 1 << j ) ) == ( 1 << j ) )
|
||||
{
|
||||
nbActiveBits++;
|
||||
}
|
||||
}
|
||||
return nbActiveBits;
|
||||
}
|
||||
|
||||
uint16_t RegionCommonGetJoinDc( TimerTime_t elapsedTime )
|
||||
{
|
||||
uint16_t dutyCycle = 0;
|
||||
|
||||
if( elapsedTime < 3600000 )
|
||||
{
|
||||
dutyCycle = BACKOFF_DC_1_HOUR;
|
||||
}
|
||||
else if( elapsedTime < ( 3600000 + 36000000 ) )
|
||||
{
|
||||
dutyCycle = BACKOFF_DC_10_HOURS;
|
||||
}
|
||||
else
|
||||
{
|
||||
dutyCycle = BACKOFF_DC_24_HOURS;
|
||||
}
|
||||
return dutyCycle;
|
||||
}
|
||||
|
||||
bool RegionCommonChanVerifyDr( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr, int8_t minDr, int8_t maxDr, ChannelParams_t* channels )
|
||||
{
|
||||
if( RegionCommonValueInRange( dr, minDr, maxDr ) == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( uint8_t i = 0, k = 0; i < nbChannels; i += 16, k++ )
|
||||
{
|
||||
for( uint8_t j = 0; j < 16; j++ )
|
||||
{
|
||||
if( ( ( channelsMask[k] & ( 1 << j ) ) != 0 ) )
|
||||
{// Check datarate validity for enabled channels
|
||||
if( RegionCommonValueInRange( dr, ( channels[i + j].DrRange.Fields.Min & 0x0F ),
|
||||
( channels[i + j].DrRange.Fields.Max & 0x0F ) ) == 1 )
|
||||
{
|
||||
// At least 1 channel has been found we can return OK.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t RegionCommonValueInRange( int8_t value, int8_t min, int8_t max )
|
||||
{
|
||||
if( ( value >= min ) && ( value <= max ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RegionCommonChanDisable( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels )
|
||||
{
|
||||
uint8_t index = id / 16;
|
||||
|
||||
if( ( index > ( maxChannels / 16 ) ) || ( id >= maxChannels ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deactivate channel
|
||||
channelsMask[index] &= ~( 1 << ( id % 16 ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t RegionCommonCountChannels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx )
|
||||
{
|
||||
uint8_t nbChannels = 0;
|
||||
|
||||
if( channelsMask == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( uint8_t i = startIdx; i < stopIdx; i++ )
|
||||
{
|
||||
nbChannels += CountChannels( channelsMask[i], 16 );
|
||||
}
|
||||
|
||||
return nbChannels;
|
||||
}
|
||||
|
||||
void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len )
|
||||
{
|
||||
if( ( channelsMaskDest != NULL ) && ( channelsMaskSrc != NULL ) )
|
||||
{
|
||||
for( uint8_t i = 0; i < len; i++ )
|
||||
{
|
||||
channelsMaskDest[i] = channelsMaskSrc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone )
|
||||
{
|
||||
if( joined == true )
|
||||
{
|
||||
band->LastTxDoneTime = lastTxDone;
|
||||
}
|
||||
else
|
||||
{
|
||||
band->LastTxDoneTime = lastTxDone;
|
||||
band->LastJoinTxDoneTime = lastTxDone;
|
||||
}
|
||||
}
|
||||
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands )
|
||||
{
|
||||
TimerTime_t nextTxDelay = TIMERTIME_T_MAX;
|
||||
|
||||
// Update bands Time OFF
|
||||
for( uint8_t i = 0; i < nbBands; i++ )
|
||||
{
|
||||
if( joined == false )
|
||||
{
|
||||
TimerTime_t elapsedJoin = TimerGetElapsedTime( bands[i].LastJoinTxDoneTime );
|
||||
TimerTime_t elapsedTx = TimerGetElapsedTime( bands[i].LastTxDoneTime );
|
||||
TimerTime_t txDoneTime = MAX( elapsedJoin,
|
||||
( dutyCycle == true ) ? elapsedTx : 0 );
|
||||
|
||||
if( bands[i].TimeOff <= txDoneTime )
|
||||
{
|
||||
bands[i].TimeOff = 0;
|
||||
}
|
||||
if( bands[i].TimeOff != 0 )
|
||||
{
|
||||
nextTxDelay = MIN( bands[i].TimeOff - txDoneTime, nextTxDelay );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dutyCycle == true )
|
||||
{
|
||||
TimerTime_t elapsed = TimerGetElapsedTime( bands[i].LastTxDoneTime );
|
||||
if( bands[i].TimeOff <= elapsed )
|
||||
{
|
||||
bands[i].TimeOff = 0;
|
||||
}
|
||||
if( bands[i].TimeOff != 0 )
|
||||
{
|
||||
nextTxDelay = MIN( bands[i].TimeOff - elapsed, nextTxDelay );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nextTxDelay = 0;
|
||||
bands[i].TimeOff = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ( nextTxDelay == TIMERTIME_T_MAX ) ? 0 : nextTxDelay;
|
||||
}
|
||||
|
||||
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* linkAdrParams )
|
||||
{
|
||||
uint8_t retIndex = 0;
|
||||
|
||||
if( payload[0] == SRV_MAC_LINK_ADR_REQ )
|
||||
{
|
||||
// Parse datarate and tx power
|
||||
linkAdrParams->Datarate = payload[1];
|
||||
linkAdrParams->TxPower = linkAdrParams->Datarate & 0x0F;
|
||||
linkAdrParams->Datarate = ( linkAdrParams->Datarate >> 4 ) & 0x0F;
|
||||
// Parse ChMask
|
||||
linkAdrParams->ChMask = ( uint16_t )payload[2];
|
||||
linkAdrParams->ChMask |= ( uint16_t )payload[3] << 8;
|
||||
// Parse ChMaskCtrl and nbRep
|
||||
linkAdrParams->NbRep = payload[4];
|
||||
linkAdrParams->ChMaskCtrl = ( linkAdrParams->NbRep >> 4 ) & 0x07;
|
||||
linkAdrParams->NbRep &= 0x0F;
|
||||
|
||||
// LinkAdrReq has 4 bytes length + 1 byte CMD
|
||||
retIndex = 5;
|
||||
}
|
||||
return retIndex;
|
||||
}
|
||||
|
||||
uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep )
|
||||
{
|
||||
uint8_t status = verifyParams->Status;
|
||||
int8_t datarate = verifyParams->Datarate;
|
||||
int8_t txPower = verifyParams->TxPower;
|
||||
int8_t nbRepetitions = verifyParams->NbRep;
|
||||
|
||||
// Handle the case when ADR is off.
|
||||
if( verifyParams->AdrEnabled == false )
|
||||
{
|
||||
// When ADR is off, we are allowed to change the channels mask
|
||||
nbRepetitions = verifyParams->CurrentNbRep;
|
||||
datarate = verifyParams->CurrentDatarate;
|
||||
txPower = verifyParams->CurrentTxPower;
|
||||
}
|
||||
|
||||
if( status != 0 )
|
||||
{
|
||||
// Verify datarate. The variable phyParam. Value contains the minimum allowed datarate.
|
||||
if( RegionCommonChanVerifyDr( verifyParams->NbChannels, verifyParams->ChannelsMask, datarate,
|
||||
verifyParams->MinDatarate, verifyParams->MaxDatarate, verifyParams->Channels ) == false )
|
||||
{
|
||||
status &= 0xFD; // Datarate KO
|
||||
}
|
||||
|
||||
// Verify tx power
|
||||
if( RegionCommonValueInRange( txPower, verifyParams->MaxTxPower, verifyParams->MinTxPower ) == 0 )
|
||||
{
|
||||
// Verify if the maximum TX power is exceeded
|
||||
if( verifyParams->MaxTxPower > txPower )
|
||||
{ // Apply maximum TX power. Accept TX power.
|
||||
txPower = verifyParams->MaxTxPower;
|
||||
}
|
||||
else
|
||||
{
|
||||
status &= 0xFB; // TxPower KO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the status is ok, verify the NbRep
|
||||
if( status == 0x07 )
|
||||
{
|
||||
if( nbRepetitions == 0 )
|
||||
{ // Restore the default value according to the LoRaWAN specification
|
||||
nbRepetitions = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply changes
|
||||
*dr = datarate;
|
||||
*txPow = txPower;
|
||||
*nbRep = nbRepetitions;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
double RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth )
|
||||
{
|
||||
return ( ( double )( 1 << phyDr ) / ( double )bandwidth ) * 1000;
|
||||
}
|
||||
|
||||
double RegionCommonComputeSymbolTimeFsk( uint8_t phyDr )
|
||||
{
|
||||
return ( 8.0 / ( double )phyDr ); // 1 symbol equals 1 byte
|
||||
}
|
||||
|
||||
void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset )
|
||||
{
|
||||
*windowTimeout = MAX( ( uint32_t )ceil( ( ( 2 * minRxSymbols - 8 ) * tSymbol + 2 * rxError ) / tSymbol ), minRxSymbols ); // Computed number of symbols
|
||||
*windowOffset = ( int32_t )ceil( ( 4.0 * tSymbol ) - ( ( *windowTimeout * tSymbol ) / 2.0 ) - wakeUpTime );
|
||||
}
|
||||
|
||||
int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain )
|
||||
{
|
||||
int8_t phyTxPower = 0;
|
||||
|
||||
phyTxPower = ( int8_t )floor( ( maxEirp - ( txPowerIndex * 2U ) ) - antennaGain );
|
||||
|
||||
return phyTxPower;
|
||||
}
|
||||
|
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams )
|
||||
{
|
||||
uint8_t bandIdx = calcBackOffParams->Channels[calcBackOffParams->Channel].Band;
|
||||
uint16_t dutyCycle = calcBackOffParams->Bands[bandIdx].DCycle;
|
||||
uint16_t joinDutyCycle = 0;
|
||||
|
||||
// Reset time-off to initial value.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
|
||||
if( calcBackOffParams->Joined == false )
|
||||
{
|
||||
// Get the join duty cycle
|
||||
joinDutyCycle = RegionCommonGetJoinDc( calcBackOffParams->ElapsedTime );
|
||||
// Apply the most restricting duty cycle
|
||||
dutyCycle = MAX( dutyCycle, joinDutyCycle );
|
||||
// Reset the timeoff if the last frame was not a join request and when the duty cycle is not enabled
|
||||
if( ( calcBackOffParams->DutyCycleEnabled == false ) && ( calcBackOffParams->LastTxIsJoinRequest == false ) )
|
||||
{
|
||||
// This is the case when the duty cycle is off and the last uplink frame was not a join.
|
||||
// This could happen in case of a rejoin, e.g. in compliance test mode.
|
||||
// In this special case we have to set the time off to 0, since the join duty cycle shall only
|
||||
// be applied after the first join request.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply band time-off.
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( calcBackOffParams->DutyCycleEnabled == true )
|
||||
{
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = calcBackOffParams->TxTimeOnAir * dutyCycle - calcBackOffParams->TxTimeOnAir;
|
||||
}
|
||||
else
|
||||
{
|
||||
calcBackOffParams->Bands[bandIdx].TimeOff = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetupParams )
|
||||
{
|
||||
bool rxContinuous = true;
|
||||
uint8_t datarate;
|
||||
|
||||
// Set the radio into sleep mode
|
||||
Radio.Sleep( );
|
||||
|
||||
// Setup frequency and payload length
|
||||
Radio.SetChannel( rxBeaconSetupParams->Frequency );
|
||||
Radio.SetMaxPayloadLength( MODEM_LORA, rxBeaconSetupParams->BeaconSize );
|
||||
|
||||
// Check the RX continuous mode
|
||||
if( rxBeaconSetupParams->RxTime != 0 )
|
||||
{
|
||||
rxContinuous = false;
|
||||
}
|
||||
|
||||
// Get region specific datarate
|
||||
datarate = rxBeaconSetupParams->Datarates[rxBeaconSetupParams->BeaconDatarate];
|
||||
|
||||
// Setup radio
|
||||
Radio.SetRxConfig( MODEM_LORA, rxBeaconSetupParams->BeaconChannelBW, datarate,
|
||||
1, 0, 10, rxBeaconSetupParams->SymbolTimeout, true, rxBeaconSetupParams->BeaconSize, false, 0, 0, false, rxContinuous );
|
||||
|
||||
Radio.Rx( rxBeaconSetupParams->RxTime );
|
||||
}
|
||||
|
|
@ -0,0 +1,421 @@
|
|||
/*!
|
||||
* \file RegionCommon.h
|
||||
*
|
||||
* \brief Region independent implementations which are common to all regions.
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONCOMMON Common region implementation
|
||||
* Region independent implementations which are common to all regions.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGIONCOMMON_H__
|
||||
#define __REGIONCOMMON_H__
|
||||
|
||||
#include "utilities.h"
|
||||
#include "radio.h"
|
||||
#include "LoRaMacTypes.h"
|
||||
#include "region/Region.h"
|
||||
|
||||
typedef struct sRegionCommonLinkAdrParams
|
||||
{
|
||||
/*!
|
||||
* Number of repetitions.
|
||||
*/
|
||||
uint8_t NbRep;
|
||||
/*!
|
||||
* Datarate.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* Tx power.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* Channels mask control field.
|
||||
*/
|
||||
uint8_t ChMaskCtrl;
|
||||
/*!
|
||||
* Channels mask field.
|
||||
*/
|
||||
uint16_t ChMask;
|
||||
}RegionCommonLinkAdrParams_t;
|
||||
|
||||
typedef struct sRegionCommonLinkAdrReqVerifyParams
|
||||
{
|
||||
/*!
|
||||
* LoRaWAN specification Version
|
||||
*/
|
||||
Version_t Version;
|
||||
/*!
|
||||
* The current status of the AdrLinkRequest.
|
||||
*/
|
||||
uint8_t Status;
|
||||
/*!
|
||||
* Set to true, if ADR is enabled.
|
||||
*/
|
||||
bool AdrEnabled;
|
||||
/*!
|
||||
* The datarate the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t Datarate;
|
||||
/*!
|
||||
* The TX power the AdrLinkRequest wants to set.
|
||||
*/
|
||||
int8_t TxPower;
|
||||
/*!
|
||||
* The number of repetitions the AdrLinkRequest wants to set.
|
||||
*/
|
||||
uint8_t NbRep;
|
||||
/*!
|
||||
* The current datarate the node is using.
|
||||
*/
|
||||
int8_t CurrentDatarate;
|
||||
/*!
|
||||
* The current TX power the node is using.
|
||||
*/
|
||||
int8_t CurrentTxPower;
|
||||
/*!
|
||||
* The current number of repetitions the node is using.
|
||||
*/
|
||||
int8_t CurrentNbRep;
|
||||
/*!
|
||||
* The number of channels.
|
||||
*/
|
||||
uint8_t NbChannels;
|
||||
/*!
|
||||
* Pointer to the first element of the channels mask.
|
||||
*/
|
||||
uint16_t* ChannelsMask;
|
||||
/*!
|
||||
* The minimum possible datarate.
|
||||
*/
|
||||
int8_t MinDatarate;
|
||||
/*!
|
||||
* The maximum possible datarate.
|
||||
*/
|
||||
int8_t MaxDatarate;
|
||||
/*!
|
||||
* Pointer to the channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* The minimum possible TX power.
|
||||
*/
|
||||
int8_t MinTxPower;
|
||||
/*!
|
||||
* The maximum possible TX power.
|
||||
*/
|
||||
int8_t MaxTxPower;
|
||||
}RegionCommonLinkAdrReqVerifyParams_t;
|
||||
|
||||
typedef struct sRegionCommonCalcBackOffParams
|
||||
{
|
||||
/*!
|
||||
* A pointer to region specific channels.
|
||||
*/
|
||||
ChannelParams_t* Channels;
|
||||
/*!
|
||||
* A pointer to region specific bands.
|
||||
*/
|
||||
Band_t* Bands;
|
||||
/*!
|
||||
* Set to true, if the last uplink was a join request.
|
||||
*/
|
||||
bool LastTxIsJoinRequest;
|
||||
/*!
|
||||
* Set to true, if the node is joined.
|
||||
*/
|
||||
bool Joined;
|
||||
/*!
|
||||
* Set to true, if the duty cycle is enabled.
|
||||
*/
|
||||
bool DutyCycleEnabled;
|
||||
/*!
|
||||
* The current channel.
|
||||
*/
|
||||
uint8_t Channel;
|
||||
/*!
|
||||
* The elapsed time since initialization.
|
||||
*/
|
||||
TimerTime_t ElapsedTime;
|
||||
/*!
|
||||
* The time on air of the last Tx frame.
|
||||
*/
|
||||
TimerTime_t TxTimeOnAir;
|
||||
}RegionCommonCalcBackOffParams_t;
|
||||
|
||||
typedef struct sRegionCommonRxBeaconSetupParams
|
||||
{
|
||||
/*!
|
||||
* A pointer to the available datarates.
|
||||
*/
|
||||
const uint8_t* Datarates;
|
||||
/*!
|
||||
* Frequency
|
||||
*/
|
||||
uint32_t Frequency;
|
||||
/*!
|
||||
* The size of the beacon frame.
|
||||
*/
|
||||
uint8_t BeaconSize;
|
||||
/*!
|
||||
* The datarate of the beacon.
|
||||
*/
|
||||
uint8_t BeaconDatarate;
|
||||
/*!
|
||||
* The channel bandwidth of the beacon.
|
||||
*/
|
||||
uint8_t BeaconChannelBW;
|
||||
/*!
|
||||
* The RX time.
|
||||
*/
|
||||
uint32_t RxTime;
|
||||
/*!
|
||||
* The symbol timeout of the RX procedure.
|
||||
*/
|
||||
uint16_t SymbolTimeout;
|
||||
}RegionCommonRxBeaconSetupParams_t;
|
||||
|
||||
/*!
|
||||
* \brief Calculates the join duty cycle.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] elapsedTime Elapsed time since the start of the device.
|
||||
*
|
||||
* \retval Duty cycle restriction.
|
||||
*/
|
||||
uint16_t RegionCommonGetJoinDc( TimerTime_t elapsedTime );
|
||||
|
||||
/*!
|
||||
* \brief Verifies, if a value is in a given range.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] value Value to verify, if it is in range.
|
||||
*
|
||||
* \param [IN] min Minimum possible value.
|
||||
*
|
||||
* \param [IN] max Maximum possible value.
|
||||
*
|
||||
* \retval Returns 1 if the value is in range, otherwise 0.
|
||||
*/
|
||||
uint8_t RegionCommonValueInRange( int8_t value, int8_t min, int8_t max );
|
||||
|
||||
/*!
|
||||
* \brief Verifies, if a datarate is available on an active channel.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] nbChannels Number of channels.
|
||||
*
|
||||
* \param [IN] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [IN] dr The datarate to verify.
|
||||
*
|
||||
* \param [IN] minDr Minimum datarate.
|
||||
*
|
||||
* \param [IN] maxDr Maximum datarate.
|
||||
*
|
||||
* \param [IN] channels The channels of the region.
|
||||
*
|
||||
* \retval Returns true if the datarate is supported, false if not.
|
||||
*/
|
||||
bool RegionCommonChanVerifyDr( uint8_t nbChannels, uint16_t* channelsMask, int8_t dr,
|
||||
int8_t minDr, int8_t maxDr, ChannelParams_t* channels );
|
||||
|
||||
/*!
|
||||
* \brief Disables a channel in a given channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [IN] id The id of the channels mask to disable.
|
||||
*
|
||||
* \param [IN] maxChannels Maximum number of channels.
|
||||
*
|
||||
* \retval Returns true if the channel could be disabled, false if not.
|
||||
*/
|
||||
bool RegionCommonChanDisable( uint16_t* channelsMask, uint8_t id, uint8_t maxChannels );
|
||||
|
||||
/*!
|
||||
* \brief Counts the number of active channels in a given channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] channelsMask The channels mask of the region.
|
||||
*
|
||||
* \param [IN] startIdx Start index.
|
||||
*
|
||||
* \param [IN] stopIdx Stop index ( the channels of this index will not be counted ).
|
||||
*
|
||||
* \retval Returns the number of active channels.
|
||||
*/
|
||||
uint8_t RegionCommonCountChannels( uint16_t* channelsMask, uint8_t startIdx, uint8_t stopIdx );
|
||||
|
||||
/*!
|
||||
* \brief Copy a channels mask.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] channelsMaskDest The destination channels mask.
|
||||
*
|
||||
* \param [IN] channelsMaskSrc The source channels mask.
|
||||
*
|
||||
* \param [IN] len The index length to copy.
|
||||
*/
|
||||
void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMaskSrc, uint8_t len );
|
||||
|
||||
/*!
|
||||
* \brief Sets the last tx done property.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [IN] band The band to be updated.
|
||||
*
|
||||
* \param [IN] lastTxDone The time of the last TX done.
|
||||
*/
|
||||
void RegionCommonSetBandTxDone( bool joined, Band_t* band, TimerTime_t lastTxDone );
|
||||
|
||||
/*!
|
||||
* \brief Updates the time-offs of the bands.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] joined Set to true, if the node has joined the network
|
||||
*
|
||||
* \param [IN] dutyCycle Set to true, if the duty cycle is enabled.
|
||||
*
|
||||
* \param [IN] bands A pointer to the bands.
|
||||
*
|
||||
* \param [IN] nbBands The number of bands available.
|
||||
*
|
||||
* \retval Returns the time which must be waited to perform the next uplink.
|
||||
*/
|
||||
TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, bool dutyCycle, Band_t* bands, uint8_t nbBands );
|
||||
|
||||
/*!
|
||||
* \brief Parses the parameter of an LinkAdrRequest.
|
||||
* This is a generic function and valid for all regions.
|
||||
*
|
||||
* \param [IN] payload Pointer to the payload containing the MAC commands. The payload
|
||||
* must contain the CMD identifier, following by the parameters.
|
||||
*
|
||||
* \param [OUT] parseLinkAdr The function fills the structure with the ADR parameters.
|
||||
*
|
||||
* \retval Returns the length of the ADR request, if a request was found. Otherwise, the
|
||||
* function returns 0.
|
||||
*/
|
||||
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* parseLinkAdr );
|
||||
|
||||
/*!
|
||||
* \brief Verifies and updates the datarate, the TX power and the number of repetitions
|
||||
* of a LinkAdrRequest. This depends on the configuration of ADR also.
|
||||
*
|
||||
* \param [IN] verifyParams Pointer to a structure containing input parameters.
|
||||
*
|
||||
* \param [OUT] dr The updated datarate.
|
||||
*
|
||||
* \param [OUT] txPow The updated TX power.
|
||||
*
|
||||
* \param [OUT] nbRep The updated number of repetitions.
|
||||
*
|
||||
* \retval Returns the status according to the LinkAdrRequest definition.
|
||||
*/
|
||||
uint8_t RegionCommonLinkAdrReqVerifyParams( RegionCommonLinkAdrReqVerifyParams_t* verifyParams, int8_t* dr, int8_t* txPow, uint8_t* nbRep );
|
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for LoRa modulation.
|
||||
*
|
||||
* \param [IN] phyDr Physical datarate to use.
|
||||
*
|
||||
* \param [IN] bandwidth Bandwidth to use.
|
||||
*
|
||||
* \retval Returns the symbol time.
|
||||
*/
|
||||
double RegionCommonComputeSymbolTimeLoRa( uint8_t phyDr, uint32_t bandwidth );
|
||||
|
||||
/*!
|
||||
* \brief Computes the symbol time for FSK modulation.
|
||||
*
|
||||
* \param [IN] phyDr Physical datarate to use.
|
||||
*
|
||||
* \param [IN] bandwidth Bandwidth to use.
|
||||
*
|
||||
* \retval Returns the symbol time.
|
||||
*/
|
||||
double RegionCommonComputeSymbolTimeFsk( uint8_t phyDr );
|
||||
|
||||
/*!
|
||||
* \brief Computes the RX window timeout and the RX window offset.
|
||||
*
|
||||
* \param [IN] tSymbol Symbol timeout.
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms interval around RxOffset.
|
||||
*
|
||||
* \param [IN] wakeUpTime Wakeup time of the system.
|
||||
*
|
||||
* \param [OUT] windowTimeout RX window timeout.
|
||||
*
|
||||
* \param [OUT] windowOffset RX window time offset to be applied to the RX delay.
|
||||
*/
|
||||
void RegionCommonComputeRxWindowParameters( double tSymbol, uint8_t minRxSymbols, uint32_t rxError, uint32_t wakeUpTime, uint32_t* windowTimeout, int32_t* windowOffset );
|
||||
|
||||
/*!
|
||||
* \brief Computes the txPower, based on the max EIRP and the antenna gain.
|
||||
*
|
||||
* \remark US915 region uses a conducted power as input value for maxEirp.
|
||||
* Thus, the antennaGain parameter must be set to 0.
|
||||
*
|
||||
* \param [IN] txPower TX power index.
|
||||
*
|
||||
* \param [IN] maxEirp Maximum EIRP.
|
||||
*
|
||||
* \param [IN] antennaGain Antenna gain. Referenced to the isotropic antenna.
|
||||
* Value is in dBi. ( antennaGain[dBi] = measuredAntennaGain[dBd] + 2.15 )
|
||||
*
|
||||
* \retval Returns the physical TX power.
|
||||
*/
|
||||
int8_t RegionCommonComputeTxPower( int8_t txPowerIndex, float maxEirp, float antennaGain );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the duty cycle for the current band.
|
||||
*
|
||||
* \param [IN] calcBackOffParams A pointer to the input parameters.
|
||||
*/
|
||||
void RegionCommonCalcBackOff( RegionCommonCalcBackOffParams_t* calcBackOffParams );
|
||||
|
||||
/*!
|
||||
* \brief Sets up the radio into RX beacon mode.
|
||||
*
|
||||
* \param [IN] rxBeaconSetupParams A pointer to the input parameters.
|
||||
*/
|
||||
void RegionCommonRxBeaconSetup( RegionCommonRxBeaconSetupParams_t* rxBeaconSetupParams );
|
||||
|
||||
/*! \} defgroup REGIONCOMMON */
|
||||
|
||||
#endif // __REGIONCOMMON_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,509 @@
|
|||
/*!
|
||||
* \file RegionEU433.h
|
||||
*
|
||||
* \brief Region definition for EU433
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONEU433 Region EU433
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_EU433_H__
|
||||
#define __REGION_EU433_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define EU433_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define EU433_NUMB_DEFAULT_CHANNELS 3
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define EU433_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define EU433_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define EU433_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define EU433_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define EU433_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define EU433_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU433_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU433_MAX_RX1_DR_OFFSET 5
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU433_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define EU433_MIN_TX_POWER TX_POWER_5
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define EU433_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define EU433_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define EU433_DEFAULT_MAX_EIRP 12.15f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define EU433_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define EU433_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define EU433_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define EU433_DUTY_CYCLE_ENABLED 1
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define EU433_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define EU433_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define EU433_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define EU433_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define EU433_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define EU433_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define EU433_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define EU433_ACK_TIMEOUT_RND 1000
|
||||
|
||||
/*!
|
||||
* Verification of default datarate
|
||||
*/
|
||||
#if ( EU433_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define EU433_RX_WND_2_FREQ 434665000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define EU433_RX_WND_2_DR DR_0
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define EU433_MAX_NB_BANDS 1
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define EU433_BEACON_CHANNEL_FREQ 434665000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define EU433_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define EU433_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define EU433_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define EU433_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define EU433_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define EU433_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU433_BAND0 { 100, EU433_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU433_LC1 { 433175000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU433_LC2 { 433375000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU433_LC3 { 433575000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define EU433_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesEU433[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsEU433[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateEU433[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU433[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionEU433InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionEU433GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionEU433Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU433ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionEU433ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionEU433ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionEU433RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionEU433TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU433LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU433RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU433NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionEU433TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU433DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionEU433AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU433CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionEU433ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionEU433ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU433SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionEU433ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionEU433RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONEU433 */
|
||||
|
||||
#endif // __REGION_EU433_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,536 @@
|
|||
/*!
|
||||
* \file RegionEU868.h
|
||||
*
|
||||
* \brief Region definition for EU868
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONEU868 Region EU868
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_EU868_H__
|
||||
#define __REGION_EU868_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define EU868_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define EU868_NUMB_DEFAULT_CHANNELS 3
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define EU868_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define EU868_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define EU868_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define EU868_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define EU868_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define EU868_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU868_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU868_MAX_RX1_DR_OFFSET 5
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define EU868_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define EU868_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define EU868_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define EU868_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define EU868_DEFAULT_MAX_EIRP 16.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define EU868_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define EU868_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define EU868_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define EU868_DUTY_CYCLE_ENABLED 1
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define EU868_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define EU868_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define EU868_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define EU868_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define EU868_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define EU868_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define EU868_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define EU868_ACK_TIMEOUT_RND 1000
|
||||
|
||||
#if ( EU868_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define EU868_RX_WND_2_FREQ 869525000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define EU868_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define EU868_BEACON_CHANNEL_FREQ 869525000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define EU868_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define EU868_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define EU868_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define EU868_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define EU868_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define EU868_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define EU868_MAX_NB_BANDS 6
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND0 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 1 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND1 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 2 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND2 { 1000, EU868_MAX_TX_POWER, 0, 0, 0 } // 0.1 %
|
||||
|
||||
/*!
|
||||
* Band 3 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND3 { 10 , EU868_MAX_TX_POWER, 0, 0, 0 } // 10.0 %
|
||||
|
||||
/*!
|
||||
* Band 4 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND4 { 100 , EU868_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* Band 5 definition
|
||||
* Band = { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define EU868_BAND5 { 1000, EU868_MAX_TX_POWER, 0, 0, 0 } // 0.1 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU868_LC1 { 868100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU868_LC2 { 868300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define EU868_LC3 { 868500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 1 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define EU868_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesEU868[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsEU868[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateEU868[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterEU868[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionEU868GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU868SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionEU868InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionEU868GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU868ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionEU868ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionEU868ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionEU868RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionEU868TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU868LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU868RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU868NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionEU868TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionEU868DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionEU868AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU868CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionEU868NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionEU868ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionEU868ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionEU868SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionEU868ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionEU868RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONEU868 */
|
||||
|
||||
#endif // __REGION_EU868_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,511 @@
|
|||
/*!
|
||||
* \file RegionIN865.h
|
||||
*
|
||||
* \brief Region definition for IN865
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONIN865 Region IN865
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_IN865_H__
|
||||
#define __REGION_IN865_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define IN865_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define IN865_NUMB_DEFAULT_CHANNELS 3
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define IN865_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define IN865_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define IN865_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define IN865_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define IN865_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define IN865_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define IN865_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define IN865_MAX_RX1_DR_OFFSET 7
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define IN865_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define IN865_MIN_TX_POWER TX_POWER_10
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define IN865_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define IN865_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define IN865_DEFAULT_MAX_EIRP 30.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define IN865_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define IN865_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define IN865_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define IN865_DUTY_CYCLE_ENABLED 1
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define IN865_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define IN865_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define IN865_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define IN865_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define IN865_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define IN865_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define IN865_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define IN865_ACK_TIMEOUT_RND 1000
|
||||
|
||||
#if ( IN865_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define IN865_RX_WND_2_FREQ 866550000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define IN865_RX_WND_2_DR DR_2
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define IN865_BEACON_CHANNEL_FREQ 866550000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define IN865_BEACON_SIZE 19
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define IN865_RFU1_SIZE 1
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define IN865_RFU2_SIZE 3
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define IN865_BEACON_CHANNEL_DR DR_4
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define IN865_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define IN865_PING_SLOT_CHANNEL_DR DR_4
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define IN865_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define IN865_BAND0 { 1 , IN865_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define IN865_LC1 { 865062500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define IN865_LC2 { 865402500, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define IN865_LC3 { 865985000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define IN865_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesIN865[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsIN865[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateIN865[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterIN865[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* Effective datarate offsets for receive window 1.
|
||||
*/
|
||||
static const int8_t EffectiveRx1DrOffsetIN865[] = { 0, 1, 2, 3, 4, 5, -1, -2 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionIN865GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionIN865SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionIN865InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionIN865GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionIN865Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionIN865ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionIN865ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionIN865ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionIN865RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionIN865TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionIN865LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionIN865RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionIN865NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionIN865TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionIN865DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionIN865AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionIN865CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionIN865NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionIN865ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionIN865ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionIN865SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionIN865ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionIN865RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONIN865 */
|
||||
|
||||
#endif // __REGION_IN865_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,521 @@
|
|||
/*!
|
||||
* \file RegionKR920.h
|
||||
*
|
||||
* \brief Region definition for KR920
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONKR920 Region KR920
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_KR920_H__
|
||||
#define __REGION_KR920_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define KR920_MAX_NB_CHANNELS 16
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define KR920_NUMB_DEFAULT_CHANNELS 3
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define KR920_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define KR920_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define KR920_TX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define KR920_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define KR920_RX_MAX_DATARATE DR_5
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define KR920_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define KR920_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define KR920_MAX_RX1_DR_OFFSET 5
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define KR920_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define KR920_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define KR920_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define KR920_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP for frequency 920.9 MHz - 921.9 MHz
|
||||
*/
|
||||
#define KR920_DEFAULT_MAX_EIRP_LOW 10.0f
|
||||
|
||||
/*!
|
||||
* Default Max EIRP for frequency 922.1 MHz - 923.3 MHz
|
||||
*/
|
||||
#define KR920_DEFAULT_MAX_EIRP_HIGH 14.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define KR920_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define KR920_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define KR920_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define KR920_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define KR920_MAX_RX_WINDOW 4000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define KR920_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define KR920_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define KR920_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define KR920_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define KR920_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define KR920_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define KR920_ACK_TIMEOUT_RND 1000
|
||||
|
||||
#if ( KR920_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define KR920_RX_WND_2_FREQ 921900000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define KR920_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define KR920_BEACON_CHANNEL_FREQ 923100000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define KR920_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define KR920_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define KR920_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define KR920_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define KR920_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define KR920_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define KR920_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define KR920_BAND0 { 1 , KR920_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define KR920_LC1 { 922100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define KR920_LC2 { 922300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 3
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define KR920_LC3 { 922500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define KR920_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) | LC( 3 ) )
|
||||
|
||||
/*!
|
||||
* RSSI threshold for a free channel [dBm]
|
||||
*/
|
||||
#define KR920_RSSI_FREE_TH -65
|
||||
|
||||
/*!
|
||||
* Specifies the time the node performs a carrier sense
|
||||
*/
|
||||
#define KR920_CARRIER_SENSE_TIME 6
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesKR920[] = { 12, 11, 10, 9, 8, 7 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsKR920[] = { 125000, 125000, 125000, 125000, 125000, 125000 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with and without a repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateKR920[] = { 51, 51, 51, 115, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterKR920[] = { 51, 51, 51, 115, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionKR920GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionKR920SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionKR920InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionKR920GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionKR920Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionKR920ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionKR920ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionKR920ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionKR920RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionKR920TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionKR920LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionKR920RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionKR920NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionKR920TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionKR920DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionKR920AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionKR920CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionKR920NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionKR920ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionKR920ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionKR920SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionKR920ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionKR920RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONKR920 */
|
||||
|
||||
#endif // __REGION_KR920_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,500 @@
|
|||
/*!
|
||||
* \file RegionRU864.h
|
||||
*
|
||||
* \brief Region definition for RU864
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONRU864 Region RU864
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_RU864_H__
|
||||
#define __REGION_RU864_H__
|
||||
|
||||
#include "LoRaMac.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define RU864_MAX_NB_CHANNELS 8
|
||||
|
||||
/*!
|
||||
* Number of default channels
|
||||
*/
|
||||
#define RU864_NUMB_DEFAULT_CHANNELS 2
|
||||
|
||||
/*!
|
||||
* Number of channels to apply for the CF list
|
||||
*/
|
||||
#define RU864_NUMB_CHANNELS_CF_LIST 5
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define RU864_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define RU864_TX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define RU864_RX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define RU864_RX_MAX_DATARATE DR_7
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define RU864_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define RU864_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define RU864_MAX_RX1_DR_OFFSET 5
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define RU864_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#define RU864_MIN_TX_POWER TX_POWER_7
|
||||
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define RU864_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define RU864_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max EIRP
|
||||
*/
|
||||
#define RU864_DEFAULT_MAX_EIRP 16.0f
|
||||
|
||||
/*!
|
||||
* Default antenna gain
|
||||
*/
|
||||
#define RU864_DEFAULT_ANTENNA_GAIN 2.15f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define RU864_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define RU864_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define RU864_DUTY_CYCLE_ENABLED 1
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define RU864_MAX_RX_WINDOW 3000 //TODO
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define RU864_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define RU864_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define RU864_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define RU864_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define RU864_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define RU864_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define RU864_ACK_TIMEOUT_RND 1000
|
||||
|
||||
#if ( RU864_DEFAULT_DATARATE > DR_5 )
|
||||
#error "A default DR higher than DR_5 may lead to connectivity loss."
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define RU864_RX_WND_2_FREQ 869100000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define RU864_RX_WND_2_DR DR_0
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define RU864_BEACON_CHANNEL_FREQ 869100000
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define RU864_BEACON_SIZE 17
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define RU864_RFU1_SIZE 2
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define RU864_RFU2_SIZE 0
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define RU864_BEACON_CHANNEL_DR DR_3
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel (Index of BandwidthsRU864[])
|
||||
*/
|
||||
#define RU864_BEACON_CHANNEL_BW 0
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define RU864_PING_SLOT_CHANNEL_DR DR_3
|
||||
|
||||
|
||||
/*!
|
||||
* Maximum number of bands
|
||||
*/
|
||||
#define RU864_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define RU864_BAND0 { 100 , RU864_MAX_TX_POWER, 0, 0, 0 } // 1.0 %
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 1
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define RU864_LC1 { 868900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
/*!
|
||||
* LoRaMac default channel 2
|
||||
* Channel = { Frequency [Hz], RX1 Frequency [Hz], { ( ( DrMax << 4 ) | DrMin ) }, Band }
|
||||
*/
|
||||
#define RU864_LC2 { 869100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||
|
||||
|
||||
/*!
|
||||
* LoRaMac channels which are allowed for the join procedure
|
||||
*/
|
||||
#define RU864_JOIN_CHANNELS ( uint16_t )( LC( 1 ) | LC( 2 ) )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesRU864[] = { 12, 11, 10, 9, 8, 7, 7, 50 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsRU864[] = { 125000, 125000, 125000, 125000, 125000, 125000, 250000, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRU864[] = { 51, 51, 51, 115, 242, 242, 242, 242 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterRU864[] = { 51, 51, 51, 115, 222, 222, 222, 222 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionRU864GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionRU864SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionRU864InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionRU864GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionRU864Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionRU864ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionRU864ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionRU864ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionRU864RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionRU864TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionRU864LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionRU864RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionRU864NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionRU864TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionRU864DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionRU864AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionRU864CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionRU864NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionRU864ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionRU864ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionRU864SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionRU864ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionRU864RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONRU864 */
|
||||
|
||||
#endif // __REGION_RU864_H__
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,506 @@
|
|||
/*!
|
||||
* \file RegionUS915.h
|
||||
*
|
||||
* \brief Region definition for US915
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013-2017 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup REGIONUS915 Region US915
|
||||
* Implementation according to LoRaWAN Specification v1.0.2.
|
||||
* \{
|
||||
*/
|
||||
#ifndef __REGION_US915_H__
|
||||
#define __REGION_US915_H__
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of channels
|
||||
*/
|
||||
#define US915_MAX_NB_CHANNELS 72
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define US915_TX_MIN_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define US915_TX_MAX_DATARATE DR_4
|
||||
|
||||
/*!
|
||||
* Minimal datarate that can be used by the node
|
||||
*/
|
||||
#define US915_RX_MIN_DATARATE DR_8
|
||||
|
||||
/*!
|
||||
* Maximal datarate that can be used by the node
|
||||
*/
|
||||
#define US915_RX_MAX_DATARATE DR_13
|
||||
|
||||
/*!
|
||||
* Default datarate used by the node
|
||||
*/
|
||||
#define US915_DEFAULT_DATARATE DR_0
|
||||
|
||||
/*!
|
||||
* Minimal Rx1 receive datarate offset
|
||||
*/
|
||||
#define US915_MIN_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Maximal Rx1 receive datarate offset
|
||||
*/
|
||||
#define US915_MAX_RX1_DR_OFFSET 3
|
||||
|
||||
/*!
|
||||
* Default Rx1 receive datarate offset
|
||||
*/
|
||||
#define US915_DEFAULT_RX1_DR_OFFSET 0
|
||||
|
||||
/*!
|
||||
* Minimal Tx output power that can be used by the node
|
||||
*/
|
||||
#if (defined(CERTIF_LORAWAN_VERSION) &&(CERTIF_LORAWAN_VERSION == 103))
|
||||
#define US915_MIN_TX_POWER TX_POWER_14
|
||||
#else
|
||||
#define US915_MIN_TX_POWER TX_POWER_10
|
||||
#endif
|
||||
/*!
|
||||
* Maximal Tx output power that can be used by the node
|
||||
*/
|
||||
#define US915_MAX_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Tx output power used by the node
|
||||
*/
|
||||
#define US915_DEFAULT_TX_POWER TX_POWER_0
|
||||
|
||||
/*!
|
||||
* Default Max ERP
|
||||
*/
|
||||
#define US915_DEFAULT_MAX_ERP 30.0f
|
||||
|
||||
/*!
|
||||
* ADR Ack limit
|
||||
*/
|
||||
#define US915_ADR_ACK_LIMIT 64
|
||||
|
||||
/*!
|
||||
* ADR Ack delay
|
||||
*/
|
||||
#define US915_ADR_ACK_DELAY 32
|
||||
|
||||
/*!
|
||||
* Enabled or disabled the duty cycle
|
||||
*/
|
||||
#define US915_DUTY_CYCLE_ENABLED 0
|
||||
|
||||
/*!
|
||||
* Maximum RX window duration
|
||||
*/
|
||||
#define US915_MAX_RX_WINDOW 3000
|
||||
|
||||
/*!
|
||||
* Receive delay 1
|
||||
*/
|
||||
#define US915_RECEIVE_DELAY1 1000
|
||||
|
||||
/*!
|
||||
* Receive delay 2
|
||||
*/
|
||||
#define US915_RECEIVE_DELAY2 2000
|
||||
|
||||
/*!
|
||||
* Join accept delay 1
|
||||
*/
|
||||
#define US915_JOIN_ACCEPT_DELAY1 5000
|
||||
|
||||
/*!
|
||||
* Join accept delay 2
|
||||
*/
|
||||
#define US915_JOIN_ACCEPT_DELAY2 6000
|
||||
|
||||
/*!
|
||||
* Maximum frame counter gap
|
||||
*/
|
||||
#define US915_MAX_FCNT_GAP 16384
|
||||
|
||||
/*!
|
||||
* Ack timeout
|
||||
*/
|
||||
#define US915_ACKTIMEOUT 2000
|
||||
|
||||
/*!
|
||||
* Random ack timeout limits
|
||||
*/
|
||||
#define US915_ACK_TIMEOUT_RND 1000
|
||||
|
||||
/*!
|
||||
* Second reception window channel frequency definition.
|
||||
*/
|
||||
#define US915_RX_WND_2_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Second reception window channel datarate definition.
|
||||
*/
|
||||
#define US915_RX_WND_2_DR DR_8
|
||||
|
||||
/*
|
||||
* CLASS B
|
||||
*/
|
||||
/*!
|
||||
* Beacon frequency
|
||||
*/
|
||||
#define US915_BEACON_CHANNEL_FREQ 923300000
|
||||
|
||||
/*!
|
||||
* Beacon frequency channel stepwidth
|
||||
*/
|
||||
#define US915_BEACON_CHANNEL_STEPWIDTH 600000
|
||||
|
||||
/*!
|
||||
* Number of possible beacon channels
|
||||
*/
|
||||
#define US915_BEACON_NB_CHANNELS 8
|
||||
|
||||
/*!
|
||||
* Payload size of a beacon frame
|
||||
*/
|
||||
#define US915_BEACON_SIZE 23
|
||||
|
||||
/*!
|
||||
* Size of RFU 1 field
|
||||
*/
|
||||
#define US915_RFU1_SIZE 5
|
||||
|
||||
/*!
|
||||
* Size of RFU 2 field
|
||||
*/
|
||||
#define US915_RFU2_SIZE 3
|
||||
|
||||
/*!
|
||||
* Datarate of the beacon channel
|
||||
*/
|
||||
#define US915_BEACON_CHANNEL_DR DR_8
|
||||
|
||||
/*!
|
||||
* Bandwith of the beacon channel
|
||||
*/
|
||||
#define US915_BEACON_CHANNEL_BW 2
|
||||
|
||||
/*!
|
||||
* Ping slot channel datarate
|
||||
*/
|
||||
#define US915_PING_SLOT_CHANNEL_DR DR_8
|
||||
|
||||
/*!
|
||||
* LoRaMac maximum number of bands
|
||||
*/
|
||||
#define US915_MAX_NB_BANDS 1
|
||||
|
||||
/*!
|
||||
* Band 0 definition
|
||||
* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }
|
||||
*/
|
||||
#define US915_BAND0 { 1, US915_MAX_TX_POWER, 0, 0, 0 } // 100.0 %
|
||||
|
||||
/*!
|
||||
* Defines the first channel for RX window 1 for US band
|
||||
*/
|
||||
#define US915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 )
|
||||
|
||||
/*!
|
||||
* Defines the last channel for RX window 1 for US band
|
||||
*/
|
||||
#define US915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 )
|
||||
|
||||
/*!
|
||||
* Defines the step width of the channels for RX window 1
|
||||
*/
|
||||
#define US915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 )
|
||||
|
||||
/*!
|
||||
* Data rates table definition
|
||||
*/
|
||||
static const uint8_t DataratesUS915[] = { 10, 9, 8, 7, 8, 0, 0, 0, 12, 11, 10, 9, 8, 7, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Bandwidths table definition in Hz
|
||||
*/
|
||||
static const uint32_t BandwidthsUS915[] = { 125000, 125000, 125000, 125000, 500000, 0, 0, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Up/Down link data rates offset definition
|
||||
*/
|
||||
static const int8_t DatarateOffsetsUS915[5][4] =
|
||||
{
|
||||
{ DR_10, DR_9 , DR_8 , DR_8 }, // DR_0
|
||||
{ DR_11, DR_10, DR_9 , DR_8 }, // DR_1
|
||||
{ DR_12, DR_11, DR_10, DR_9 }, // DR_2
|
||||
{ DR_13, DR_12, DR_11, DR_10 }, // DR_3
|
||||
{ DR_13, DR_13, DR_12, DR_11 }, // DR_4
|
||||
};
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Cannot operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 53, 129, 242, 242, 242, 242, 0, 0 };
|
||||
|
||||
/*!
|
||||
* Maximum payload with respect to the datarate index. Can operate with repeater.
|
||||
*/
|
||||
static const uint8_t MaxPayloadOfDatarateRepeaterUS915[] = { 11, 53, 125, 242, 242, 0, 0, 0, 33, 109, 222, 222, 222, 222, 0, 0 };
|
||||
|
||||
/*!
|
||||
* \brief The function gets a value of a specific phy attribute.
|
||||
*
|
||||
* \param [IN] getPhy Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns a structure containing the PHY parameter.
|
||||
*/
|
||||
PhyParam_t RegionUS915GetPhyParam( GetPhyParams_t* getPhy );
|
||||
|
||||
/*!
|
||||
* \brief Updates the last TX done parameters of the current channel.
|
||||
*
|
||||
* \param [IN] txDone Pointer to the function parameters.
|
||||
*/
|
||||
void RegionUS915SetBandTxDone( SetBandTxDoneParams_t* txDone );
|
||||
|
||||
/*!
|
||||
* \brief Initializes the channels masks and the channels.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*/
|
||||
void RegionUS915InitDefaults( InitDefaultsParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to the internal context and its size.
|
||||
*
|
||||
* \param [OUT] params Pointer to the function parameters.
|
||||
*
|
||||
* \retval Points to a structure where the module store its non-volatile context.
|
||||
*/
|
||||
void* RegionUS915GetNvmCtx( GetNvmCtxParams_t* params );
|
||||
|
||||
/*!
|
||||
* \brief Verifies a parameter.
|
||||
*
|
||||
* \param [IN] verify Pointer to the function parameters.
|
||||
*
|
||||
* \param [IN] type Sets the initialization type.
|
||||
*
|
||||
* \retval Returns true, if the parameter is valid.
|
||||
*/
|
||||
bool RegionUS915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );
|
||||
|
||||
/*!
|
||||
* \brief The function parses the input buffer and sets up the channels of the
|
||||
* CF list.
|
||||
*
|
||||
* \param [IN] applyCFList Pointer to the function parameters.
|
||||
*/
|
||||
void RegionUS915ApplyCFList( ApplyCFListParams_t* applyCFList );
|
||||
|
||||
/*!
|
||||
* \brief Sets a channels mask.
|
||||
*
|
||||
* \param [IN] chanMaskSet Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channels mask could be set.
|
||||
*/
|
||||
bool RegionUS915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );
|
||||
|
||||
/*!
|
||||
* Computes the Rx window timeout and offset.
|
||||
*
|
||||
* \param [IN] datarate Rx window datarate index to be used
|
||||
*
|
||||
* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.
|
||||
*
|
||||
* \param [IN] rxError System maximum timing error of the receiver. In milliseconds
|
||||
* The receiver will turn on in a [-rxError : +rxError] ms
|
||||
* interval around RxOffset
|
||||
*
|
||||
* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.
|
||||
*/
|
||||
void RegionUS915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );
|
||||
|
||||
/*!
|
||||
* \brief Configuration of the RX windows.
|
||||
*
|
||||
* \param [IN] rxConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] datarate The datarate index which was set.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );
|
||||
|
||||
/*!
|
||||
* \brief TX configuration.
|
||||
*
|
||||
* \param [IN] txConfig Pointer to the function parameters.
|
||||
*
|
||||
* \param [OUT] txPower The tx power index which was set.
|
||||
*
|
||||
* \param [OUT] txTimeOnAir The time-on-air of the frame.
|
||||
*
|
||||
* \retval Returns true, if the configuration was applied successfully.
|
||||
*/
|
||||
bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Link ADR Request.
|
||||
*
|
||||
* \param [IN] linkAdrReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionUS915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a RX Parameter Setup Request.
|
||||
*
|
||||
* \param [IN] rxParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionUS915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a Channel Request.
|
||||
*
|
||||
* \param [IN] newChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionUS915NewChannelReq( NewChannelReqParams_t* newChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a TX ParamSetup Request.
|
||||
*
|
||||
* \param [IN] txParamSetupReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
* Returns -1, if the functionality is not implemented. In this case, the end node
|
||||
* shall not process the command.
|
||||
*/
|
||||
int8_t RegionUS915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );
|
||||
|
||||
/*!
|
||||
* \brief The function processes a DlChannel Request.
|
||||
*
|
||||
* \param [IN] dlChannelReq Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns the status of the operation, according to the LoRaMAC specification.
|
||||
*/
|
||||
uint8_t RegionUS915DlChannelReq( DlChannelReqParams_t* dlChannelReq );
|
||||
|
||||
/*!
|
||||
* \brief Alternates the datarate of the channel for the join request.
|
||||
*
|
||||
* \param [IN] currentDr Current datarate.
|
||||
*
|
||||
* \param [IN] type Alternation type.
|
||||
*
|
||||
* \retval Datarate to apply.
|
||||
*/
|
||||
int8_t RegionUS915AlternateDr( int8_t currentDr, AlternateDrType_t type );
|
||||
|
||||
/*!
|
||||
* \brief Calculates the back-off time.
|
||||
*
|
||||
* \param [IN] calcBackOff Pointer to the function parameters.
|
||||
*/
|
||||
void RegionUS915CalcBackOff( CalcBackOffParams_t* calcBackOff );
|
||||
|
||||
/*!
|
||||
* \brief Searches and set the next random available channel
|
||||
*
|
||||
* \param [OUT] channel Next channel to use for TX.
|
||||
*
|
||||
* \param [OUT] time Time to wait for the next transmission according to the duty
|
||||
* cycle.
|
||||
*
|
||||
* \param [OUT] aggregatedTimeOff Updates the aggregated time off.
|
||||
*
|
||||
* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]
|
||||
*/
|
||||
LoRaMacStatus_t RegionUS915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );
|
||||
|
||||
/*!
|
||||
* \brief Adds a channel.
|
||||
*
|
||||
* \param [IN] channelAdd Pointer to the function parameters.
|
||||
*
|
||||
* \retval Status of the operation.
|
||||
*/
|
||||
LoRaMacStatus_t RegionUS915ChannelAdd( ChannelAddParams_t* channelAdd );
|
||||
|
||||
/*!
|
||||
* \brief Removes a channel.
|
||||
*
|
||||
* \param [IN] channelRemove Pointer to the function parameters.
|
||||
*
|
||||
* \retval Returns true, if the channel was removed successfully.
|
||||
*/
|
||||
bool RegionUS915ChannelsRemove( ChannelRemoveParams_t* channelRemove );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into continuous wave mode.
|
||||
*
|
||||
* \param [IN] continuousWave Pointer to the function parameters.
|
||||
*/
|
||||
void RegionUS915SetContinuousWave( ContinuousWaveParams_t* continuousWave );
|
||||
|
||||
/*!
|
||||
* \brief Computes new datarate according to the given offset
|
||||
*
|
||||
* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms
|
||||
*
|
||||
* \param [IN] dr Current datarate
|
||||
*
|
||||
* \param [IN] drOffset Offset to be applied
|
||||
*
|
||||
* \retval newDr Computed datarate.
|
||||
*/
|
||||
uint8_t RegionUS915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );
|
||||
|
||||
/*!
|
||||
* \brief Sets the radio into beacon reception mode
|
||||
*
|
||||
* \param [IN] rxBeaconSetup Pointer to the function parameters
|
||||
*/
|
||||
void RegionUS915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );
|
||||
|
||||
/*! \} defgroup REGIONUS915 */
|
||||
|
||||
#endif // __REGION_US915_H__
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*!
|
||||
* \file secure-element.h
|
||||
*
|
||||
* \brief Secure Element driver API
|
||||
*
|
||||
* \copyright Revised BSD License, see section \ref LICENSE.
|
||||
*
|
||||
* \code
|
||||
* ______ _
|
||||
* / _____) _ | |
|
||||
* ( (____ _____ ____ _| |_ _____ ____| |__
|
||||
* \____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
* _____) ) ____| | | || |_| ____( (___| | | |
|
||||
* (______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
* (C)2013 Semtech
|
||||
*
|
||||
* ___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
* embedded.connectivity.solutions===============
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \author Miguel Luis ( Semtech )
|
||||
*
|
||||
* \author Gregory Cristian ( Semtech )
|
||||
*
|
||||
* \author Daniel Jaeckle ( STACKFORCE )
|
||||
*
|
||||
* \author Johannes Bruder ( STACKFORCE )
|
||||
*
|
||||
* \defgroup SECUREELEMENT Secure Element API Definition
|
||||
*
|
||||
* \{
|
||||
*
|
||||
*/
|
||||
#ifndef __SECURE_ELEMENT_H__
|
||||
#define __SECURE_ELEMENT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "LoRaMacCrypto.h"
|
||||
|
||||
#define SE_EUI_SIZE 16
|
||||
|
||||
/*!
|
||||
* Return values.
|
||||
*/
|
||||
typedef enum eSecureElementStatus
|
||||
{
|
||||
/*!
|
||||
* No error occurred
|
||||
*/
|
||||
SECURE_ELEMENT_SUCCESS = 0,
|
||||
/*!
|
||||
* CMAC does not match
|
||||
*/
|
||||
SECURE_ELEMENT_FAIL_CMAC,
|
||||
/*!
|
||||
* Null pointer exception
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR_NPE,
|
||||
/*!
|
||||
* Invalid key identifier exception
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR_INVALID_KEY_ID,
|
||||
/*!
|
||||
* Invalid LoRaWAN specification version
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR_INVALID_LORAWAM_SPEC_VERSION,
|
||||
/*!
|
||||
* Incompatible buffer size
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR_BUF_SIZE,
|
||||
/*!
|
||||
* Undefined Error occurred
|
||||
*/
|
||||
SECURE_ELEMENT_ERROR,
|
||||
}SecureElementStatus_t;
|
||||
|
||||
/*!
|
||||
* Signature of callback function to be called by the Secure Element driver when the
|
||||
* non volatile context have to be stored.
|
||||
*
|
||||
*/
|
||||
typedef void ( *SecureElementNvmEvent )( void );
|
||||
|
||||
/*!
|
||||
* Initialization of Secure Element driver
|
||||
*
|
||||
* \param[IN] seNvmCtxChanged - Callback function which will be called when the
|
||||
* non-volatile context have to be stored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementInit( SecureElementNvmEvent seNvmCtxChanged );
|
||||
|
||||
/*!
|
||||
* Restores the internal nvm context from passed pointer.
|
||||
*
|
||||
* \param[IN] seNvmCtx - Pointer to non-volatile module context to be restored.
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementRestoreNvmCtx( void* seNvmCtx );
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal non-volatile context.
|
||||
*
|
||||
* \param[IN] seNvmCtxSize - Size of the module non volatile context
|
||||
* \retval - Points to a structure where the module store its non volatile context
|
||||
*/
|
||||
void* SecureElementGetNvmCtx( size_t* seNvmCtxSize );
|
||||
|
||||
/*!
|
||||
* Sets a key
|
||||
*
|
||||
* \param[IN] keyID - Key identifier
|
||||
* \param[IN] key - Key value
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetKey( KeyIdentifier_t keyID, uint8_t* key );
|
||||
|
||||
/*!
|
||||
* Computes a CMAC of a message using provided initial Bx block
|
||||
*
|
||||
* \param[IN] micBxBuffer - Buffer containing the initial Bx block
|
||||
* \param[IN] buffer - Data buffer
|
||||
* \param[IN] size - Data buffer size
|
||||
* \param[IN] keyID - Key identifier to determine the AES key to be used
|
||||
* \param[OUT] cmac - Computed cmac
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementComputeAesCmac( uint8_t* micBxBuffer, uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint32_t* cmac );
|
||||
|
||||
/*!
|
||||
* Verifies a CMAC (computes and compare with expected cmac)
|
||||
*
|
||||
* \param[IN] buffer - Data buffer
|
||||
* \param[IN] size - Data buffer size
|
||||
* \param[in] expectedCmac - Expected cmac
|
||||
* \param[IN] keyID - Key identifier to determine the AES key to be used
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementVerifyAesCmac( uint8_t* buffer, uint16_t size, uint32_t expectedCmac, KeyIdentifier_t keyID );
|
||||
|
||||
/*!
|
||||
* Encrypt a buffer
|
||||
*
|
||||
* \param[IN] buffer - Data buffer
|
||||
* \param[IN] size - Data buffer size
|
||||
* \param[IN] keyID - Key identifier to determine the AES key to be used
|
||||
* \param[OUT] encBuffer - Encrypted buffer
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, KeyIdentifier_t keyID, uint8_t* encBuffer );
|
||||
|
||||
/*!
|
||||
* Derives and store a key
|
||||
*
|
||||
* \param[IN] version - LoRaWAN specification version currently in use.
|
||||
* \param[IN] input - Input data from which the key is derived ( 16 byte )
|
||||
* \param[IN] rootKeyID - Key identifier of the root key to use to perform the derivation
|
||||
* \param[IN] targetKeyID - Key identifier of the key which will be derived
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID );
|
||||
|
||||
/*!
|
||||
* Generates a random number
|
||||
*
|
||||
* \param[OUT] randomNum - 32 bit random number
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementRandomNumber( uint32_t* randomNum );
|
||||
|
||||
/*!
|
||||
* Sets the DevEUI
|
||||
*
|
||||
* \param[IN] devEui - Pointer to the 16-byte devEUI
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetDevEui( uint8_t* devEui );
|
||||
|
||||
/*!
|
||||
* Gets the DevEUI
|
||||
*
|
||||
* \retval - Pointer to the 16-byte devEUI
|
||||
*/
|
||||
uint8_t* SecureElementGetDevEui( void );
|
||||
|
||||
/*!
|
||||
* Sets the JoinEUI
|
||||
*
|
||||
* \param[IN] joinEui - Pointer to the 16-byte joinEui
|
||||
* \retval - Status of the operation
|
||||
*/
|
||||
SecureElementStatus_t SecureElementSetJoinEui( uint8_t* joinEui );
|
||||
|
||||
/*!
|
||||
* Gets the DevEUI
|
||||
*
|
||||
* \retval - Pointer to the 16-byte joinEui
|
||||
*/
|
||||
uint8_t* SecureElementGetJoinEui( void );
|
||||
|
||||
/*! \} defgroup SECUREELEMENT */
|
||||
|
||||
#endif // __SECURE_ELEMENT_H__
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file app_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief applic configuration, e.g. : debug, trace, low power, sensors
|
||||
* @note this is a template: the app_conf.h shall be defined in the Project/...
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __APP_CONF_H__
|
||||
#define __APP_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* LoraWAN application configuration (Mw is configured by lorawan_conf.h) */
|
||||
#define ACTIVE_REGION LORAMAC_REGION_EU868
|
||||
#define HYBRID_ENABLED 0
|
||||
|
||||
#define LORAMAC_CLASSB_ACTIVE 0 /* 0 if not active, 1 if active */
|
||||
|
||||
/* Enable trace logs. Note verbose level can be selected in app_system.h */
|
||||
#define APP_LOG_ENABLED 1
|
||||
|
||||
#define DEBUGGER_ON 0 /* if ON (=1) it enables the debbugger plus 4 dgb pins */
|
||||
/* if OFF (=0) the debugger is OFF (lower consumption) */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_CONF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file app_system_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief function prototypes for app_system.c file
|
||||
* @note this is a template: the app_conf.h shall be defined in the Project/...
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __APP_SYSTEM_H__
|
||||
#define __APP_SYSTEM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include "app_conf.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define VERBOSE_LEVEL VLEVEL_L
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
#define APP_PPRINTF(...) do{ } while( 0!= TraceSend(0, 0, __VA_ARGS__) ) //Polling Mode
|
||||
#define APP_TPRINTF(...) do{ {TraceSend(1, 0, __VA_ARGS__);} }while(0); //with timestamp
|
||||
#define APP_PRINTF(...) do{ {TraceSend(0, 0, __VA_ARGS__);} }while(0);
|
||||
|
||||
|
||||
#if defined (APP_LOG_ENABLED) && (APP_LOG_ENABLED == 1)
|
||||
#define APP_LOG(TS,VL,...) do{ {TraceSend(TS, VL, __VA_ARGS__);} }while(0);
|
||||
#elif defined (APP_LOG_ENABLED) && (APP_LOG_ENABLED == 0) /* APP_LOG disabled */
|
||||
#define APP_LOG(TS,VL,...)
|
||||
#else
|
||||
#error "APP_LOG_ENABLED not defined or out of range <0,1>"
|
||||
#endif
|
||||
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_SYSTEM_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,433 @@
|
|||
/******************************************************************************
|
||||
* @file lora-test.c
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stddef.h"
|
||||
//#include "lorawan_conf.h" /* Don't remove: needed for LORAMAC_CLASSB_ENABLED */
|
||||
//#include "mw_log_conf.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "LoRaMacTest.h"
|
||||
#include "lora.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
typedef struct ComplianceTest_s
|
||||
{
|
||||
bool Running;
|
||||
uint8_t State;
|
||||
LoraConfirm_t IsTxConfirmed;
|
||||
uint8_t DataBufferSize;
|
||||
uint8_t DataBuffer[242]; /* max possible payload */
|
||||
uint16_t DownLinkCounter;
|
||||
bool LinkCheck;
|
||||
uint8_t DemodMargin;
|
||||
uint8_t NbGateways;
|
||||
} ComplianceTest_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CERTIF_TX_PROCESS = 0,
|
||||
CERTIF_RX_PROCESS
|
||||
} requestProcess_t;
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define TEST_TX_DUTYCYCLE 5000
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
|
||||
static requestProcess_t requested_process_id;
|
||||
|
||||
/*!
|
||||
* Timer to handle the application data transmission duty cycle
|
||||
*/
|
||||
static TimerEvent_t CertifTxNextPacketTimer;
|
||||
|
||||
static ComplianceTest_t certifParam;
|
||||
static LoraConfirm_t IsTxConfirmed;
|
||||
static bool AdrEnableInit;
|
||||
static McpsIndication_t *CertifMcpsIndication;
|
||||
static MlmeReqJoin_t *CertifJoinParameters;
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static bool CERTIF_running(void);
|
||||
|
||||
static void CERTIF_DownLinkIncrement(void);
|
||||
|
||||
static void CERTIF_linkCheck(MlmeConfirm_t *mlmeConfirm);
|
||||
|
||||
static void CERTIF_rx_request(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
static void CERTIF_rx(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
static bool CERTIF_tx(void);
|
||||
|
||||
static void OnCertifTxNextPacketTimerEvent(void *context);
|
||||
|
||||
static void (*CertifProcessNotify)(void);
|
||||
|
||||
static LoRaCertifCallback_t certifCb =
|
||||
{
|
||||
CERTIF_running,
|
||||
CERTIF_DownLinkIncrement,
|
||||
CERTIF_linkCheck,
|
||||
CERTIF_rx_request,
|
||||
};
|
||||
|
||||
/* Exported functions definition---------------------------------------------------------*/
|
||||
|
||||
void CERTIF_Init(void (*CERTIF_ProcessNotify)(void))
|
||||
{
|
||||
/*initialises Callback into the Lora.c layer*/
|
||||
LORA_TestInit(&certifCb);
|
||||
/*Register TestProcessNotify callback*/
|
||||
CertifProcessNotify = CERTIF_ProcessNotify;
|
||||
}
|
||||
|
||||
void CERTIF_Process(void)
|
||||
{
|
||||
switch (requested_process_id)
|
||||
{
|
||||
case CERTIF_TX_PROCESS:
|
||||
CERTIF_tx();
|
||||
break;
|
||||
case CERTIF_RX_PROCESS:
|
||||
CERTIF_rx(CertifMcpsIndication, CertifJoinParameters);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static bool CERTIF_running(void)
|
||||
{
|
||||
return certifParam.Running;
|
||||
}
|
||||
|
||||
static void CERTIF_DownLinkIncrement(void)
|
||||
{
|
||||
certifParam.DownLinkCounter++;
|
||||
}
|
||||
|
||||
static void CERTIF_linkCheck(MlmeConfirm_t *mlmeConfirm)
|
||||
{
|
||||
certifParam.LinkCheck = true;
|
||||
certifParam.DemodMargin = mlmeConfirm->DemodMargin;
|
||||
certifParam.NbGateways = mlmeConfirm->NbGateways;
|
||||
}
|
||||
|
||||
static bool CERTIF_tx(void)
|
||||
{
|
||||
McpsReq_t mcpsReq;
|
||||
LoRaMacTxInfo_t txInfo;
|
||||
#if (ACTIVE_REGION == LORAMAC_REGION_US915)
|
||||
bool abortTx = false;
|
||||
#endif /* ACTIVE_REGION == LORAMAC_REGION_US915 */
|
||||
|
||||
if (certifParam.LinkCheck == true)
|
||||
{
|
||||
certifParam.LinkCheck = false;
|
||||
certifParam.DataBufferSize = 3;
|
||||
certifParam.DataBuffer[0] = 5;
|
||||
certifParam.DataBuffer[1] = certifParam.DemodMargin;
|
||||
certifParam.DataBuffer[2] = certifParam.NbGateways;
|
||||
certifParam.State = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (certifParam.State)
|
||||
{
|
||||
case 4:
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 1:
|
||||
certifParam.DataBufferSize = 2;
|
||||
certifParam.DataBuffer[0] = certifParam.DownLinkCounter >> 8;
|
||||
certifParam.DataBuffer[1] = certifParam.DownLinkCounter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (LoRaMacQueryTxPossible(certifParam.DataBufferSize, &txInfo) != LORAMAC_STATUS_OK)
|
||||
{
|
||||
#if (ACTIVE_REGION == LORAMAC_REGION_US915)
|
||||
abortTx = true; /* Do not send empty frame as some testers do not support it */
|
||||
#else
|
||||
// Send empty frame in order to flush MAC commands
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
|
||||
mcpsReq.Req.Unconfirmed.Datarate = DR_0;
|
||||
#endif /* ACTIVE_REGION == LORAMAC_REGION_US915 */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsTxConfirmed == LORAWAN_UNCONFIRMED_MSG)
|
||||
{
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fPort = CERTIF_PORT;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = certifParam.DataBufferSize;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = &(certifParam.DataBuffer);
|
||||
mcpsReq.Req.Unconfirmed.Datarate = DR_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcpsReq.Type = MCPS_CONFIRMED;
|
||||
mcpsReq.Req.Confirmed.fPort = CERTIF_PORT;
|
||||
mcpsReq.Req.Confirmed.fBufferSize = certifParam.DataBufferSize;
|
||||
mcpsReq.Req.Confirmed.fBuffer = &(certifParam.DataBuffer);
|
||||
mcpsReq.Req.Confirmed.NbTrials = 8;
|
||||
mcpsReq.Req.Confirmed.Datarate = DR_0;
|
||||
}
|
||||
}
|
||||
|
||||
/*cerification test on-going*/
|
||||
TimerStart(&CertifTxNextPacketTimer);
|
||||
|
||||
#if (ACTIVE_REGION == LORAMAC_REGION_US915)
|
||||
if (abortTx == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif /* ACTIVE_REGION == LORAMAC_REGION_US915 */
|
||||
|
||||
if (LoRaMacMcpsRequest(&mcpsReq) == LORAMAC_STATUS_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CERTIF_rx_request(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters)
|
||||
{
|
||||
CertifMcpsIndication = mcpsIndication;
|
||||
CertifJoinParameters = JoinParameters;
|
||||
|
||||
requested_process_id = CERTIF_RX_PROCESS;
|
||||
|
||||
CertifProcessNotify();
|
||||
}
|
||||
|
||||
static void CERTIF_rx(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters)
|
||||
{
|
||||
if (certifParam.Running == false)
|
||||
{
|
||||
// Check compliance test enable command (i)
|
||||
if ((mcpsIndication->BufferSize == 4) &&
|
||||
(mcpsIndication->Buffer[0] == 0x01) &&
|
||||
(mcpsIndication->Buffer[1] == 0x01) &&
|
||||
(mcpsIndication->Buffer[2] == 0x01) &&
|
||||
(mcpsIndication->Buffer[3] == 0x01))
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
IsTxConfirmed = LORAWAN_UNCONFIRMED_MSG;
|
||||
certifParam.DataBufferSize = 2;
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.LinkCheck = false;
|
||||
certifParam.DemodMargin = 0;
|
||||
certifParam.NbGateways = 0;
|
||||
certifParam.Running = true;
|
||||
certifParam.State = 1;
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
|
||||
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
AdrEnableInit = mibReq.Param.AdrEnable;
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = true;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if ( (ACTIVE_REGION == LORAMAC_REGION_EU868)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_RU864)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_CN779)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_EU433))
|
||||
{
|
||||
LoRaMacTestSetDutyCycleOn(false);
|
||||
}
|
||||
|
||||
TimerInit(&CertifTxNextPacketTimer, OnCertifTxNextPacketTimerEvent);
|
||||
TimerSetValue(&CertifTxNextPacketTimer, TEST_TX_DUTYCYCLE);
|
||||
|
||||
/*confirm test mode activation */
|
||||
CERTIF_tx();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
certifParam.State = mcpsIndication->Buffer[0];
|
||||
switch (certifParam.State)
|
||||
{
|
||||
case 0: // Check compliance test disable command (ii)
|
||||
{
|
||||
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.Running = false;
|
||||
|
||||
MibRequestConfirm_t mibReq;
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = AdrEnableInit;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if ( (ACTIVE_REGION == LORAMAC_REGION_EU868)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_RU864)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_CN779)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_EU433))
|
||||
{
|
||||
LoRaMacTestSetDutyCycleOn(true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // (iii, iv)
|
||||
certifParam.DataBufferSize = 2;
|
||||
break;
|
||||
case 2: // Enable confirmed messages (v)
|
||||
IsTxConfirmed = LORAWAN_CONFIRMED_MSG;
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 3: // Disable confirmed messages (vi)
|
||||
IsTxConfirmed = LORAWAN_UNCONFIRMED_MSG;
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 4: // (vii)
|
||||
certifParam.DataBufferSize = mcpsIndication->BufferSize;
|
||||
|
||||
certifParam.DataBuffer[0] = 4;
|
||||
for (uint8_t i = 1; i < certifParam.DataBufferSize; i++)
|
||||
{
|
||||
certifParam.DataBuffer[i] = mcpsIndication->Buffer[i] + 1;
|
||||
}
|
||||
break;
|
||||
case 5: // (viii)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_LINK_CHECK;
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
case 6: // (ix)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
// Disable TestMode and revert back to normal operation
|
||||
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.Running = false;
|
||||
|
||||
MibRequestConfirm_t mibReq;
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = AdrEnableInit;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mlmeReq.Type = MLME_JOIN;
|
||||
mlmeReq.Req.Join = *JoinParameters;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // (x)
|
||||
{
|
||||
if (mcpsIndication->BufferSize == 3)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_TXCW;
|
||||
mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]);
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
else if (mcpsIndication->BufferSize == 7)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_TXCW_1;
|
||||
mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]);
|
||||
mlmeReq.Req.TxCw.Frequency = (uint32_t)((mcpsIndication->Buffer[3] << 16) | (mcpsIndication->Buffer[4] << 8) | mcpsIndication->Buffer[5]) * 100;
|
||||
mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: // Send DeviceTimeReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_DEVICE_TIME;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
case 9: // Switch end device Class
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
// CLASS_A = 0, CLASS_B = 1, CLASS_C = 2
|
||||
mibReq.Param.Class = (DeviceClass_t)mcpsIndication->Buffer[1];
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
break;
|
||||
}
|
||||
case 10: // Send PingSlotInfoReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_PING_SLOT_INFO;
|
||||
|
||||
mlmeReq.Req.PingSlotInfo.PingSlot.Value = mcpsIndication->Buffer[1];
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
case 11: // Send BeaconTimingReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_BEACON_TIMING;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (certifParam.Running == false)
|
||||
{
|
||||
/*certification test stops*/
|
||||
TimerStop(&CertifTxNextPacketTimer);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Function executed on TxNextPacket Timeout event
|
||||
*/
|
||||
static void OnCertifTxNextPacketTimerEvent(void *context)
|
||||
{
|
||||
requested_process_id = CERTIF_TX_PROCESS;
|
||||
CertifProcessNotify();
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/******************************************************************************
|
||||
* @file lora_test.h
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __LORA_TEST_H__
|
||||
#define __LORA_TEST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define CERTIF_PORT 224
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Certification Initialisation
|
||||
* @param [IN] Notification call back to the appl that a CERTIF_Process must be called
|
||||
* @retval none
|
||||
*/
|
||||
void CERTIF_Init(void (*CERTIF_ProcessNotify)(void));
|
||||
/**
|
||||
* @brief CERTIF_Process to be called when a CERTIF_ProcessNotify callback is generated
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
void CERTIF_Process(void);
|
||||
|
||||
/* Lora Test callbacks*/
|
||||
typedef struct sLoRaCertifCallback
|
||||
{
|
||||
bool (*running)(void);
|
||||
|
||||
void (*DownLinkIncrement)(void);
|
||||
|
||||
void (*linkCheck)(MlmeConfirm_t *mlmeConfirm);
|
||||
|
||||
void (*rx)(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
} LoRaCertifCallback_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__LORA_TEST_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,985 @@
|
|||
/*
|
||||
_/_/_/ _/_/_/ _/_/_/ _/_/_/ _/ _/ _/_/_/ _/ _/ _/_/_/_/
|
||||
_/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
|
||||
_/_/_/ _/ _/_/ _/ _/ _/ _/ _/ _/_/ _/_/_/_/ _/_/_/
|
||||
_/ _/ _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
|
||||
_/ _/ _/_/_/ _/_/_/ _/_/_/ _/ _/ _/_/_/ _/ _/ _/
|
||||
(C)2020/5/20 RisingHF, all rights reserved.
|
||||
Lorawan API
|
||||
*/
|
||||
|
||||
#include "timer.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "LoRaMacTest.h"
|
||||
#include "lora.h"
|
||||
#include "app_system.h"
|
||||
#include "lorawan_info.h"
|
||||
#include "stm32_mem.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lw_state_t otaa; /*< ENABLE if over the air activation, DISABLE otherwise */
|
||||
lw_state_t duty_cycle; /*< ENABLE if dutycyle is on, DISABLE otherwise */
|
||||
uint8_t DevEui[8]; /*< Device EUI */
|
||||
uint8_t JoinEui[8]; /*< Join Eui */
|
||||
uint8_t AppKey[16]; /*< Application Key */
|
||||
uint8_t NwkKey[16]; /*< Application Key */
|
||||
uint8_t NwkSEncKey[16]; /*< Network Session Key */
|
||||
uint8_t AppSKey[16]; /*< Application Session Key */
|
||||
uint8_t FNwkSIntKey[16]; /*< Application Session Key */
|
||||
uint8_t SNwkSIntKey[16]; /*< Application Session Key */
|
||||
int16_t Rssi; /*< Rssi of the received packet */
|
||||
int8_t Snr; /*< Snr of the received packet */
|
||||
uint8_t application_port; /*< Application port we will receive to */
|
||||
LoraConfirm_t ReqAck; /*< ENABLE if acknowledge is requested */
|
||||
int8_t TxDatarate;
|
||||
}lorawan_configuration_t;
|
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/
|
||||
typedef struct slorawan_param
|
||||
{
|
||||
bool adr_enable; /*Activation state of adaptativeDatarate*/
|
||||
bool enable_public_network; /*Enable or disable a public network*/
|
||||
int8_t tx_datarate; /*Uplink datarate, if AdrEnable is off*/
|
||||
uint8_t confirm_retry; /*the uplink confirm frame retry times*/
|
||||
LoRaMacRegion_t active_region; /*region to open*/
|
||||
uint32_t dev_addr;
|
||||
} lw_param_t;
|
||||
|
||||
static lorawan_configuration_t lw_config =
|
||||
{
|
||||
.otaa = LORA_ENABLE,
|
||||
.duty_cycle = LORA_ENABLE,
|
||||
.DevEui = LORAWAN_DEVICE_EUI,
|
||||
.JoinEui = LORAWAN_JOIN_EUI,
|
||||
.AppKey = LORAWAN_APP_KEY,
|
||||
.NwkKey = LORAWAN_NWK_KEY,
|
||||
.NwkSEncKey = LORAWAN_NWK_S_ENC_KEY,
|
||||
.AppSKey = LORAWAN_APP_S_KEY,
|
||||
.FNwkSIntKey = LORAWAN_F_NWK_S_INT_KEY,
|
||||
.SNwkSIntKey = LORAWAN_S_NWK_S_INT_KEY,
|
||||
.Rssi = 0,
|
||||
.Snr = 0,
|
||||
.ReqAck = LORAWAN_UNCONFIRMED_MSG,
|
||||
.TxDatarate = 0
|
||||
};
|
||||
|
||||
|
||||
static lw_param_t lw_param_init =
|
||||
{
|
||||
.adr_enable = 0,
|
||||
.tx_datarate =DR_0,
|
||||
.confirm_retry = 2,
|
||||
.enable_public_network = LORAWAN_PUBLIC_NETWORK,
|
||||
.active_region = LORAWAN_DEFAULT_ACTIVE_REGION,
|
||||
.dev_addr = LORAWAN_DEVICE_ADDRESS
|
||||
};
|
||||
|
||||
/*!
|
||||
* Select either Device_Time_req or Beacon_Time_Req following LoRaWAN version
|
||||
* - Device_Time_req Available for V1.0.3 or later
|
||||
* - Beacon_time_Req Available for V1.0.2 and before
|
||||
*/
|
||||
#define USE_DEVICE_TIMING
|
||||
|
||||
|
||||
#include "LoRaMacTest.h"
|
||||
|
||||
/*for classB=============================================================*/
|
||||
#ifndef LORAMAC_CLASSB_ACTIVE
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined ( shall be <0 or 1> )
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
/*!
|
||||
* Default ping slots periodicity
|
||||
*
|
||||
* \remark periodicity is equal to 2^LORAWAN_DEFAULT_PING_SLOT_PERIODICITY seconds
|
||||
* example: 2^3 = 8 seconds. The end-device will open an Rx slot every 8 seconds.
|
||||
*/
|
||||
#define LORAWAN_DEFAULT_PING_SLOT_PERIODICITY 0
|
||||
static uint8_t DefaultPingSlotPeriodicity;
|
||||
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
/*=============================================================*/
|
||||
|
||||
#define HEX16(X) X[0],X[1], X[2],X[3], X[4],X[5], X[6],X[7],X[8],X[9], X[10],X[11], X[12],X[13], X[14],X[15]
|
||||
#define HEX8(X) X[0],X[1], X[2],X[3], X[4],X[5], X[6],X[7]
|
||||
|
||||
static MlmeReqJoin_t JoinParameters;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Dummy data sent periodically to let the tester respond with start test command*/
|
||||
static TimerEvent_t TxcertifTimer;
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/*for classB=============================================================*/
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
static LoraErrorStatus lw_beacon_req(void);
|
||||
static LoraErrorStatus lw_pingslot_req(void);
|
||||
|
||||
#if defined( USE_DEVICE_TIMING )
|
||||
static LoraErrorStatus lw_device_time_req(void);
|
||||
#else
|
||||
static LoraErrorStatus lw_beacon_time_req(void);
|
||||
#endif /* USE_DEVICE_TIMING */
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
/*======================================================================*/
|
||||
|
||||
|
||||
|
||||
static LoRaMacPrimitives_t LoRaMacPrimitives;
|
||||
static LoRaMacCallback_t LoRaMacCallbacks;
|
||||
static MibRequestConfirm_t mibReq;
|
||||
|
||||
|
||||
static LoRaMainCallback_t *LoRaMainCallbacks;
|
||||
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/*!
|
||||
* \brief MCPS-Confirm event function
|
||||
*
|
||||
* \param [IN] McpsConfirm - Pointer to the confirm structure,
|
||||
* containing confirm attributes.
|
||||
*/
|
||||
static void McpsConfirm(McpsConfirm_t *mcpsConfirm)
|
||||
{
|
||||
lw_app_data_t app_data = {0};
|
||||
|
||||
if (mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
switch (mcpsConfirm->McpsRequest)
|
||||
{
|
||||
case MCPS_UNCONFIRMED:
|
||||
case MCPS_CONFIRMED:
|
||||
{
|
||||
// Check Datarate
|
||||
// Check TxPower
|
||||
// Check AckReceived
|
||||
|
||||
// Check NbTrials
|
||||
break;
|
||||
}
|
||||
case MCPS_PROPRIETARY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
app_data.ack = mcpsConfirm->AckReceived;
|
||||
LoRaMainCallbacks->app_events(APP_TX_DONE_EVENT,&app_data);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief MCPS-Indication event function
|
||||
*
|
||||
* \param [IN] mcpsIndication - Pointer to the indication structure,
|
||||
* containing indication attributes.
|
||||
*/
|
||||
static void McpsIndication(McpsIndication_t *mcpsIndication)
|
||||
{
|
||||
lw_app_data_t app_data ={0};
|
||||
|
||||
if(mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mcpsIndication->McpsIndication)
|
||||
{
|
||||
case MCPS_UNCONFIRMED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case MCPS_CONFIRMED:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case MCPS_PROPRIETARY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case MCPS_MULTICAST:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Check Buffer
|
||||
// Check BufferSize
|
||||
// Check Rssi
|
||||
// Check Snr
|
||||
// Check RxSlot
|
||||
if(mcpsIndication->RxData == true)
|
||||
{
|
||||
app_data.port = mcpsIndication->Port;
|
||||
app_data.size = mcpsIndication->BufferSize;
|
||||
app_data.buff = mcpsIndication->Buffer;
|
||||
app_data.fpending = mcpsIndication->FramePending;
|
||||
|
||||
lw_config.Rssi = mcpsIndication->Rssi;
|
||||
lw_config.Snr = mcpsIndication->Snr;
|
||||
LoRaMainCallbacks->app_events(APP_RX_EVENT,&app_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief MLME-Confirm event function
|
||||
*
|
||||
* \param [IN] MlmeConfirm - Pointer to the confirm structure,
|
||||
* containing confirm attributes.
|
||||
*/
|
||||
static void MlmeConfirm(MlmeConfirm_t *mlmeConfirm)
|
||||
{
|
||||
#if (LORAMAC_CLASSB_ACTIVE == 1)
|
||||
MibRequestConfirm_t mibReq;
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
switch (mlmeConfirm->MlmeRequest)
|
||||
{
|
||||
case MLME_JOIN:
|
||||
{
|
||||
if(mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
// Status is OK, node has joined the network
|
||||
LoRaMainCallbacks->app_events(APP_JOINED_EVENT,NULL);
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
#if defined( USE_DEVICE_TIMING )
|
||||
lw_device_time_req();
|
||||
#else
|
||||
lw_beacon_time_req();
|
||||
#endif /* USE_DEVICE_TIMING */
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
}
|
||||
else
|
||||
{
|
||||
// Join was not successful. Try to join again
|
||||
lw_join();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MLME_LINK_CHECK:
|
||||
{
|
||||
if (mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
case MLME_BEACON_ACQUISITION:
|
||||
{
|
||||
if(mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
/* Beacon has been acquired */
|
||||
/* REquest Server for Ping Slot */
|
||||
lw_pingslot_req();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Beacon not acquired */
|
||||
/* Search again */
|
||||
/* we can check if the MAC has received a time reference for the beacon*/
|
||||
/* in this case do either a Device_Time_Req or a Beacon_Timing_req*/
|
||||
lw_beacon_req();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MLME_PING_SLOT_INFO:
|
||||
{
|
||||
if(mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
/* class B is now ativated*/
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
mibReq.Param.Class = CLASS_B;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if((lw_param_init.active_region == LORAMAC_REGION_AU915) || (lw_param_init.active_region == LORAMAC_REGION_US915))
|
||||
{
|
||||
mibReq.Type = MIB_PING_SLOT_DATARATE;
|
||||
mibReq.Param.PingSlotDatarate = DR_8;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
/*notify upper layer*/
|
||||
/*ClassB*/
|
||||
DeviceClass_t cur_class =CLASS_B;
|
||||
LoRaMainCallbacks->app_events(APP_CONFIRM_ClASS_EVENT,&cur_class);
|
||||
}
|
||||
else
|
||||
{
|
||||
lw_pingslot_req();
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if defined( USE_DEVICE_TIMING )
|
||||
case MLME_DEVICE_TIME:
|
||||
{
|
||||
if (mlmeConfirm->Status != LORAMAC_EVENT_INFO_STATUS_OK)
|
||||
{
|
||||
lw_device_time_req();
|
||||
}
|
||||
}
|
||||
#endif /* USE_DEVICE_TIMING */
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief MLME-Indication event function
|
||||
*
|
||||
* \param [IN] MlmeIndication - Pointer to the indication structure.
|
||||
*/
|
||||
static void MlmeIndication(MlmeIndication_t *MlmeIndication)
|
||||
{
|
||||
lw_app_data_t app_data ={0};
|
||||
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
MibRequestConfirm_t mibReq;
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
switch (MlmeIndication->MlmeIndication)
|
||||
{
|
||||
case MLME_SCHEDULE_UPLINK:
|
||||
{
|
||||
app_data.fpending = 1;
|
||||
// The MAC signals that we shall provide an uplink as soon as possible
|
||||
LoRaMainCallbacks->app_events(APP_RX_EVENT,&app_data);
|
||||
break;
|
||||
}
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
case MLME_BEACON_LOST:
|
||||
{
|
||||
// Switch to class A again
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
mibReq.Param.Class = CLASS_A;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
lw_beacon_req();
|
||||
break;
|
||||
}
|
||||
case MLME_BEACON:
|
||||
{
|
||||
if(MlmeIndication->Status == LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED)
|
||||
{
|
||||
APP_LOG("BEACON RECEIVED\n\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_LOG("BEACON NOT RECEIVED\n\r");
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* lorawan init
|
||||
*/
|
||||
void lw_init(LoRaMainCallback_t *callbacks)
|
||||
{
|
||||
LoRaMacInfo_t *LoRaMacRegionInfo;
|
||||
|
||||
LoraMacInfo_Init();
|
||||
LoRaMacRegionInfo = LoraMacInfo_GetPtr();
|
||||
if(LoRaMacRegionInfo->Region == 0)
|
||||
{
|
||||
APP_PRINTF("error: At leats one region shall be defined in the MW: check lorawan_conf.h \n\r");
|
||||
while(1) {} /* At leats one region shall be defined in MW */
|
||||
}
|
||||
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
if(LoRaMacRegionInfo->ClassB != 1)
|
||||
{
|
||||
APP_PRINTF("error: ClassB is not defined in the MW: set lorawan_conf.h accordingly\n\r");
|
||||
while(1) {} /* error: ClassB is not defined in the MW*/
|
||||
}
|
||||
#elif ( LORAMAC_CLASSB_ACTIVE == 0 )
|
||||
if(LoRaMacRegionInfo->ClassB != 0)
|
||||
{
|
||||
APP_PRINTF("error: missmatch between applic and MW CLASSB defines: set lorawan_conf.h according to app_conf.h\n\r");
|
||||
while(1) {} /* error: ClassB should not be defined in the MW*/
|
||||
}
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
/* init the main call backs*/
|
||||
LoRaMainCallbacks = callbacks;
|
||||
|
||||
#if (STATIC_DEVICE_EUI != 1)
|
||||
LoRaMainCallbacks->BoardGetUniqueId(lw_config.DevEui);
|
||||
#endif
|
||||
|
||||
#if (STATIC_DEVICE_ADDRESS != 1)
|
||||
// Choose a "pseudo-random" device address
|
||||
lw_param_init.dev_addr = LoRaMainCallbacks->BoardGetRandomSeed();
|
||||
#endif
|
||||
|
||||
LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
|
||||
LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
|
||||
LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
|
||||
LoRaMacPrimitives.MacMlmeIndication = MlmeIndication;
|
||||
LoRaMacCallbacks.GetBatteryLevel = LoRaMainCallbacks->BoardGetBatteryLevel;
|
||||
LoRaMacCallbacks.GetTemperatureLevel = LoRaMainCallbacks->BoardGetTemperatureLevel;
|
||||
LoRaMacCallbacks.MacProcessNotify = LoRaMainCallbacks->MacProcessNotify;
|
||||
|
||||
if(0U != ((1<<(lw_param_init.active_region))& (LoRaMacRegionInfo->Region)))
|
||||
{
|
||||
LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, lw_param_init.active_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_PRINTF("error: Region is not defined in the MW: set lorawan_conf.h accordingly\n\r");
|
||||
while(1) {} /* error: Region is not defined in the MW */
|
||||
}
|
||||
if((lw_param_init.active_region == LORAMAC_REGION_CN470)||(lw_param_init.active_region == LORAMAC_REGION_CN470ALI))
|
||||
{
|
||||
uint16_t channelMask[] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
|
||||
if(lw_param_init.active_region == LORAMAC_REGION_CN470){
|
||||
channelMask[0] = 0x00FF;
|
||||
}
|
||||
else{
|
||||
channelMask[0] = 0xFF00;
|
||||
}
|
||||
mibReq.Type = MIB_CHANNELS_MASK;
|
||||
mibReq.Param.ChannelsMask = channelMask;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
mibReq.Type = MIB_CHANNELS_DEFAULT_MASK;
|
||||
mibReq.Param.ChannelsDefaultMask = channelMask;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
|
||||
lw_config_otaa_set(lw_config.otaa);
|
||||
|
||||
mibReq.Type = MIB_DEV_EUI;
|
||||
mibReq.Param.DevEui = lw_config.DevEui;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_JOIN_EUI;
|
||||
mibReq.Param.JoinEui = lw_config.JoinEui;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = lw_param_init.adr_enable;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_PUBLIC_NETWORK;
|
||||
mibReq.Param.EnablePublicNetwork = lw_param_init.enable_public_network;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_APP_KEY;
|
||||
mibReq.Param.AppKey = lw_config.AppKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_NWK_KEY;
|
||||
mibReq.Param.NwkKey = lw_config.NwkKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
mibReq.Param.Class = CLASS_A;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if((lw_param_init.active_region == LORAMAC_REGION_EU868)
|
||||
|| (lw_param_init.active_region == LORAMAC_REGION_RU864)
|
||||
|| (lw_param_init.active_region == LORAMAC_REGION_CN779)
|
||||
|| (lw_param_init.active_region == LORAMAC_REGION_EU433))
|
||||
{
|
||||
LoRaMacTestSetDutyCycleOn(true);
|
||||
lw_config.duty_cycle = LORA_ENABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
lw_config.duty_cycle = LORA_DISABLE;
|
||||
}
|
||||
|
||||
mibReq.Type = MIB_SYSTEM_MAX_RX_ERROR;
|
||||
mibReq.Param.SystemMaxRxError = 20;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
if (LoRaMacRegionInfo->ClassB == 1)
|
||||
{
|
||||
DefaultPingSlotPeriodicity = LORAWAN_DEFAULT_PING_SLOT_PERIODICITY;
|
||||
}
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
/*set Mac statein Idle*/
|
||||
LoRaMacStart();
|
||||
}
|
||||
|
||||
LoRaMacStatus_t lw_join(void)
|
||||
{
|
||||
LoRaMacStatus_t status;
|
||||
|
||||
if (lw_config.otaa == LORA_ENABLE)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_JOIN;
|
||||
mlmeReq.Req.Join.Datarate = lw_param_init.tx_datarate;
|
||||
|
||||
JoinParameters = mlmeReq.Req.Join;
|
||||
status = LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*no Join in abp*/
|
||||
status = LORAMAC_STATUS_BUSY;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
LoraFlagStatus lw_join_status(void)
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
|
||||
mibReq.Type = MIB_NETWORK_ACTIVATION;
|
||||
|
||||
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
|
||||
if(mibReq.Param.NetworkActivation == ACTIVATION_TYPE_NONE)
|
||||
{
|
||||
return LORA_RESET;
|
||||
}
|
||||
else
|
||||
{
|
||||
return LORA_SET;
|
||||
}
|
||||
}
|
||||
|
||||
LoRaMacStatus_t lw_current_chmask_get(LWChannel_mask_t* ch)
|
||||
{
|
||||
mibReq.Type = MIB_CHANNELS_MASK;
|
||||
mibReq.Param.ChannelsMask = (uint16_t*)ch;
|
||||
LoRaMacStatus_t sta = LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
|
||||
if(LORAMAC_STATUS_OK == sta)
|
||||
{
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
{
|
||||
ch->mask[i] = mibReq.Param.ChannelsMask[i];
|
||||
}
|
||||
}
|
||||
return sta;
|
||||
}
|
||||
LoRaMacStatus_t lw_current_chmask_set(const LWChannel_mask_t* ch)
|
||||
{
|
||||
static bool only;
|
||||
|
||||
if(only == false)
|
||||
{
|
||||
only = true;
|
||||
mibReq.Type = MIB_CHANNELS_DEFAULT_MASK;
|
||||
mibReq.Param.ChannelsDefaultMask = (uint16_t*)ch;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
|
||||
mibReq.Type = MIB_CHANNELS_MASK;
|
||||
mibReq.Param.ChannelsMask = (uint16_t*)ch;
|
||||
return LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
LoRaMacStatus_t lw_rxwin2_ch_set(const RxChannelParams_t* rx2_ch)
|
||||
{
|
||||
LoRaMacStatus_t sta;
|
||||
|
||||
mibReq.Type = MIB_RX2_CHANNEL;
|
||||
mibReq.Param.Rx2Channel.Frequency = rx2_ch->Frequency;
|
||||
mibReq.Param.Rx2Channel.Datarate = rx2_ch->Datarate;
|
||||
|
||||
sta = LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
return sta;
|
||||
}
|
||||
|
||||
LoRaMacStatus_t lw_rxwin2_ch_get(RxChannelParams_t* rx2_ch)
|
||||
{
|
||||
LoRaMacStatus_t sta;
|
||||
mibReq.Type = MIB_RX2_CHANNEL;
|
||||
|
||||
sta = LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
|
||||
if(LORAMAC_STATUS_OK == sta)
|
||||
{
|
||||
*rx2_ch = mibReq.Param.Rx2Channel;
|
||||
}
|
||||
return sta;
|
||||
}
|
||||
|
||||
|
||||
LoRaMacStatus_t lw_adr_set(lw_state_t sta)
|
||||
{
|
||||
LoRaMacStatus_t n_sta=0;
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = sta ;
|
||||
n_sta = LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
if(LORAMAC_STATUS_OK == n_sta){
|
||||
lw_param_init.adr_enable = sta;
|
||||
}
|
||||
return n_sta;
|
||||
}
|
||||
|
||||
|
||||
LoRaMacStatus_t lw_send(lw_app_data_t *app_data, LoraConfirm_t IsTxConfirmed)
|
||||
{
|
||||
McpsReq_t mcpsReq;
|
||||
LoRaMacTxInfo_t txInfo;
|
||||
|
||||
if(LoRaMacQueryTxPossible(app_data->size, &txInfo) != LORAMAC_STATUS_OK)
|
||||
{
|
||||
// Send empty frame in order to flush MAC commands
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
|
||||
mcpsReq.Req.Unconfirmed.Datarate = lw_config_tx_datarate_get() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsTxConfirmed == LORAWAN_UNCONFIRMED_MSG)
|
||||
{
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fPort = app_data->port;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = app_data->size;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = app_data->buff;
|
||||
mcpsReq.Req.Unconfirmed.Datarate = lw_config_tx_datarate_get() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcpsReq.Type = MCPS_CONFIRMED;
|
||||
mcpsReq.Req.Confirmed.fPort = app_data->port;
|
||||
mcpsReq.Req.Confirmed.fBufferSize = app_data->size;
|
||||
mcpsReq.Req.Confirmed.fBuffer = app_data->buff;
|
||||
mcpsReq.Req.Confirmed.NbTrials = lw_confirm_retry_get();
|
||||
mcpsReq.Req.Confirmed.Datarate = lw_config_tx_datarate_get() ;
|
||||
}
|
||||
}
|
||||
return LoRaMacMcpsRequest(&mcpsReq);
|
||||
|
||||
}
|
||||
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
#if defined( USE_DEVICE_TIMING )
|
||||
static LoRaMacStatus_t lw_device_time_req(void)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_DEVICE_TIME;
|
||||
|
||||
return LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
#else
|
||||
static LoRaMacStatus_t lw_beacon_time_req(void)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_BEACON_TIMING;
|
||||
|
||||
return LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
#endif /* USE_DEVICE_TIMING */
|
||||
|
||||
static LoRaMacStatus_t lw_beacon_req(void)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_BEACON_ACQUISITION;
|
||||
|
||||
return LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
|
||||
static LoRaMacStatus_t lw_pingslot_req(void)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_LINK_CHECK;
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
|
||||
mlmeReq.Type = MLME_PING_SLOT_INFO;
|
||||
mlmeReq.Req.PingSlotInfo.PingSlot.Fields.Periodicity = DefaultPingSlotPeriodicity;
|
||||
mlmeReq.Req.PingSlotInfo.PingSlot.Fields.RFU = 0;
|
||||
|
||||
return LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
LoRaMacStatus_t lw_request_class(DeviceClass_t newClass)
|
||||
{
|
||||
LoRaMacStatus_t Errorstatus = LORAMAC_STATUS_OK;
|
||||
|
||||
MibRequestConfirm_t mibReq;
|
||||
DeviceClass_t currentClass;
|
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
|
||||
currentClass = mibReq.Param.Class;
|
||||
/*attempt to swicth only if class update*/
|
||||
if(currentClass != newClass)
|
||||
{
|
||||
switch(newClass)
|
||||
{
|
||||
case CLASS_A:
|
||||
{
|
||||
mibReq.Param.Class = CLASS_A;
|
||||
|
||||
Errorstatus = LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
if(Errorstatus == LORAMAC_STATUS_OK)
|
||||
{
|
||||
DeviceClass_t cur_class =CLASS_A;
|
||||
LoRaMainCallbacks->app_events(APP_CONFIRM_ClASS_EVENT,&cur_class);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLASS_B:
|
||||
{
|
||||
#if (LORAMAC_CLASSB_ACTIVE == 1)
|
||||
if(currentClass != CLASS_A)
|
||||
{
|
||||
Errorstatus = LORAMAC_STATUS_ERROR;
|
||||
}
|
||||
/*switch is not instantanuous*/
|
||||
Errorstatus = lw_beacon_req();
|
||||
#else
|
||||
APP_PRINTF("warning: LORAMAC_CLASSB_ACTIVE has not been defined at compilation\n\r");
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
break;
|
||||
}
|
||||
case CLASS_C:
|
||||
{
|
||||
if (currentClass != CLASS_A)
|
||||
{
|
||||
Errorstatus = LORAMAC_STATUS_ERROR;
|
||||
}
|
||||
/*switch is instantanuous*/
|
||||
mibReq.Param.Class = CLASS_C;
|
||||
|
||||
Errorstatus = LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if(Errorstatus == LORAMAC_STATUS_OK)
|
||||
{
|
||||
DeviceClass_t cur_class =CLASS_C;
|
||||
LoRaMainCallbacks->app_events(APP_CONFIRM_ClASS_EVENT,&cur_class);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Errorstatus;
|
||||
}
|
||||
|
||||
DeviceClass_t lw_get_current_class(void)
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
|
||||
return mibReq.Param.Class;
|
||||
}
|
||||
|
||||
void lw_config_otaa_set(lw_state_t otaa)
|
||||
{
|
||||
lw_config.otaa = otaa;
|
||||
|
||||
if (lw_config.otaa == LORA_ENABLE)
|
||||
{
|
||||
APP_PPRINTF("OTAA Mode enabled\n\r");
|
||||
APP_PPRINTF("DevEui= %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n\r", HEX8(lw_config.DevEui));
|
||||
APP_PPRINTF("JoinEui= %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n\r", HEX8(lw_config.JoinEui));
|
||||
APP_PPRINTF("AppKey= %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n\r", HEX16(lw_config.AppKey));
|
||||
|
||||
mibReq.Type = MIB_NETWORK_ACTIVATION;
|
||||
mibReq.Param.NetworkActivation = ACTIVATION_TYPE_NONE;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_PPRINTF("ABP Mode enabled\n\r");
|
||||
APP_PPRINTF("DevEui= %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n\r", HEX8(lw_config.DevEui));
|
||||
APP_PPRINTF("DevAdd= %08X\n\r", lw_param_init.dev_addr) ;
|
||||
APP_PPRINTF("NwkSKey= %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n\r", HEX16(lw_config.NwkSEncKey));
|
||||
APP_PPRINTF("AppSKey= %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n\r", HEX16(lw_config.AppSKey));
|
||||
|
||||
mibReq.Type = MIB_NET_ID;
|
||||
mibReq.Param.NetID = LORAWAN_NETWORK_ID;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_DEV_ADDR;
|
||||
mibReq.Param.DevAddr = lw_param_init.dev_addr;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_F_NWK_S_INT_KEY;
|
||||
mibReq.Param.FNwkSIntKey = lw_config.FNwkSIntKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_S_NWK_S_INT_KEY;
|
||||
mibReq.Param.SNwkSIntKey = lw_config.SNwkSIntKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_NWK_S_ENC_KEY;
|
||||
mibReq.Param.NwkSEncKey = lw_config.NwkSEncKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_APP_S_KEY;
|
||||
mibReq.Param.AppSKey = lw_config.AppSKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_NETWORK_ACTIVATION;
|
||||
mibReq.Param.NetworkActivation = ACTIVATION_TYPE_ABP;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
// Enable legacy mode to operate according to LoRaWAN Spec. 1.0.3
|
||||
Version_t abpLrWanVersion;
|
||||
|
||||
abpLrWanVersion.Fields.Major = 1;
|
||||
abpLrWanVersion.Fields.Minor = 0;
|
||||
abpLrWanVersion.Fields.Revision = 3;
|
||||
abpLrWanVersion.Fields.Rfu = 0;
|
||||
|
||||
mibReq.Type = MIB_ABP_LORAWAN_VERSION;
|
||||
mibReq.Param.AbpLrWanVersion = abpLrWanVersion;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
}
|
||||
|
||||
lw_state_t lw_config_otaa_get(void)
|
||||
{
|
||||
return lw_config.otaa;
|
||||
}
|
||||
|
||||
|
||||
void lw_confirm_retry_set(uint8_t retry)
|
||||
{
|
||||
lw_param_init.confirm_retry = retry;
|
||||
}
|
||||
|
||||
|
||||
uint8_t lw_confirm_retry_get(void)
|
||||
{
|
||||
return lw_param_init.confirm_retry;
|
||||
}
|
||||
|
||||
|
||||
void lw_config_duty_cycle_set(lw_state_t duty_cycle)
|
||||
{
|
||||
lw_config.duty_cycle = duty_cycle;
|
||||
LoRaMacTestSetDutyCycleOn((duty_cycle == LORA_ENABLE) ? 1 : 0);
|
||||
}
|
||||
|
||||
lw_state_t lw_config_duty_cycle_get(void)
|
||||
{
|
||||
return lw_config.duty_cycle;
|
||||
}
|
||||
|
||||
uint8_t *lw_config_deveui_get(void)
|
||||
{
|
||||
return lw_config.DevEui;
|
||||
}
|
||||
|
||||
uint8_t *lw_config_joineui_get(void)
|
||||
{
|
||||
return lw_config.JoinEui;
|
||||
}
|
||||
|
||||
void lw_config_joineui_set(uint8_t joineui[8])
|
||||
{
|
||||
UTIL_MEM_cpy_8(lw_config.JoinEui, joineui, sizeof(lw_config.JoinEui));
|
||||
|
||||
mibReq.Type = MIB_JOIN_EUI;
|
||||
mibReq.Param.JoinEui = lw_config.JoinEui;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
|
||||
uint8_t *lw_config_appkey_get(void)
|
||||
{
|
||||
return lw_config.AppKey;
|
||||
}
|
||||
|
||||
void lw_config_appkey_set(uint8_t appkey[16])
|
||||
{
|
||||
UTIL_MEM_cpy_8(lw_config.AppKey, appkey, sizeof(lw_config.AppKey));
|
||||
UTIL_MEM_cpy_8(lw_config.NwkKey, appkey, sizeof(lw_config.NwkKey));
|
||||
|
||||
mibReq.Type = MIB_APP_KEY;
|
||||
mibReq.Param.AppKey = lw_config.AppKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mibReq.Type = MIB_NWK_KEY;
|
||||
mibReq.Param.NwkKey = lw_config.NwkKey;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
}
|
||||
|
||||
void lw_config_reqack_set(LoraConfirm_t reqack)
|
||||
{
|
||||
lw_config.ReqAck = reqack;
|
||||
}
|
||||
|
||||
LoraConfirm_t lw_config_reqack_get(void)
|
||||
{
|
||||
return lw_config.ReqAck;
|
||||
}
|
||||
|
||||
int8_t lw_config_snr_get(void)
|
||||
{
|
||||
return lw_config.Snr;
|
||||
}
|
||||
|
||||
int16_t lw_config_rssi_get(void)
|
||||
{
|
||||
return lw_config.Rssi;
|
||||
}
|
||||
|
||||
void lw_config_tx_datarate_set(int8_t TxDataRate)
|
||||
{
|
||||
lw_config.TxDatarate = TxDataRate;
|
||||
}
|
||||
|
||||
int8_t lw_config_tx_datarate_get(void)
|
||||
{
|
||||
return lw_config.TxDatarate;
|
||||
}
|
||||
|
||||
|
||||
LoRaMacRegion_t lora_region_get(void)
|
||||
{
|
||||
return lw_param_init.active_region;
|
||||
}
|
||||
#if ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
LoRaMacClassBNvmCtx_t* lw_get_classBCtx(void)
|
||||
{
|
||||
mibReq.Type = MIB_NVM_CTXS;
|
||||
LoRaMacMibGetRequestConfirm( &mibReq );
|
||||
return ( LoRaMacClassBNvmCtx_t*) mibReq.Param.Contexts->ClassBNvmCtx;
|
||||
}
|
||||
|
||||
uint8_t lw_get_pingslot_periodicity(void)
|
||||
{
|
||||
return DefaultPingSlotPeriodicity;
|
||||
}
|
||||
|
||||
void lw_set_pingslot_periodicity(uint8_t PingSlotPeriodicity)
|
||||
{
|
||||
DefaultPingSlotPeriodicity= PingSlotPeriodicity;
|
||||
}
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,407 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lora.h
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __LORA_H__
|
||||
#define __LORA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "Commissioning.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "app_conf.h"
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
#include "LoRaMacClassB.h"
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
#include "region/Region.h"
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/*!
|
||||
* LoRaWAN confirmed messages
|
||||
*/
|
||||
|
||||
#define LORAWAN_ADR_ON 1
|
||||
#define LORAWAN_ADR_OFF 0
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/*!
|
||||
* Application Data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*point to the LoRa App data buffer*/
|
||||
uint8_t *buff;
|
||||
/*LoRa App data buffer size*/
|
||||
uint8_t size;
|
||||
/*Port on which the LoRa App is data is sent/ received*/
|
||||
uint8_t port;
|
||||
|
||||
uint8_t ack;
|
||||
|
||||
uint8_t fpending;
|
||||
|
||||
} lw_app_data_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_RESET = 0,
|
||||
LORA_SET = !LORA_RESET
|
||||
} LoraFlagStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_DISABLE = 0,
|
||||
LORA_ENABLE = !LORA_DISABLE
|
||||
} lw_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_ERROR = -1,
|
||||
LORA_SUCCESS = 0
|
||||
} LoraErrorStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORAWAN_UNCONFIRMED_MSG = 0,
|
||||
LORAWAN_CONFIRMED_MSG = !LORAWAN_UNCONFIRMED_MSG
|
||||
} LoraConfirm_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_TRUE = 0,
|
||||
LORA_FALSE = !LORA_TRUE
|
||||
} LoraBool_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
APP_RX_EVENT,
|
||||
APP_JOINED_EVENT,
|
||||
APP_CONFIRM_ClASS_EVENT,
|
||||
APP_TX_DONE_EVENT,
|
||||
}APP_EVENT_t;
|
||||
|
||||
|
||||
/* Lora Main callbacks*/
|
||||
typedef struct sLoRaMainCallback
|
||||
{
|
||||
/*!
|
||||
* @brief mac event callback
|
||||
*
|
||||
* @retval null
|
||||
*/
|
||||
void (*app_events)(APP_EVENT_t evt,const void* param);
|
||||
/*!
|
||||
*\brief Will be called each time a Radio IRQ is handled by the MAC
|
||||
* layer.
|
||||
*
|
||||
*\warning Runs in a IRQ context. Should only change variables state.
|
||||
*/
|
||||
void (*MacProcessNotify)(void);
|
||||
/*!
|
||||
* @brief Get the current battery level
|
||||
*
|
||||
* @retval value battery level ( 0: very low, 254: fully charged )
|
||||
*/
|
||||
uint8_t (*BoardGetBatteryLevel)(void);
|
||||
/*!
|
||||
* \brief Get the current temperature
|
||||
*
|
||||
* \retval value temperature in degreeCelcius( q7.8 )
|
||||
*/
|
||||
uint16_t (*BoardGetTemperatureLevel)(void);
|
||||
/*!
|
||||
* @brief Gets the board 64 bits unique ID
|
||||
*
|
||||
* @param [IN] id Pointer to an array that will contain the Unique ID
|
||||
*/
|
||||
void (*BoardGetUniqueId)(uint8_t *id);
|
||||
/*!
|
||||
* Returns a pseudo random seed generated using the MCU Unique ID
|
||||
*
|
||||
* @retval seed Generated pseudo random seed
|
||||
*/
|
||||
uint32_t (*BoardGetRandomSeed)(void);
|
||||
|
||||
} LoRaMainCallback_t;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t mask[6];
|
||||
}LWChannel_mask_t;
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Lora Initialisation
|
||||
* @param [IN] LoRaMainCallback_t
|
||||
* @param [IN] application parmaters
|
||||
* @retval none
|
||||
*/
|
||||
void lw_init(LoRaMainCallback_t *callbacks);
|
||||
|
||||
/**
|
||||
* @brief run Lora classA state Machine
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
LoRaMacStatus_t lw_send(lw_app_data_t *AppData, LoraConfirm_t IsTxConfirmed);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Join a Lora Network in classA
|
||||
* @Note if the device is ABP, this is a pass through functon
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
LoRaMacStatus_t lw_join(void);
|
||||
|
||||
/**
|
||||
* @brief Check whether the Device is joined to the network
|
||||
* @param [IN] none
|
||||
* @retval returns LORA_SET if joined
|
||||
*/
|
||||
LoraFlagStatus lw_join_status(void);
|
||||
|
||||
/*=====================================================================
|
||||
if you want to use the Api below , you must call them after LORA_Init
|
||||
|
||||
because it has been made Initialization configuration
|
||||
|
||||
======================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enable or Disable ADR
|
||||
* @param [IN] lw_state_t
|
||||
* @retval returns req state
|
||||
*/
|
||||
LoRaMacStatus_t lw_adr_set(lw_state_t sta);
|
||||
|
||||
|
||||
/**
|
||||
* @brief uplink confirm retry times setting
|
||||
* @param [IN] times
|
||||
* @retval returns req state
|
||||
*/
|
||||
void lw_confirm_retry_set(uint8_t retry);
|
||||
|
||||
/**
|
||||
* @brief return uplink confirm retry times
|
||||
* @param [IN] null
|
||||
* @retval times
|
||||
*/
|
||||
uint8_t lw_confirm_retry_get(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief set the currnt chmask
|
||||
* @param [IN] LWChannel_mask_t
|
||||
* @retval status
|
||||
*/
|
||||
LoRaMacStatus_t lw_current_chmask_set(const LWChannel_mask_t* ch);
|
||||
|
||||
/**
|
||||
* @brief return the currnt chmask
|
||||
* @param [IN] LWChannel_mask_t
|
||||
* @retval status
|
||||
*/
|
||||
LoRaMacStatus_t lw_current_chmask_get(LWChannel_mask_t* ch);
|
||||
|
||||
/**
|
||||
* @brief set Rx win2 datarate and freq , there are default configuration in region parameter
|
||||
* @param [IN] RxChannelParams_t
|
||||
* @retval status
|
||||
*/
|
||||
LoRaMacStatus_t lw_rxwin2_ch_set(const RxChannelParams_t* rx2_ch);
|
||||
|
||||
/**
|
||||
* @brief get Rx win2 datarate and freq
|
||||
* @param [IN] RxChannelParams_t
|
||||
* @retval status
|
||||
*/
|
||||
|
||||
LoRaMacStatus_t lw_rxwin2_ch_get(RxChannelParams_t* rx2_ch);
|
||||
|
||||
/**
|
||||
* @brief change Lora Class
|
||||
* @Note callback LORA_ConfirmClass informs upper layer that the change has occured
|
||||
* @Note Only switch from class A to class B/C OR from class B/C to class A is allowed
|
||||
* @Attention can be calld only in LORA_ClassSwitchSlot or LORA_RxData callbacks
|
||||
* @param [IN] DeviceClass_t NewClass
|
||||
* @retval LoraErrorStatus
|
||||
*/
|
||||
LoRaMacStatus_t lw_request_class(DeviceClass_t newClass);
|
||||
|
||||
/**
|
||||
* @brief get the current Lora Class
|
||||
* @param [IN] DeviceClass_t NewClass
|
||||
* @retval None
|
||||
*/
|
||||
DeviceClass_t lw_get_current_class(void);
|
||||
|
||||
/**
|
||||
* @brief Set join activation process: OTAA vs ABP
|
||||
* @param Over The Air Activation status to set: enable or disable
|
||||
* @retval None
|
||||
*/
|
||||
void lw_config_otaa_set(lw_state_t otaa);
|
||||
|
||||
/**
|
||||
* @brief Get join activation process: OTAA vs ABP
|
||||
* @param None
|
||||
* @retval ENABLE if OTAA is used, DISABLE if ABP is used
|
||||
*/
|
||||
lw_state_t lw_config_otaa_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set duty cycle: ENABLE or DISABLE
|
||||
* @param Duty cycle to set: enable or disable
|
||||
* @retval None
|
||||
*/
|
||||
void lw_config_duty_cycle_set(lw_state_t duty_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get Duty cycle: OTAA vs ABP
|
||||
* @param None
|
||||
* @retval ENABLE / DISABLE
|
||||
*/
|
||||
lw_state_t lw_config_duty_cycle_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get Device EUI
|
||||
* @param None
|
||||
* @retval DevEUI
|
||||
*/
|
||||
uint8_t *lw_config_deveui_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get Join Eui
|
||||
* @param None
|
||||
* @retval JoinEUI
|
||||
*/
|
||||
uint8_t *lw_config_joineui_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set Join Eui
|
||||
* @param JoinEUI
|
||||
* @retval Nonoe
|
||||
*/
|
||||
void lw_config_joineui_set(uint8_t joineui[8]);
|
||||
|
||||
/**
|
||||
* @brief Get Application Key
|
||||
* @param None
|
||||
* @retval AppKey
|
||||
*/
|
||||
uint8_t *lw_config_appkey_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set Application Key
|
||||
* @param AppKey
|
||||
* @retval None
|
||||
*/
|
||||
void lw_config_appkey_set(uint8_t appkey[16]);
|
||||
|
||||
/**
|
||||
* @brief Set whether or not acknowledgement is required
|
||||
* @param ENABLE or DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void lw_config_reqack_set(LoraConfirm_t reqack);
|
||||
|
||||
/**
|
||||
* @brief Get whether or not acknowledgement is required
|
||||
* @param None
|
||||
* @retval ENABLE or DISABLE
|
||||
*/
|
||||
LoraConfirm_t lw_config_reqack_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the SNR of the last received data
|
||||
* @param None
|
||||
* @retval SNR
|
||||
*/
|
||||
int8_t lw_config_snr_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the RSSI of the last received data
|
||||
* @param None
|
||||
* @retval RSSI
|
||||
*/
|
||||
int16_t lw_config_rssi_get(void);
|
||||
|
||||
/**
|
||||
* @brief set tx datarate
|
||||
* @param None
|
||||
* @retval The application port
|
||||
*/
|
||||
void lw_config_tx_datarate_set(int8_t TxDataRate);
|
||||
|
||||
/**
|
||||
* @brief get tx datarate
|
||||
* @param None
|
||||
* @retval tx datarate
|
||||
*/
|
||||
int8_t lw_config_tx_datarate_get(void);
|
||||
|
||||
/**
|
||||
* @brief get LoRaMac region
|
||||
* @param None
|
||||
* @retval LoRaMac region
|
||||
*/
|
||||
LoRaMacRegion_t lw_region_get(void);
|
||||
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
|
||||
LoRaMacClassBNvmCtx_t* LORA_Get_ClassBCtx(void);
|
||||
uint8_t LORA_Get_PingSlotPeriodicity(void);
|
||||
void LORA_Set_PingSlotPeriodicity(uint8_t PingSlotPeriodicity);
|
||||
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__LORA_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lorawan_info.c
|
||||
* @author MCD Application Team
|
||||
* @brief To give info to the application about LoraWAN configuration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lorawan_info.h"
|
||||
#include "LoRaMac.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
LoRaMacInfo_t LoRaMacInfoTable;
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/**
|
||||
* @brief initialises the LoraMacInfo capabilities table
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void LoraMacInfo_Init(void)
|
||||
{
|
||||
LoRaMacInfoTable.Region = 0;
|
||||
#ifdef REGION_AS923
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_AS923) ;
|
||||
#endif
|
||||
#ifdef REGION_AU915
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_AU915) ;
|
||||
#endif
|
||||
#ifdef REGION_CN470
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_CN470) ;
|
||||
#endif
|
||||
#ifdef REGION_CN470ALI
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_CN470ALI);
|
||||
#endif
|
||||
#ifdef REGION_CN779
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_CN779) ;
|
||||
#endif
|
||||
#ifdef REGION_EU433
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_EU433) ;
|
||||
#endif
|
||||
#ifdef REGION_EU868
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_EU868) ;
|
||||
#endif
|
||||
#ifdef REGION_KR920
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_KR920) ;
|
||||
#endif
|
||||
#ifdef REGION_IN865
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_IN865) ;
|
||||
#endif
|
||||
#ifdef REGION_US915
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_US915) ;
|
||||
#endif
|
||||
#ifdef REGION_RU864
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_RU864) ;
|
||||
#endif
|
||||
|
||||
#ifdef LORAMAC_CLASSB_ENABLED
|
||||
LoRaMacInfoTable.ClassB = 1;
|
||||
#else
|
||||
LoRaMacInfoTable.ClassB = 0;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the pointer to the LoraMacInfo capabilities table
|
||||
* @param none
|
||||
* @retval LoRaMacInfoTable pointer
|
||||
*/
|
||||
LoRaMacInfo_t* LoraMacInfo_GetPtr(void)
|
||||
{
|
||||
return &LoRaMacInfoTable;
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lorawan_info.h
|
||||
* @author MCD Application Team
|
||||
* @brief To give info to the application about LoraWAN configuration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __LORAWAN_INFO_H__
|
||||
#define __LORAWAN_INFO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/*!
|
||||
* To give info to the application about LoraWAN capability
|
||||
* it can depend how it has been compiled (e.g. compiled regions ...)
|
||||
* Params should be better uint32_t foe easier alignment with info_table concept
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Region; /*!< Combination of regions compiled on MW */
|
||||
uint32_t ClassB; /*!< 0: not compiled in Mw, 1 : compiled in MW */
|
||||
}LoRaMacInfo_t;
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief initialises the LoraMacInfo table
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void LoraMacInfo_Init(void);
|
||||
|
||||
/**
|
||||
* @brief returns the pointer to the LoraMacInfo table
|
||||
* @param none
|
||||
* @retval LoRaMacInfoTable pointer
|
||||
*/
|
||||
LoRaMacInfo_t* LoraMacInfo_GetPtr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAWAN_INFO_H__
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file app_conf_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief applic configuration, e.g. : debug, trace, low power, sensors
|
||||
* @note this is a template: the app_conf.h shall be defined in the Project/...
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __APP_CONF_H__
|
||||
#define __APP_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* LoraWAN application configuration (Mw is configured by lorawan_conf.h) */
|
||||
#define ACTIVE_REGION LORAMAC_REGION_EU868
|
||||
#define HYBRID_ENABLED 0
|
||||
|
||||
#define LORAMAC_CLASSB_ACTIVE 0 /* 0 if not active, 1 if active */
|
||||
|
||||
/* Enable trace logs. Note verbose level can be selected in app_system.h */
|
||||
#define APP_LOG_ENABLED 1
|
||||
|
||||
#define DEBUGGER_ON 0 /* if ON (=1) it enables the debbugger plus 4 dgb pins */
|
||||
/* if OFF (=0) the debugger is OFF (lower consumption) */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_CONF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file app_system_template.h
|
||||
* @author MCD Application Team
|
||||
* @brief function prototypes for app_system.c file
|
||||
* @note this is a template: the app_conf.h shall be defined in the Project/...
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __APP_SYSTEM_H__
|
||||
#define __APP_SYSTEM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include "app_conf.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define VERBOSE_LEVEL VLEVEL_L
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
#define APP_PPRINTF(...) do{ } while( 0!= TraceSend(0, 0, __VA_ARGS__) ) //Polling Mode
|
||||
#define APP_TPRINTF(...) do{ {TraceSend(1, 0, __VA_ARGS__);} }while(0); //with timestamp
|
||||
#define APP_PRINTF(...) do{ {TraceSend(0, 0, __VA_ARGS__);} }while(0);
|
||||
|
||||
|
||||
#if defined (APP_LOG_ENABLED) && (APP_LOG_ENABLED == 1)
|
||||
#define APP_LOG(TS,VL,...) do{ {TraceSend(TS, VL, __VA_ARGS__);} }while(0);
|
||||
#elif defined (APP_LOG_ENABLED) && (APP_LOG_ENABLED == 0) /* APP_LOG disabled */
|
||||
#define APP_LOG(TS,VL,...)
|
||||
#else
|
||||
#error "APP_LOG_ENABLED not defined or out of range <0,1>"
|
||||
#endif
|
||||
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __APP_SYSTEM_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/******************************************************************************
|
||||
* @file lora-test.c
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stddef.h"
|
||||
//#include "lorawan_conf.h" /* Don't remove: needed for LORAMAC_CLASSB_ENABLED */
|
||||
//#include "mw_log_conf.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "LoRaMacTest.h"
|
||||
#include "lora.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
typedef struct ComplianceTest_s
|
||||
{
|
||||
bool Running;
|
||||
uint8_t State;
|
||||
LoraConfirm_t IsTxConfirmed;
|
||||
uint8_t DataBufferSize;
|
||||
uint8_t DataBuffer[242]; /* max possible payload */
|
||||
uint16_t DownLinkCounter;
|
||||
bool LinkCheck;
|
||||
uint8_t DemodMargin;
|
||||
uint8_t NbGateways;
|
||||
} ComplianceTest_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CERTIF_TX_PROCESS = 0,
|
||||
CERTIF_RX_PROCESS
|
||||
} requestProcess_t;
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define TEST_TX_DUTYCYCLE 5000
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
|
||||
static requestProcess_t requested_process_id;
|
||||
|
||||
/*!
|
||||
* Timer to handle the application data transmission duty cycle
|
||||
*/
|
||||
static TimerEvent_t CertifTxNextPacketTimer;
|
||||
|
||||
static ComplianceTest_t certifParam;
|
||||
static LoraConfirm_t IsTxConfirmed;
|
||||
static bool AdrEnableInit;
|
||||
static McpsIndication_t *CertifMcpsIndication;
|
||||
static MlmeReqJoin_t *CertifJoinParameters;
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
static bool CERTIF_running(void);
|
||||
|
||||
static void CERTIF_DownLinkIncrement(void);
|
||||
|
||||
static void CERTIF_linkCheck(MlmeConfirm_t *mlmeConfirm);
|
||||
|
||||
static void CERTIF_rx_request(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
static void CERTIF_rx(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
static bool CERTIF_tx(void);
|
||||
|
||||
static void OnCertifTxNextPacketTimerEvent(void *context);
|
||||
|
||||
static void (*CertifProcessNotify)(void);
|
||||
|
||||
static LoRaCertifCallback_t certifCb =
|
||||
{
|
||||
CERTIF_running,
|
||||
CERTIF_DownLinkIncrement,
|
||||
CERTIF_linkCheck,
|
||||
CERTIF_rx_request,
|
||||
};
|
||||
|
||||
/* Exported functions definition---------------------------------------------------------*/
|
||||
|
||||
void CERTIF_Init(void (*CERTIF_ProcessNotify)(void))
|
||||
{
|
||||
/*initialises Callback into the Lora.c layer*/
|
||||
LORA_TestInit(&certifCb);
|
||||
/*Register TestProcessNotify callback*/
|
||||
CertifProcessNotify = CERTIF_ProcessNotify;
|
||||
}
|
||||
|
||||
void CERTIF_Process(void)
|
||||
{
|
||||
switch (requested_process_id)
|
||||
{
|
||||
case CERTIF_TX_PROCESS:
|
||||
CERTIF_tx();
|
||||
break;
|
||||
case CERTIF_RX_PROCESS:
|
||||
CERTIF_rx(CertifMcpsIndication, CertifJoinParameters);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static bool CERTIF_running(void)
|
||||
{
|
||||
return certifParam.Running;
|
||||
}
|
||||
|
||||
static void CERTIF_DownLinkIncrement(void)
|
||||
{
|
||||
certifParam.DownLinkCounter++;
|
||||
}
|
||||
|
||||
static void CERTIF_linkCheck(MlmeConfirm_t *mlmeConfirm)
|
||||
{
|
||||
certifParam.LinkCheck = true;
|
||||
certifParam.DemodMargin = mlmeConfirm->DemodMargin;
|
||||
certifParam.NbGateways = mlmeConfirm->NbGateways;
|
||||
}
|
||||
|
||||
static bool CERTIF_tx(void)
|
||||
{
|
||||
McpsReq_t mcpsReq;
|
||||
LoRaMacTxInfo_t txInfo;
|
||||
|
||||
if (certifParam.LinkCheck == true)
|
||||
{
|
||||
certifParam.LinkCheck = false;
|
||||
certifParam.DataBufferSize = 3;
|
||||
certifParam.DataBuffer[0] = 5;
|
||||
certifParam.DataBuffer[1] = certifParam.DemodMargin;
|
||||
certifParam.DataBuffer[2] = certifParam.NbGateways;
|
||||
certifParam.State = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (certifParam.State)
|
||||
{
|
||||
case 4:
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 1:
|
||||
certifParam.DataBufferSize = 2;
|
||||
certifParam.DataBuffer[0] = certifParam.DownLinkCounter >> 8;
|
||||
certifParam.DataBuffer[1] = certifParam.DownLinkCounter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (LoRaMacQueryTxPossible(certifParam.DataBufferSize, &txInfo) != LORAMAC_STATUS_OK)
|
||||
{
|
||||
// Send empty frame in order to flush MAC commands
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
|
||||
mcpsReq.Req.Unconfirmed.Datarate = DR_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsTxConfirmed == LORAWAN_UNCONFIRMED_MSG)
|
||||
{
|
||||
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||
mcpsReq.Req.Unconfirmed.fPort = CERTIF_PORT;
|
||||
mcpsReq.Req.Unconfirmed.fBufferSize = certifParam.DataBufferSize;
|
||||
mcpsReq.Req.Unconfirmed.fBuffer = &(certifParam.DataBuffer);
|
||||
mcpsReq.Req.Unconfirmed.Datarate = DR_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mcpsReq.Type = MCPS_CONFIRMED;
|
||||
mcpsReq.Req.Confirmed.fPort = CERTIF_PORT;
|
||||
mcpsReq.Req.Confirmed.fBufferSize = certifParam.DataBufferSize;
|
||||
mcpsReq.Req.Confirmed.fBuffer = &(certifParam.DataBuffer);
|
||||
mcpsReq.Req.Confirmed.NbTrials = 8;
|
||||
mcpsReq.Req.Confirmed.Datarate = DR_0;
|
||||
}
|
||||
}
|
||||
|
||||
/*cerification test on-going*/
|
||||
TimerStart(&CertifTxNextPacketTimer);
|
||||
|
||||
if (LoRaMacMcpsRequest(&mcpsReq) == LORAMAC_STATUS_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CERTIF_rx_request(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters)
|
||||
{
|
||||
CertifMcpsIndication = mcpsIndication;
|
||||
CertifJoinParameters = JoinParameters;
|
||||
|
||||
requested_process_id = CERTIF_RX_PROCESS;
|
||||
|
||||
CertifProcessNotify();
|
||||
}
|
||||
|
||||
static void CERTIF_rx(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters)
|
||||
{
|
||||
if (certifParam.Running == false)
|
||||
{
|
||||
// Check compliance test enable command (i)
|
||||
if ((mcpsIndication->BufferSize == 4) &&
|
||||
(mcpsIndication->Buffer[0] == 0x01) &&
|
||||
(mcpsIndication->Buffer[1] == 0x01) &&
|
||||
(mcpsIndication->Buffer[2] == 0x01) &&
|
||||
(mcpsIndication->Buffer[3] == 0x01))
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
IsTxConfirmed = LORAWAN_UNCONFIRMED_MSG;
|
||||
certifParam.DataBufferSize = 2;
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.LinkCheck = false;
|
||||
certifParam.DemodMargin = 0;
|
||||
certifParam.NbGateways = 0;
|
||||
certifParam.Running = true;
|
||||
certifParam.State = 1;
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
|
||||
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||
AdrEnableInit = mibReq.Param.AdrEnable;
|
||||
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = true;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if ( (ACTIVE_REGION == LORAMAC_REGION_EU868)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_RU864)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_CN779)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_EU433))
|
||||
{
|
||||
LoRaMacTestSetDutyCycleOn(false);
|
||||
}
|
||||
|
||||
TimerInit(&CertifTxNextPacketTimer, OnCertifTxNextPacketTimerEvent);
|
||||
TimerSetValue(&CertifTxNextPacketTimer, TEST_TX_DUTYCYCLE);
|
||||
|
||||
/*confirm test mode activation */
|
||||
CERTIF_tx();
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
certifParam.State = mcpsIndication->Buffer[0];
|
||||
switch (certifParam.State)
|
||||
{
|
||||
case 0: // Check compliance test disable command (ii)
|
||||
{
|
||||
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.Running = false;
|
||||
|
||||
MibRequestConfirm_t mibReq;
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = AdrEnableInit;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
if ( (ACTIVE_REGION == LORAMAC_REGION_EU868)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_RU864)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_CN779)
|
||||
|| (ACTIVE_REGION == LORAMAC_REGION_EU433))
|
||||
{
|
||||
LoRaMacTestSetDutyCycleOn(true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: // (iii, iv)
|
||||
certifParam.DataBufferSize = 2;
|
||||
break;
|
||||
case 2: // Enable confirmed messages (v)
|
||||
IsTxConfirmed = LORAWAN_CONFIRMED_MSG;
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 3: // Disable confirmed messages (vi)
|
||||
IsTxConfirmed = LORAWAN_UNCONFIRMED_MSG;
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
case 4: // (vii)
|
||||
certifParam.DataBufferSize = mcpsIndication->BufferSize;
|
||||
|
||||
certifParam.DataBuffer[0] = 4;
|
||||
for (uint8_t i = 1; i < certifParam.DataBufferSize; i++)
|
||||
{
|
||||
certifParam.DataBuffer[i] = mcpsIndication->Buffer[i] + 1;
|
||||
}
|
||||
break;
|
||||
case 5: // (viii)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_LINK_CHECK;
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
case 6: // (ix)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
// Disable TestMode and revert back to normal operation
|
||||
|
||||
certifParam.DownLinkCounter = 0;
|
||||
certifParam.Running = false;
|
||||
|
||||
MibRequestConfirm_t mibReq;
|
||||
mibReq.Type = MIB_ADR;
|
||||
mibReq.Param.AdrEnable = AdrEnableInit;
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
|
||||
mlmeReq.Type = MLME_JOIN;
|
||||
mlmeReq.Req.Join = *JoinParameters;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // (x)
|
||||
{
|
||||
if (mcpsIndication->BufferSize == 3)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_TXCW;
|
||||
mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]);
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
else if (mcpsIndication->BufferSize == 7)
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
mlmeReq.Type = MLME_TXCW_1;
|
||||
mlmeReq.Req.TxCw.Timeout = (uint16_t)((mcpsIndication->Buffer[1] << 8) | mcpsIndication->Buffer[2]);
|
||||
mlmeReq.Req.TxCw.Frequency = (uint32_t)((mcpsIndication->Buffer[3] << 16) | (mcpsIndication->Buffer[4] << 8) | mcpsIndication->Buffer[5]) * 100;
|
||||
mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
}
|
||||
certifParam.State = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: // Send DeviceTimeReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_DEVICE_TIME;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
case 9: // Switch end device Class
|
||||
{
|
||||
MibRequestConfirm_t mibReq;
|
||||
|
||||
mibReq.Type = MIB_DEVICE_CLASS;
|
||||
// CLASS_A = 0, CLASS_B = 1, CLASS_C = 2
|
||||
mibReq.Param.Class = (DeviceClass_t)mcpsIndication->Buffer[1];
|
||||
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||
break;
|
||||
}
|
||||
case 10: // Send PingSlotInfoReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_PING_SLOT_INFO;
|
||||
|
||||
mlmeReq.Req.PingSlotInfo.PingSlot.Value = mcpsIndication->Buffer[1];
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
case 11: // Send BeaconTimingReq
|
||||
{
|
||||
MlmeReq_t mlmeReq;
|
||||
|
||||
mlmeReq.Type = MLME_BEACON_TIMING;
|
||||
|
||||
LoRaMacMlmeRequest(&mlmeReq);
|
||||
break;
|
||||
}
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (certifParam.Running == false)
|
||||
{
|
||||
/*certification test stops*/
|
||||
TimerStop(&CertifTxNextPacketTimer);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Function executed on TxNextPacket Timeout event
|
||||
*/
|
||||
static void OnCertifTxNextPacketTimerEvent(void *context)
|
||||
{
|
||||
requested_process_id = CERTIF_TX_PROCESS;
|
||||
CertifProcessNotify();
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/******************************************************************************
|
||||
* @file lora_test.h
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __LORA_TEST_H__
|
||||
#define __LORA_TEST_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define CERTIF_PORT 224
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Certification Initialisation
|
||||
* @param [IN] Notification call back to the appl that a CERTIF_Process must be called
|
||||
* @retval none
|
||||
*/
|
||||
void CERTIF_Init(void (*CERTIF_ProcessNotify)(void));
|
||||
/**
|
||||
* @brief CERTIF_Process to be called when a CERTIF_ProcessNotify callback is generated
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
void CERTIF_Process(void);
|
||||
|
||||
/* Lora Test callbacks*/
|
||||
typedef struct sLoRaCertifCallback
|
||||
{
|
||||
bool (*running)(void);
|
||||
|
||||
void (*DownLinkIncrement)(void);
|
||||
|
||||
void (*linkCheck)(MlmeConfirm_t *mlmeConfirm);
|
||||
|
||||
void (*rx)(McpsIndication_t *mcpsIndication, MlmeReqJoin_t *JoinParameters);
|
||||
|
||||
} LoRaCertifCallback_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__LORA_TEST_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,403 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lora.h
|
||||
* @author MCD Application Team
|
||||
* @brief lora API to drive the lora state Machine
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __LORA_H__
|
||||
#define __LORA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "Commissioning.h"
|
||||
#include "LoRaMac.h"
|
||||
#include "app_conf.h"
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
#include "LoRaMacClassB.h"
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif /* LORAMAC_CLASSB_ACTIVE */
|
||||
|
||||
#include "region/Region.h"
|
||||
#include "lora-test.h"
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/*!
|
||||
* LoRaWAN confirmed messages
|
||||
*/
|
||||
|
||||
#define LORAWAN_ADR_ON 1
|
||||
#define LORAWAN_ADR_OFF 0
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/*!
|
||||
* Application Data structure
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*point to the LoRa App data buffer*/
|
||||
uint8_t *Buff;
|
||||
/*LoRa App data buffer size*/
|
||||
uint8_t BuffSize;
|
||||
/*Port on which the LoRa App is data is sent/ received*/
|
||||
uint8_t Port;
|
||||
|
||||
} lora_AppData_t;
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_RESET = 0,
|
||||
LORA_SET = !LORA_RESET
|
||||
} LoraFlagStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_DISABLE = 0,
|
||||
LORA_ENABLE = !LORA_DISABLE
|
||||
} LoraState_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_ERROR = -1,
|
||||
LORA_SUCCESS = 0
|
||||
} LoraErrorStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORAWAN_UNCONFIRMED_MSG = 0,
|
||||
LORAWAN_CONFIRMED_MSG = !LORAWAN_UNCONFIRMED_MSG
|
||||
} LoraConfirm_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LORA_TRUE = 0,
|
||||
LORA_FALSE = !LORA_TRUE
|
||||
} LoraBool_t;
|
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/
|
||||
typedef enum eTxEventType
|
||||
{
|
||||
/*!
|
||||
* @brief AppdataTransmition issue based on timer every TxDutyCycleTime
|
||||
*/
|
||||
TX_ON_TIMER,
|
||||
/*!
|
||||
* @brief AppdataTransmition external event plugged on OnSendEvent( )
|
||||
*/
|
||||
TX_ON_EVENT
|
||||
} TxEventType_t;
|
||||
|
||||
|
||||
/*!
|
||||
* LoRa State Machine states
|
||||
*/
|
||||
typedef struct sLoRaParam
|
||||
{
|
||||
/*!
|
||||
* @brief Activation state of adaptativeDatarate
|
||||
*/
|
||||
bool AdrEnable;
|
||||
/*!
|
||||
* @brief Uplink datarate, if AdrEnable is off
|
||||
*/
|
||||
int8_t TxDatarate;
|
||||
/*!
|
||||
* @brief Enable or disable a public network
|
||||
*/
|
||||
bool EnablePublicNetwork;
|
||||
/*!
|
||||
* @brief region to open
|
||||
*/
|
||||
LoRaMacRegion_t ActiveRegion;
|
||||
} LoRaParam_t;
|
||||
|
||||
/* Lora Main callbacks*/
|
||||
typedef struct sLoRaMainCallback
|
||||
{
|
||||
/*!
|
||||
* @brief Get the current battery level
|
||||
*
|
||||
* @retval value battery level ( 0: very low, 254: fully charged )
|
||||
*/
|
||||
uint8_t (*BoardGetBatteryLevel)(void);
|
||||
/*!
|
||||
* \brief Get the current temperature
|
||||
*
|
||||
* \retval value temperature in degreeCelcius( q7.8 )
|
||||
*/
|
||||
uint16_t (*BoardGetTemperatureLevel)(void);
|
||||
/*!
|
||||
* @brief Gets the board 64 bits unique ID
|
||||
*
|
||||
* @param [IN] id Pointer to an array that will contain the Unique ID
|
||||
*/
|
||||
void (*BoardGetUniqueId)(uint8_t *id);
|
||||
/*!
|
||||
* Returns a pseudo random seed generated using the MCU Unique ID
|
||||
*
|
||||
* @retval seed Generated pseudo random seed
|
||||
*/
|
||||
uint32_t (*BoardGetRandomSeed)(void);
|
||||
/*!
|
||||
* @brief Process Rx Data received from Lora network
|
||||
*
|
||||
* @param [IN] AppData structure
|
||||
*
|
||||
*/
|
||||
void (*LORA_RxData)(lora_AppData_t *AppData);
|
||||
|
||||
/*!
|
||||
* @brief callback indicating EndNode has jsu joiny
|
||||
*
|
||||
* @param [IN] None
|
||||
*/
|
||||
void (*LORA_HasJoined)(void);
|
||||
/*!
|
||||
* @brief Confirms the class change
|
||||
*
|
||||
* @param [IN] AppData is a buffer to process
|
||||
*
|
||||
* @param [IN] port is a Application port on wicth Appdata will be sent
|
||||
*
|
||||
* @param [IN] length is the number of recieved bytes
|
||||
*/
|
||||
void (*LORA_ConfirmClass)(DeviceClass_t Class);
|
||||
/*!
|
||||
* @brief callback indicating an uplink transmission is needed to allow
|
||||
* a pending downlink transmission
|
||||
*
|
||||
* @param [IN] None
|
||||
*/
|
||||
void (*LORA_TxNeeded)(void);
|
||||
/*!
|
||||
*\brief Will be called each time a Radio IRQ is handled by the MAC
|
||||
* layer.
|
||||
*
|
||||
*\warning Runs in a IRQ context. Should only change variables state.
|
||||
*/
|
||||
void (*MacProcessNotify)(void);
|
||||
/*!
|
||||
* @brief callback indicating a downlink transmission providing
|
||||
* an acknowledgment for an uplink confirmed data message transmission
|
||||
*
|
||||
* @param [IN] None
|
||||
*/
|
||||
void (*LORA_McpsDataConfirm)(void);
|
||||
} LoRaMainCallback_t;
|
||||
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
/**
|
||||
* @brief Lora Initialisation
|
||||
* @param [IN] LoRaMainCallback_t
|
||||
* @param [IN] application parmaters
|
||||
* @retval none
|
||||
*/
|
||||
void LORA_Init(LoRaMainCallback_t *callbacks, LoRaParam_t *LoRaParam);
|
||||
|
||||
/**
|
||||
* @brief Lora Certif Initialisation (Registers CB)
|
||||
* @param [IN] LoRaCertifCallback_t
|
||||
* @retval none
|
||||
*/
|
||||
void LORA_TestInit(LoRaCertifCallback_t *callbacks);
|
||||
/**
|
||||
* @brief run Lora classA state Machine
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
LoraErrorStatus LORA_send(lora_AppData_t *AppData, LoraConfirm_t IsTxConfirmed);
|
||||
|
||||
/**
|
||||
* @brief Join a Lora Network in classA
|
||||
* @Note if the device is ABP, this is a pass through functon
|
||||
* @param [IN] none
|
||||
* @retval none
|
||||
*/
|
||||
LoraErrorStatus LORA_Join(void);
|
||||
|
||||
/**
|
||||
* @brief Check whether the Device is joined to the network
|
||||
* @param [IN] none
|
||||
* @retval returns LORA_SET if joined
|
||||
*/
|
||||
LoraFlagStatus LORA_JoinStatus(void);
|
||||
|
||||
/**
|
||||
* @brief change Lora Class
|
||||
* @Note callback LORA_ConfirmClass informs upper layer that the change has occured
|
||||
* @Note Only switch from class A to class B/C OR from class B/C to class A is allowed
|
||||
* @Attention can be calld only in LORA_ClassSwitchSlot or LORA_RxData callbacks
|
||||
* @param [IN] DeviceClass_t NewClass
|
||||
* @retval LoraErrorStatus
|
||||
*/
|
||||
LoraErrorStatus LORA_RequestClass(DeviceClass_t newClass);
|
||||
|
||||
/**
|
||||
* @brief get the current Lora Class
|
||||
* @param [IN] DeviceClass_t NewClass
|
||||
* @retval None
|
||||
*/
|
||||
void LORA_GetCurrentClass(DeviceClass_t *currentClass);
|
||||
|
||||
/**
|
||||
* @brief Set join activation process: OTAA vs ABP
|
||||
* @param Over The Air Activation status to set: enable or disable
|
||||
* @retval None
|
||||
*/
|
||||
void lora_config_otaa_set(LoraState_t otaa);
|
||||
|
||||
/**
|
||||
* @brief Get join activation process: OTAA vs ABP
|
||||
* @param None
|
||||
* @retval ENABLE if OTAA is used, DISABLE if ABP is used
|
||||
*/
|
||||
LoraState_t lora_config_otaa_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set duty cycle: ENABLE or DISABLE
|
||||
* @param Duty cycle to set: enable or disable
|
||||
* @retval None
|
||||
*/
|
||||
void lora_config_duty_cycle_set(LoraState_t duty_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get Duty cycle: OTAA vs ABP
|
||||
* @param None
|
||||
* @retval ENABLE / DISABLE
|
||||
*/
|
||||
LoraState_t lora_config_duty_cycle_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get Device EUI
|
||||
* @param None
|
||||
* @retval DevEUI
|
||||
*/
|
||||
uint8_t *lora_config_deveui_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get Join Eui
|
||||
* @param None
|
||||
* @retval JoinEUI
|
||||
*/
|
||||
uint8_t *lora_config_joineui_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set Join Eui
|
||||
* @param JoinEUI
|
||||
* @retval Nonoe
|
||||
*/
|
||||
void lora_config_joineui_set(uint8_t joineui[8]);
|
||||
|
||||
/**
|
||||
* @brief Get Application Key
|
||||
* @param None
|
||||
* @retval AppKey
|
||||
*/
|
||||
uint8_t *lora_config_appkey_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set Application Key
|
||||
* @param AppKey
|
||||
* @retval None
|
||||
*/
|
||||
void lora_config_appkey_set(uint8_t appkey[16]);
|
||||
|
||||
/**
|
||||
* @brief Set whether or not acknowledgement is required
|
||||
* @param ENABLE or DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void lora_config_reqack_set(LoraConfirm_t reqack);
|
||||
|
||||
/**
|
||||
* @brief Get whether or not acknowledgement is required
|
||||
* @param None
|
||||
* @retval ENABLE or DISABLE
|
||||
*/
|
||||
LoraConfirm_t lora_config_reqack_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the SNR of the last received data
|
||||
* @param None
|
||||
* @retval SNR
|
||||
*/
|
||||
int8_t lora_config_snr_get(void);
|
||||
|
||||
/**
|
||||
* @brief Get the RSSI of the last received data
|
||||
* @param None
|
||||
* @retval RSSI
|
||||
*/
|
||||
int16_t lora_config_rssi_get(void);
|
||||
|
||||
/**
|
||||
* @brief Launch LoraWan certification tests
|
||||
* @param None
|
||||
* @retval The application port
|
||||
*/
|
||||
void lora_wan_certif(void);
|
||||
|
||||
/**
|
||||
* @brief set tx datarate
|
||||
* @param None
|
||||
* @retval The application port
|
||||
*/
|
||||
void lora_config_tx_datarate_set(int8_t TxDataRate);
|
||||
|
||||
/**
|
||||
* @brief get tx datarate
|
||||
* @param None
|
||||
* @retval tx datarate
|
||||
*/
|
||||
int8_t lora_config_tx_datarate_get(void);
|
||||
|
||||
/**
|
||||
* @brief get LoRaMac region
|
||||
* @param None
|
||||
* @retval LoRaMac region
|
||||
*/
|
||||
LoRaMacRegion_t lora_region_get(void);
|
||||
|
||||
#if defined (LORAMAC_CLASSB_ACTIVE) && ( LORAMAC_CLASSB_ACTIVE == 1 )
|
||||
|
||||
LoRaMacClassBNvmCtx_t* LORA_Get_ClassBCtx(void);
|
||||
uint8_t LORA_Get_PingSlotPeriodicity(void);
|
||||
void LORA_Set_PingSlotPeriodicity(uint8_t PingSlotPeriodicity);
|
||||
|
||||
#elif !defined (LORAMAC_CLASSB_ACTIVE)
|
||||
#error LORAMAC_CLASSB_ACTIVE not defined
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__LORA_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lorawan_info.c
|
||||
* @author MCD Application Team
|
||||
* @brief To give info to the application about LoraWAN configuration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lorawan_info.h"
|
||||
#include "LoRaMac.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported variables --------------------------------------------------------*/
|
||||
|
||||
LoRaMacInfo_t LoRaMacInfoTable;
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/**
|
||||
* @brief initialises the LoraMacInfo capabilities table
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void LoraMacInfo_Init(void)
|
||||
{
|
||||
LoRaMacInfoTable.Region = 0;
|
||||
#ifdef REGION_AS923
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_AS923) ;
|
||||
#endif
|
||||
#ifdef REGION_AU915
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_AU915) ;
|
||||
#endif
|
||||
#ifdef REGION_CN470
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_CN470) ;
|
||||
#endif
|
||||
#ifdef REGION_CN779
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_CN779) ;
|
||||
#endif
|
||||
#ifdef REGION_EU433
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_EU433) ;
|
||||
#endif
|
||||
#ifdef REGION_EU868
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_EU868) ;
|
||||
#endif
|
||||
#ifdef REGION_KR920
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_KR920) ;
|
||||
#endif
|
||||
#ifdef REGION_IN865
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_IN865) ;
|
||||
#endif
|
||||
#ifdef REGION_US915
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_US915) ;
|
||||
#endif
|
||||
#ifdef REGION_RU864
|
||||
LoRaMacInfoTable.Region |= (1<<LORAMAC_REGION_RU864) ;
|
||||
#endif
|
||||
|
||||
#ifdef LORAMAC_CLASSB_ENABLED
|
||||
LoRaMacInfoTable.ClassB = 1;
|
||||
#else
|
||||
LoRaMacInfoTable.ClassB = 0;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the pointer to the LoraMacInfo capabilities table
|
||||
* @param none
|
||||
* @retval LoRaMacInfoTable pointer
|
||||
*/
|
||||
LoRaMacInfo_t* LoraMacInfo_GetPtr(void)
|
||||
{
|
||||
return &LoRaMacInfoTable;
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lorawan_info.h
|
||||
* @author MCD Application Team
|
||||
* @brief To give info to the application about LoraWAN configuration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __LORAWAN_INFO_H__
|
||||
#define __LORAWAN_INFO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
|
||||
/*!
|
||||
* To give info to the application about LoraWAN capability
|
||||
* it can depend how it has been compiled (e.g. compiled regions ...)
|
||||
* Params should be better uint32_t foe easier alignment with info_table concept
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Region; /*!< Combination of regions compiled on MW */
|
||||
uint32_t ClassB; /*!< 0: not compiled in Mw, 1 : compiled in MW */
|
||||
}LoRaMacInfo_t;
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief initialises the LoraMacInfo table
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void LoraMacInfo_Init(void);
|
||||
|
||||
/**
|
||||
* @brief returns the pointer to the LoraMacInfo table
|
||||
* @param none
|
||||
* @retval LoRaMacInfoTable pointer
|
||||
*/
|
||||
LoRaMacInfo_t* LoraMacInfo_GetPtr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __LORAWAN_INFO_H__
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
|
||||
Description: Helper functions implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian
|
||||
*/
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* Portions COPYRIGHT 2019 STMicroelectronics
|
||||
*
|
||||
* @file utilities.c
|
||||
* @author MCD Application Team
|
||||
* @brief Helper functions implementation
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
/*!
|
||||
* Redefinition of rand() and srand() standard C functions.
|
||||
* These functions are redefined in order to get the same behavior across
|
||||
* different compiler toolchains implementations.
|
||||
*/
|
||||
// Standard random functions redefinition start
|
||||
#define RAND_LOCAL_MAX 2147483647L
|
||||
|
||||
static uint32_t next = 1;
|
||||
|
||||
int32_t rand1( void )
|
||||
{
|
||||
return ( ( next = next * 1103515245L + 12345L ) % RAND_LOCAL_MAX );
|
||||
}
|
||||
|
||||
void srand1( uint32_t seed )
|
||||
{
|
||||
next = seed;
|
||||
}
|
||||
// Standard random functions redefinition end
|
||||
|
||||
int32_t randr( int32_t min, int32_t max )
|
||||
{
|
||||
return ( int32_t )rand1( ) % ( max - min + 1 ) + min;
|
||||
}
|
||||
|
||||
void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size )
|
||||
{
|
||||
while( size-- )
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size )
|
||||
{
|
||||
dst = dst + ( size - 1 );
|
||||
while( size-- )
|
||||
{
|
||||
*dst-- = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
void memset1( uint8_t *dst, uint8_t value, uint16_t size )
|
||||
{
|
||||
while( size-- )
|
||||
{
|
||||
*dst++ = value;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t Nibble2HexChar( uint8_t a )
|
||||
{
|
||||
if( a < 10 )
|
||||
{
|
||||
return '0' + a;
|
||||
}
|
||||
else if( a < 16 )
|
||||
{
|
||||
return 'A' + ( a - 10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
|
||||
Description: Helper functions implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian
|
||||
*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* Portions COPYRIGHT 2019 STMicroelectronics
|
||||
*
|
||||
* @file utilities.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header for driver utilities.c module
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __UTILITIES_H__
|
||||
#define __UTILITIES_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include "utilities_conf.h"
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Defines -------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#define TIMERTIME_T_MAX ( ( uint32_t )~0 )
|
||||
|
||||
/*!
|
||||
* @brief Returns the minimum value between a and b
|
||||
*
|
||||
* @param [IN] a 1st value
|
||||
* @param [IN] b 2nd value
|
||||
* @retval minValue Minimum value
|
||||
*/
|
||||
#ifndef MIN
|
||||
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Returns the maximum value between a and b
|
||||
*
|
||||
* @param [IN] a 1st value
|
||||
* @param [IN] b 2nd value
|
||||
* @retval maxValue Maximum value
|
||||
*/
|
||||
#ifndef MAX
|
||||
#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Returns 2 raised to the power of n
|
||||
*
|
||||
* @param [IN] n power value
|
||||
* @retval result of raising 2 to the power n
|
||||
*/
|
||||
#define POW2( n ) ( 1 << n )
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Initializes the pseudo random generator initial value
|
||||
* @param [IN] seed Pseudo random generator initial value
|
||||
* @retval none
|
||||
*/
|
||||
void srand1( uint32_t seed );
|
||||
|
||||
/*!
|
||||
* @brief Computes a random number between min and max
|
||||
* @param [IN] min range minimum value
|
||||
* @param [IN] max range maximum value
|
||||
* @retval random random value in range min..max
|
||||
*/
|
||||
int32_t randr( int32_t min, int32_t max );
|
||||
|
||||
/*!
|
||||
* @brief Computes a random number
|
||||
* @param none
|
||||
* @retval random value in range min..max
|
||||
*/
|
||||
int32_t rand1( void );
|
||||
|
||||
/*!
|
||||
* @brief Copies size elements of src array to dst array
|
||||
* @remark STM32 Standard memcpy function only works on pointers that are aligned
|
||||
* @param [OUT] dst Destination array
|
||||
* @param [IN] src Source array
|
||||
* @param [IN] size Number of bytes to be copied
|
||||
* @retval none
|
||||
*/
|
||||
void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size );
|
||||
|
||||
/*!
|
||||
* @brief Copies size elements of src array to dst array reversing the byte order
|
||||
* @param [OUT] dst Destination array
|
||||
* @param [IN] src Source array
|
||||
* @param [IN] size Number of bytes to be copied
|
||||
* @retval none
|
||||
*/
|
||||
void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size );
|
||||
|
||||
/*!
|
||||
* @brief Set size elements of dst array with value
|
||||
* @remark STM32 Standard memset function only works on pointers that are aligned
|
||||
* @param [OUT] dst Destination array
|
||||
* @param [IN] value Default value
|
||||
* @param [IN] size Number of bytes to be copied
|
||||
* @retval none
|
||||
*/
|
||||
void memset1( uint8_t *dst, uint8_t value, uint16_t size );
|
||||
|
||||
/*!
|
||||
* @brief Converts a nibble to an hexadecimal character
|
||||
* @param [IN] a Nibble to be converted
|
||||
* @retval hexChar Converted hexadecimal character
|
||||
*/
|
||||
int8_t Nibble2HexChar( uint8_t a );
|
||||
|
||||
#endif // __UTILITIES_H__
|
||||
|
|
@ -0,0 +1,771 @@
|
|||
# LoRaWAN endpoint stack implementation and example projects
|
||||
|
||||
______ _
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013-2019 Semtech
|
||||
|
||||
___ _____ _ ___ _ _____ ___ ___ ___ ___
|
||||
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
|
||||
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|
||||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
## Introduction
|
||||
|
||||
The aim of this project is to show an example of the endpoint LoRaWAN stack implementation.
|
||||
|
||||
This project has 3 active branches in place. The **[master](https://github.com/Lora-net/LoRaMac-node/tree/master)** branch which provides the latest released source code ([v4.4.2](https://github.com/Lora-net/LoRaMac-node/releases/tag/v4.4.2)), the **[develop](https://github.com/Lora-net/LoRaMac-node/tree/develop)** branch which provides the current source code development status to be released next ([Milestone 4.4.3](https://github.com/Lora-net/LoRaMac-node/milestone/4)) and the **[feature/5.0.0](https://github.com/Lora-net/LoRaMac-node/tree/feature/5.0.0)** branch which provides a preview of the current source code development status for [LoRaWAN Specification v1.1](https://lora-alliance.org/resource-hub/lorawantm-specification-v11) specification.([Milestone 5.0.0](https://github.com/Lora-net/LoRaMac-node/milestone/3))
|
||||
|
||||
* The [master](https://github.com/Lora-net/LoRaMac-node/tree/master) branch implementation is based on [LoRaWAN Specification v1.0.3](https://lora-alliance.org/resource-hub/lorawantm-specification-v103) and [LoRaWAN Regional Parameters v1.0.3revA](https://www.lora-alliance.org/resource-hub/lorawantm-regional-parameters-v103reva) specifications.
|
||||
ClassA, ClassB and ClassC end-device classes are fully implemented.
|
||||
|
||||
* The [develop](https://github.com/Lora-net/LoRaMac-node/tree/develop) branch implementation is based on [LoRaWAN Specification v1.0.3](https://lora-alliance.org/resource-hub/lorawantm-specification-v103) and [LoRaWAN Regional Parameters v1.0.3revA](https://lora-alliance.org/resource-hub/lorawan-regional-parameters-v103reva) specifications.
|
||||
ClassA, ClassB and ClassC end-device classes are fully implemented.
|
||||
|
||||
* The [feature/5.0.0](https://github.com/Lora-net/LoRaMac-node/tree/feature/5.0.0) branch implementation is based on [LoRaWAN Specification v1.1](https://lora-alliance.org/resource-hub/lorawantm-specification-v11) and [LoRaWAN Regional Parameters v1.1rB](https://lora-alliance.org/resource-hub/lorawantm-regional-parameters-v11rb) specifications.
|
||||
ClassA, ClassB and ClassC end-device classes are fully implemented.
|
||||
|
||||
This project also provides SX1272/73, SX1276/77/78/79 and SX1261/2 radio drivers.
|
||||
|
||||
For each currently supported platform example applications are provided.
|
||||
|
||||
* **LoRaMac/classA**: ClassA end-device example application.
|
||||
|
||||
* **LoRaMac/classB**: ClassB end-device example application.
|
||||
|
||||
* **LoRaMac/classC**: ClassC end-device example application.
|
||||
|
||||
* **LoRaMac/fuota-test-01**: FUOTA test scenario 01 end-device example application. (Based on provided application common packages)
|
||||
|
||||
* **LoRaMac/periodic-uplink-lpp**: ClassA/B/C end-device example application. Periodically uplinks a frame using the Cayenne LPP protocol. (Based on provided application common packages)
|
||||
|
||||
* **ping-pong**: Point to point RF link example application.
|
||||
|
||||
* **rx-sensi**: Example application useful to measure the radio sensitivity level using an RF generator.
|
||||
|
||||
* **tx-cw**: Example application to show how to generate an RF Continuous Wave transmission.
|
||||
|
||||
**Note**: *Each LoRaWAN application example (LoRaMac/classX) includes an implementation of the LoRa-Alliance; LoRaWAN certification protocol.*
|
||||
|
||||
**Note**: *The LoRaWAN stack API documentation can be found at: http://stackforce.github.io/LoRaMac-doc/*
|
||||
|
||||
## Supported platforms
|
||||
|
||||
This project currently provides support for the below platforms.
|
||||
This project can be ported to other platforms using different MCU than the ones currently supported.
|
||||
The [Porting Guide](http://stackforce.github.io/LoRaMac-doc/_p_o_r_t_i_n_g__g_u_i_d_e.html) document provides guide lines on how to port the project to other platforms.
|
||||
|
||||
* NAMote72
|
||||
* [NAMote72 platform documentation](Doc/NAMote72-platform.md)
|
||||
|
||||
* NucleoLxxx - Discovery kit
|
||||
* [NucleoLxxx and Discovery kit platforms documentation](Doc/NucleoLxxx-platform.md)
|
||||
|
||||
* SKiM880B, SKiM980A, SKiM881AXL
|
||||
* [SKiM88xx platforms documentation](Doc/SKiM88xx-platform.md)
|
||||
|
||||
* SAML21
|
||||
* [SAML21 platform documentation](Doc/SAML21-platform.md)
|
||||
|
||||
## Usage
|
||||
|
||||
A CMAKE building system is used in order to generate the right set of files to compile and debug the different projects.
|
||||
|
||||
Further information can be found in [Development environment](Doc/development-environment.md) document.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
The mbed (https://mbed.org/) project was used at the beginning as source of
|
||||
inspiration.
|
||||
|
||||
This program uses the AES algorithm implementation (http://www.gladman.me.uk/) by Brian Gladman.
|
||||
|
||||
This program uses the CMAC algorithm implementation
|
||||
(http://www.cse.chalmers.se/research/group/dcs/masters/contikisec/) by Lander Casado, Philippas Tsigas.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2019-07-19, V4.4.2
|
||||
|
||||
* General
|
||||
1. Release based on "LoRaWAN specification 1.0.3" and "LoRaWAN Regional Parameters v1.0.3revA"
|
||||
2. Examples application refactoring plus the addition of the application status display on the serial port. (921600-8-N-1)
|
||||
3. Added new refactored application examples
|
||||
* Added LoRa-Alliance defined application layer protocols support. Only FUOTA test scenario 01 required features are currently implemented.
|
||||
- "Clock Synchronization" package
|
||||
- "Fragmented data block transport" package
|
||||
- "Remote multicast setup" package
|
||||
4. Added a NVM context management module. (Disabled by default)
|
||||
5. Added secure-element support
|
||||
6. Refactored timer.c/h, rtc-driver.c/h and added a systime.c/h module.
|
||||
7. Functions in ISR context have been moved to main context
|
||||
8. Replaced BoardDisableIrq and BoardEnableIrq functions by CRITICAL_SECTION_BEGIN and CRITICAL_SECTION_END respectively.
|
||||
9. Added B-L072Z-LRWAN1 platform support.
|
||||
10. Added NucleoL476 platform support.
|
||||
11. Added IMST new platforms.
|
||||
12. Removed SensorNode platform support
|
||||
13. Removed MoteII platform support
|
||||
14. Removed LoRaMote platform support
|
||||
15. Applied SX1272 and SX1276 radios errata note 3.1 to the radio drivers implementation.
|
||||
16. Fix printf/scanf functions when GCC is used as compiler.
|
||||
|
||||
* LoRaWAN
|
||||
1. GitHub reported issues corrections. Please refer to [Release Version 4.4.2](https://github.com/Lora-net/LoRaMac-node/milestone/2)
|
||||
2. Heavily refactored the LoRaMac.c/h implementation.
|
||||
3. Added RU864 region support.
|
||||
4. Removed US915-Hybrid region support
|
||||
5. Added ClassB support.
|
||||
6. Added a callback to notify the upper layer to call LoRaMacProcess function
|
||||
7. Implemented the support for RxC windows (ClassC) required by the application layer protocols.
|
||||
8. Changed multicast channels handling according to the application layer protocols.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2018-03-07, V4.4.1
|
||||
|
||||
* General
|
||||
1. Release based on "LoRaWAN specification 1.0.2" and "LoRaWAN Regional Parameters v1.0.2rB"
|
||||
2. Added SX126x radio support.
|
||||
3. Added NucleoL073 and NucleoL152 board platforms support.
|
||||
4. Added Microchip/Atmel SAML21 Xplained Pro hardware platform support.
|
||||
5. Added CMAKE build system support
|
||||
6. Removed CoIDE projects support
|
||||
7. Removed Keil projects support
|
||||
|
||||
* LoRaWAN
|
||||
1. GitHub reported issues corrections. Please refer to [Release Version 4.4.1](https://github.com/Lora-net/LoRaMac-node/milestone/1)
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2017-09-08, V4.4.0
|
||||
|
||||
* General
|
||||
1. First release based on "LoRaWAN specification 1.0.2" and "LoRaWAN Regional Parameters v1.0.2rB"
|
||||
2. This version has passed the LoRa-Alliance compliance tests for the regions shown in the below table.
|
||||
3. GitHub reported issues corrections.
|
||||
4. Updated radio driver to perform the LBT carrier sense continuously for a given period of time.
|
||||
|
||||
* LoRaWAN
|
||||
1. GitHub reported issues corrections.
|
||||
2. Updated implementation to support 1.0.2 specification additions.
|
||||
3. Added the support for all "LoRaWAN Regional Parameters v1.0.2rB" document defined regions.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2017-04-19, V4.3.2
|
||||
|
||||
* General (Last release based on LoRaWAN specification 1.0.1)
|
||||
1. This version has passed EU868 and US915 LoRa-Alliance compliance tests.
|
||||
2. GitHub reported issues corrections.
|
||||
3. Added an algorithm to automatically compute the Rx windows parameters. (Window symbolTimeout and Offset from downlink expected time)
|
||||
4. Added a workaround to reset the radio in case a TxTimeout occurs.
|
||||
5. Modified FSK modem handling to use the provided symbolTimeout (1 symbol equals 1 byte) when in RxSingle mode.
|
||||
6. Added newly defined TxCw(Tx Continuous Wave) certification protocol command.
|
||||
7. Added a fix for an overflow issue that could happen with NmeaStringSize variable.
|
||||
8. Improved GpioMcuInit function to first configure the output pin state before activating the pin.
|
||||
|
||||
* LoRaWAN
|
||||
1. GitHub reported issues corrections.
|
||||
2. Changed the AdrAckCounter handling as expected by the test houses.
|
||||
3. Fix an issue where the node stopped transmitting.
|
||||
4. Removed useless LoRaMacPayload buffer.
|
||||
5. MAC layer indications handling simplification.
|
||||
6. Relocate parameter settings from ResetMacParameters to the initialization.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2017-02-27, V4.3.1
|
||||
|
||||
* General
|
||||
1. This version has passed EU868 and US915 LoRa-Alliance compliance tests.
|
||||
2. Update the MAC layer in order to be LoRaWAN version 1.0.1 compliant (Mainly US915 bug fixes)
|
||||
3. Removed api-v3 support from the project.
|
||||
4. GitHub reported issues corrections.
|
||||
5. Updated SensorNode projects according to the new MCU reference STM32L151CBU6. Bigger memories.
|
||||
6. Addition of MoteII platform based on the IMST module iM881A (STM32L051C8)
|
||||
7. Addition of NAMote72 platform
|
||||
8. Correct compliance test protocol command 0x06 behavior
|
||||
9. Added TxCw (Tx continuous wave) LoRaWAN compliance protocol command.
|
||||
10. Added TxContinuousWave support to the radio drivers.
|
||||
11. Updated ST HAL drivers.
|
||||
* STM32L1xx_HAL-Driver : V1.2.0
|
||||
* STM32L0xx_HAL_Driver : V1.7.0
|
||||
|
||||
* LoRaWAN
|
||||
1. US band corrections in order to pass the LoRaWAN certification.
|
||||
2. GitHub reported issues corrections.
|
||||
3. Add region CN470 support.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2016-06-22, V4.3.0
|
||||
|
||||
* General
|
||||
1. This version has passed all LoRa-Alliance compliance tests.
|
||||
2. Update the MAC layer in order to be LoRaWAN version 1.0.1 compliant
|
||||
3. Applied to all application files the certification protocol change for LoRaWAN 1.0.1 compliance tests.
|
||||
|
||||
**REMARK**: api-v3 application files aren't updated.
|
||||
|
||||
4. Add radio RX_TIMEOUT irq clear into the irq handler.
|
||||
5. Removed the end less loop from HAL_UART_ErrorCallback.
|
||||
6. Update of the STM32L0 HAL to version 1.6.0
|
||||
7. Consolidated the line endings across all project files.
|
||||
Windows line endings has been choose for almost every file.
|
||||
|
||||
* LoRaWAN
|
||||
1. Updated maximum payload size for US band.
|
||||
2. Update datarate offset table for US band.
|
||||
3. Make MAC commands sticky
|
||||
4. Add retransmission back-off
|
||||
5. Remove the TxPower limitation for US band on LoRaMacMibSetRequestConfirm function. The power will be limited anyway when the SendFrameOnChannel functions is called.
|
||||
6. Issue(#81): Bug fix in function LoRaMacMlmeRequest case MLME_JOIN. Function will return LORAMAC_STATUS_BUSY in case the MAC is in status MAC_TX_DELAYED.
|
||||
7. Add debug pin support to LoRaMote platform.
|
||||
8. Updated and improved MPL3115 device driver.
|
||||
9. Issue(#83): Bug fix in parameter validation
|
||||
10. Issue(#84): Fix issue of CalibrateTimer function.
|
||||
11. RTC driver major update
|
||||
12. Applied pull request #87.
|
||||
13. Add a function to verify the RX frequency of window 2 for US band.
|
||||
14. Issue(#88): Bug fix in function PrepareFrame where repeated MAC commands were not handled correctly.
|
||||
15. Bug fix in OnRadioRxDone. Node now drops frames on port 0 with fOpts > 0.
|
||||
16. Bug fix in OnRadioRxDone. Node now receives frames with fOpts > 0 when no payload is present.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2016-05-13, V4.2.0
|
||||
|
||||
* General
|
||||
1. This version has passed all LoRa-Alliance compliance tests.
|
||||
2. Update STM32L1xx_HAL_Driver version to 1.5. Update related drivers and implementations accordingly.
|
||||
|
||||
**REMARK**: This change implies that the time base had to be changed from microseconds to milliseconds.
|
||||
|
||||
3. Corrected the frequency check condition for // ERRATA 2.1 - Sensitivity Optimization with a 500 kHz Bandwidth
|
||||
4. Optimize radio drivers regarding FSK PER
|
||||
5. Resolve issue when calling SX127xInit function more than once
|
||||
6. Add a definition for the LoRaWAN device address. Add an IEEE_OUI for the LoRaWAN device EUI.
|
||||
7. Add a definition for the default datarate.
|
||||
8. Issue(#66) correction of functions SX1276SetOpMode and SX1272SetOpMode.
|
||||
9. Issue(#68): Fix for low level RF switch control.
|
||||
10. Increase RTC tick frequency for higher resolution.
|
||||
11. Update the radio wake up time.
|
||||
|
||||
* LoRaWAN
|
||||
1. Issue(#56) correction
|
||||
2. Update channel mask handling for US915 hybrid mode to support any block in the channel mask.
|
||||
3. Issue(#63) correct the maximum payload length in RX mode.
|
||||
4. Fix Tx power setting loss for repeated join requests on US band.
|
||||
5. Introduce individual MIN and MAX datarates for RX and TX.
|
||||
6. Add the possibility to set and get the ChannelsDefaultDatarate.
|
||||
7. Optimization of the RX symbol timeout.
|
||||
8. Issue(#59): Add the possibility to set the uplink and downlink counter.
|
||||
9. Replace definition LORAMAC_DEFAULT_DATARATE by ChannelsDefaultDatarate in LoRaMacChannelAdd.
|
||||
10. Issue(#72): Fix of possible array overrun in LoRaMacChannelRemove.
|
||||
11. Introduce a new status MAC_RX_ABORT. Reset MAC_TX_RUNNING only in OnMacStateCheckTimerEvent.
|
||||
12. Accept MAC information of duplicated, confirmed downlinks.
|
||||
13. Issue(#74): Drop frames with a downlink counter difference greater or equal to MAX_FCNT_GAP.
|
||||
|
||||
**LoRaWAN pre-certification results**
|
||||
|
||||
Please refer to [Releases pre-certification-results](https://github.com/Lora-net/LoRaMac-node/wiki/releases-pre-certification-results) document for further information.
|
||||
|
||||
### 2016-03-10, V4.1.0
|
||||
|
||||
* General
|
||||
1. This version has passed all mandatory LoRa-Alliance compliance tests.
|
||||
|
||||
*One of the optional tests is unsuccessful (FSK downlinks PER on Rx1 and Rx2 windows) and is currently under investigation.*
|
||||
2. Removed support for Raisonance Ride7 IDE (Reduces the amount of work to be done at each new release)
|
||||
3. Removed the Bleeper-72 and Bleeper-76 platforms support as these are now deprecated.
|
||||
4. Application state machine. Relocate setting sleep state and update the duty cycle in compliance test mode.
|
||||
5. Bug fix in TimerIrqHandler. Now, it is possible to insert timers in callback.
|
||||
6. Changed TimerHwDelayMs function to be re-entrant.
|
||||
7. Corrected FSK modem packets bigger than 64 bytes handling (Issue #36)
|
||||
|
||||
* LoRaWAN
|
||||
1. Rename attribute nbRetries to NbTrials in structure McpsReqConfirmed_t. (Issue #37)
|
||||
2. Updated implementation of SetNextChannel. Added enabling default channels in case of join request. (Issue #39)
|
||||
3. Add missing documentation about MIB_REPEATER_SUPPORT. (Issue #42).
|
||||
4. Add a new LoRaMacState to allow adding channels during TX procedure. (Issue #43)
|
||||
5. Relocate the activation of LoRaMacFlags.Bits.McpsInd in OnRadioRxDone.
|
||||
6. Add a new function PrepareRxDoneAbort to prepare a break-out of OnRadioRxDone in case of an error
|
||||
7. Activate default channels in case all others are disabled. (Issue #39)
|
||||
8. Bug fix in setting the default channel in case none is enabled.
|
||||
9. SRV_MAC_NEW_CHANNEL_REQ MAC command added a fix to the macIndex variable on US915 band.
|
||||
10. Start the MacStateCheckTimer in OnRxDone and related error cases with a short interval to handle events promptly. (Issue #44)
|
||||
11. Reset status of NodeAckRequested if we received an ACK or in case of timeout.
|
||||
12. Removed additional EU868 channels from the LoRaWAN implementation files. GitHub (Issue #49)
|
||||
The creation of these additional channels has been moved to the application example.
|
||||
13. Improved and corrected AdrNextDr function.
|
||||
|
||||
### 2015-12-18, V4.0.0
|
||||
|
||||
* General
|
||||
1. STACKFORCE new API integration
|
||||
2. Reverse the EUIs arrays in the MAC layer.
|
||||
3. LoRaWAN certification protocol implementation
|
||||
4. All reported issues and Pull requests have been addressed.
|
||||
|
||||
### 2015-10-06, V3.4.1
|
||||
|
||||
* General
|
||||
1. Bug fixes
|
||||
|
||||
* LoRaWAN
|
||||
1. Corrected downlink counter roll over management when several downlinks were missed.
|
||||
2. Corrected the Radio maximum payload length management. Radio was filtering received frames with a length bigger than the transmitted one.
|
||||
3. Applied Pull request #22 solution proposition.
|
||||
|
||||
### 2015-10-30, V3.4.0
|
||||
|
||||
* General
|
||||
1. Changed all applications in order to have preprocessing definitions on top of the files and added relevant comments
|
||||
2. Applications LED control is no more done into the timer callback functions but instead on the main while loop.
|
||||
3. Added TimerStop function calls to each timer event callback.
|
||||
4. Corrected timings comments. Timing values are most of the time us based.
|
||||
5. Changed types names for stdint.h names. Helps on code portability
|
||||
6. Renamed rand and srand to rand1 and srand1. Helps on code portability
|
||||
7. Added some missing variables casts. Helps on code portability
|
||||
8. Removed NULL definition from board.h
|
||||
9. Added const variable attribute when necessary to functions prototypes
|
||||
10. Moved ID1, ID2 and ID3 definition from board.h to board.c, usb-cdc-board.c and usb-dfu-board.c
|
||||
11. Removed the definition of RAND_SEED. It has been replaced by a function named BoardGetRandomSeed
|
||||
12. Renamed BoardMeasureBatterieLevel to BoardGetBatteryLevel
|
||||
13. Added SetMaxPayloadLength API function to SX1272 and SX1276 radio drivers
|
||||
14. Changed the name of Radio API Status function to GetStatus
|
||||
15. AES/CMAC Changed types names for stdint.h names. Helps on code portability (Issue #20)
|
||||
16. Moved __ffs function from utilities.h to spi-board.c. This function is only used there.
|
||||
17. Utilities.c removed fputc function redefinition.
|
||||
18. Replaced the usage of __IO attribute by volatile.
|
||||
|
||||
* LoRaWAN
|
||||
1. Added support for the US915 band (Normal mode and hybrid mode. Hybrid mode is a temporary configuration up until servers support it automatically) (Issue #16)
|
||||
2. Corrected and simplified the downlink sequence counter management.
|
||||
3. Removed the usage of PACKED attribute for data structures.
|
||||
4. Renamed LoRaMacEvent_t into LoRaMacCallbacks_t and added a function pointer for getting battery level status
|
||||
5. Renamed LoRaMacSetDutyCycleOn into LoRaMacSetTestDutyCycleOn
|
||||
6. Renamed LoRaMacSetMicTest into LoRaMacTestSetMic
|
||||
7. Increased the PHY buffer size to 250
|
||||
8. Removed IsChannelFree check on LoRaMacSetNextChannel function. LoRaWAN is an ALHOA protocol. (Pull request #8)
|
||||
9. LoRaMacEventInfo.TxDatarate now returns LoRaWAN datarate (DR0 -> DR7) instead of (SF12 -> DF7)
|
||||
10. Corrected channel mask management for EU868 band.
|
||||
11. Corrected LoRaMacPrepareFrame behavior function when no applicative payload is present.
|
||||
12. LoRaMac-board.h now implements the settings for the PHY layers specified by LoRaWAN 1.0 specification. ( EU433, CN780, EU868, US915 ) (Issue #19)
|
||||
13. Added LORAMAC_MIN_RX1_DR_OFFSET and LORAMAC_MAX_RX1_DR_OFFSET definitions to LoRaMac-board.h. Can be different upon used PHY layer
|
||||
14. Added the limitation of output power according to the number of enabled channels for US915 band.
|
||||
15. Added the limitation of the applicative payload length according to the datarate. Does not yet take in account the MAC commands buffer. (Issue #15)
|
||||
16. Corrected MacCommandBufferIndex management. (Issue #18)
|
||||
|
||||
### 2015-08-07, v3.3.0
|
||||
|
||||
* General
|
||||
1. Added the support for LoRaWAN Class C devices.
|
||||
2. Implemented the radios errata note workarounds. SX1276 errata 2.3 "Receiver Spurious Reception of a LoRa Signal" is not yet implemented.
|
||||
3. Increased FSK SyncWord timeout value in order to listen for longer time if a down link is available or not. Makes FSK downlink more reliable.
|
||||
4. Increased the UART USB FIFO buffer size in order to handle bigger chunks of data.
|
||||
|
||||
* LoRaWAN
|
||||
1. Renamed data rates as per LoRaWAN specification.
|
||||
2. Added the support for LoRaWAN Class C devices.
|
||||
3. Handling of the MAC commands was done incorrectly the condition to verify the length of the buffer has changed from < to <=.
|
||||
4. Added the possibility to change the channel mask and number of repetitions trough SRV_MAC_LINK_ADR_REQ command when ADR is disabled.
|
||||
5. Corrected Rx1DrOffset management. In previous version DR1 was missing for all offsets.
|
||||
6. Changed confirmed messages function to use default datarate when ADR control is off.
|
||||
7. After a Join accept the node falls back to the default datarate. Enables the user to Join a network using a different datarate from its own default one.
|
||||
8. Corrected default FSK channel frequency.
|
||||
9. Solved a firmware freezing when one of the following situations arrived in OnRxDone callback: bad address, bad MIC, bad frame. (Pull request #10)
|
||||
10. Moved the MAC commands processing to the right places. FOpts field before the Payload and Port 0 just after the decryption. (Pull request #9)
|
||||
11. Weird conditions to check datarate on cmd mac SRV_MAC_NEW_CHANNEL_REQ (Pull request #7)
|
||||
12. Ignore join accept message if already joined (Pull request #6)
|
||||
13. Channel index verification should use OR on SRV_MAC_NEW_CHANNEL_REQ command (Pull request #5)
|
||||
14. Corrected the CFList management on JoinAccept. The for loop indexes were wrong. (Pull request #4)
|
||||
15. Correction of AES key size (Pull request #3)
|
||||
|
||||
### 2015-04-30, v3.2.0
|
||||
|
||||
* General
|
||||
1. Updated LoRaMac implementation according to LoRaWAN R1.0 specification
|
||||
2. General cosmetics corrections
|
||||
3. Added the support of packed structures when using IAR tool chain
|
||||
4. Timers: Added a function to get the time in us.
|
||||
5. Timers: Added a typedef for time variables (TimerTime_t)
|
||||
6. Radios: Changed the TimeOnAir radio function to return a uint32_t value instead of a double. The value is in us.
|
||||
7. Radios: Corrected the 250 kHz bandwidth choice for the FSK modem
|
||||
8. GPS: Added a function that returns if the GPS has a fix or not.
|
||||
9. GPS: Changed the GetPosition functions to return a latitude and longitude of 0 and altitude of 65535 when no GPS fix.
|
||||
|
||||
* LoRaWAN
|
||||
1. Removed support for previous LoRaMac/LoRaWAN specifications
|
||||
2. Added missing MAC commands and updated others when necessary
|
||||
* Corrected the Port 0 MAC commands decryption
|
||||
* Changed the way the upper layer is notified. Now it is only notified
|
||||
when all the operations are finished.
|
||||
|
||||
When a ClassA Tx cycle starts a timer is launched to check every second if everything is finished.
|
||||
|
||||
* Added a new parameter to LoRaMacEventFlags structure that indicates on which Rx window the data has been received.
|
||||
* Added a new parameter to LoRaMacEventFlags structure that indicates if there is applicative data on the received payload.
|
||||
* Corrected ADR MAC command behavior
|
||||
* DutyCycle enforcement implementation (EU868 PHY only)
|
||||
|
||||
**REMARK 1** *The regulatory duty cycle enforcement is enabled by default
|
||||
which means that for lower data rates the node may not transmit a new
|
||||
frame as quickly as requested.
|
||||
The formula used to compute the node idle time is*
|
||||
|
||||
*Toff = TimeOnAir / DutyCycle - TxTimeOnAir*
|
||||
|
||||
*Example:*
|
||||
*A device just transmitted a 0.5 s long frame on one default channel.
|
||||
This channel is in a sub-band allowing 1% duty-cycle. Therefore this
|
||||
whole sub-band (868 MHz - 868.6 MHz) will be unavailable for 49.5 s.*
|
||||
|
||||
**REMARK 2** *The duty cycle enforcement can be disabled for test
|
||||
purposes by calling the LoRaMacSetDutyCycleOn function with false
|
||||
parameter.*
|
||||
* Implemented aggregated duty cycle management
|
||||
* Added a function to create new channels
|
||||
* Implemented the missing features on the JoinAccept MAC command
|
||||
* Updated LoRaMacJoinDecrypt function to handle the CFList field.
|
||||
3. Due to duty cycle management the applicative API has changed.
|
||||
All applications must be updated accordingly.
|
||||
4. Added the possibility to chose to use either public or private networks
|
||||
|
||||
### 2015-01-30, v3.1.0
|
||||
|
||||
* General
|
||||
1. Started to add support for CooCox CoIDE Integrated Development Environment.
|
||||
Currently only LoRaMote and SensorNode platform projects are available.
|
||||
2. Updated GCC compiler linker scripts.
|
||||
3. Added the support of different tool chains for the HardFault_Handler function.
|
||||
|
||||
4. Corrected Radio drivers I&Q signals inversion to be possible in Rx and in Tx.
|
||||
Added some missing radio state machine initialization.
|
||||
5. Changed the RSSI values type from int8_t to int16_t. We can have RSSI values below -128 dBm.
|
||||
6. Corrected SNR computation on RxDone interrupt.
|
||||
7. Updated radio API to support FHSS and CAD handling.
|
||||
8. Corrected in SetRxConfig function the FSK modem preamble register name.
|
||||
9. Added an invalid bandwidth to the Bandwidths table in order to avoid an error
|
||||
when selecting 250 kHz bandwidth when using FSK modem.
|
||||
|
||||
10. Corrected RTC alarm setup which could be set to an invalid date.
|
||||
11. Added another timer in order increment the tick counter without blocking the normal timer count.
|
||||
12. Added the possibility to switch between low power timers and normal timers on the fly.
|
||||
13. I2C driver corrected the 2 bytes internal address management.
|
||||
Corrected buffer read function when more that 1 byte was to be read.
|
||||
Added a function to wait for the I2C bus to become IDLE.
|
||||
14. Added an I2C EEPROM driver.
|
||||
15. Corrected and improved USB Virtual COM Port management files.
|
||||
Corrected the USB CDC and USB UART drivers.
|
||||
16. Added the possibility to analyze a hard fault interrupt.
|
||||
|
||||
* LoRaMac
|
||||
1. Corrected RxWindow2 Datarate management.
|
||||
2. SrvAckRequested variable was never reset.
|
||||
3. Corrected tstIndoor applications for LoRaMac R3.0 support.
|
||||
4. LoRaMac added the possibility to configure almost all the MAC parameters.
|
||||
5. Corrected the LoRaMacSetNextChannel function.
|
||||
6. Corrected the port 0 MAC command decoding.
|
||||
7. Changed all structures declarations to be packed.
|
||||
8. Corrected the Acknowledgment retries management when only 1 trial is needed.
|
||||
Before the device was issuing at least 2 trials.
|
||||
9. Corrected server mac new channel req answer.
|
||||
10. Added the functions to read the Up and Down Link sequence counters.
|
||||
11. Corrected SRV_MAC_RX2_SETUP_REQ frequency handling. Added a 100 multiplication.
|
||||
12. Corrected SRV_MAC_NEW_CHANNEL_REQ. Removed the DutyCycle parameter decoding.
|
||||
13. Automatically activate the channel once it is created.
|
||||
14. Corrected NbRepTimeoutTimer initial value. RxWindow2Delay already contains RxWindow1Delay in it.
|
||||
|
||||
### 2014-07-18, v3.0.0
|
||||
|
||||
* General
|
||||
1. Added to Radio API the possibility to select the modem.
|
||||
2. Corrected RSSI reading formulas as well as changed the RSSI and SNR values from double to int8_t type.
|
||||
3. Changed radio callbacks events to timeout when it is a timeout event and error when it is a CRC error.
|
||||
4. Radio API updated.
|
||||
5. Updated ping-pong applications.
|
||||
6. Updated tx-cw applications.
|
||||
7. Updated LoRaMac applications in order to handle LoRaMac returned functions calls status.
|
||||
8. Updated LoRaMac applications to toggle LED2 each time there is an application payload down link.
|
||||
9. Updated tstIndoor application to handle correctly more than 6 channels.
|
||||
10. Changed the MPL3115 altitude variable from unsigned to signed value.
|
||||
11. Replaced the usage of pow(2, n) by defining POW2 functions. Saves ~2 KBytes of code.
|
||||
12. Corrected an issue potentially arriving when LOW_POWER_MODE_ENABLE wasn't defined.
|
||||
A timer interrupt could be generated while the TimerList could already be emptied.
|
||||
|
||||
* LoRaMac
|
||||
1. Implemented LoRaMac specification R3.0 changes.
|
||||
|
||||
2. MAC commands implemented
|
||||
* LinkCheckReq **YES**
|
||||
* LinkCheckAns **YES**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **YES**
|
||||
* DutyCycleReq **YES**
|
||||
* DutyCycleAns **YES**
|
||||
* Rx2SetupReq **YES**
|
||||
* Rx2SetupAns **YES**
|
||||
* DevStatusReq **YES**
|
||||
* DevStatusAns **YES**
|
||||
* JoinReq **YES**
|
||||
* JoinAccept **YES**
|
||||
* NewChannelReq **YES**
|
||||
* NewChannelAns **YES**
|
||||
|
||||
3. Features implemented
|
||||
* Possibility to shut-down the device **YES**
|
||||
|
||||
Possible by issuing DutyCycleReq MAC command.
|
||||
* Duty cycle management enforcement **NO**
|
||||
* Acknowledgments retries **YES**
|
||||
* Unconfirmed messages retries **YES**
|
||||
|
||||
### 2014-07-10, v2.3.RC2
|
||||
|
||||
* General
|
||||
1. Corrected all radios antenna switch low power mode handling.
|
||||
2. SX1276: Corrected antenna switch control.
|
||||
|
||||
### 2014-06-06, v2.3.RC1
|
||||
|
||||
* General
|
||||
1. Added the support for SX1276 radio.
|
||||
2. Radio continuous reception mode correction.
|
||||
3. Radio driver RxDone callback function API has changed ( size parameter is no more a pointer).
|
||||
Previous function prototype:
|
||||
|
||||
void ( *RxDone )( uint8_t *payload, uint16_t *size, double rssi, double snr, uint8_t rawSnr );
|
||||
|
||||
New function prototype:
|
||||
|
||||
void ( *RxDone )( uint8_t *payload, uint16_t size, double rssi, double snr, uint8_t rawSnr );
|
||||
|
||||
4. Added Bleeper-76 and SensorNode platforms support.
|
||||
5. Added to the radio drivers a function that generates a random value from
|
||||
RSSI readings.
|
||||
6. Added a project to transmit a continuous wave and a project to measure the
|
||||
the radio sensitivity.
|
||||
7. Added a bootloader project for the LoRaMote and SensorNode platforms.
|
||||
8. The LoRaMac application for Bleeper platforms now sends the Selector and LED status plus the sensors values.
|
||||
* The application payload for the Bleeper platforms is as follows:
|
||||
|
||||
LoRaMac port 1:
|
||||
|
||||
{ 0xX0/0xX1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
---------- ---------- ---------- ---------- ----
|
||||
| | | | |
|
||||
SELECTOR/LED PRESSURE TEMPERATURE ALTITUDE BATTERY
|
||||
MSB nibble = SELECTOR (barometric)
|
||||
LSB bit = LED
|
||||
9. Redefined rand() and srand() standard C functions. These functions are
|
||||
redefined in order to get the same behavior across different compiler
|
||||
tool chains implementations.
|
||||
10. GPS driver improvements. Made independent of the board platform.
|
||||
11. Simplified the RTC management.
|
||||
12. Added a function to the timer driver that checks if a timer is already in
|
||||
the list or not.
|
||||
13. Added the UART Overrun bit exception handling to the UART driver.
|
||||
14. Removed dependency of spi-board files to the "__builtin_ffs" function.
|
||||
This function is only available on GNU compiler tool suite. Removed --gnu
|
||||
compiler option from Keil projects. Added own __ffs function
|
||||
implementation to utilities.h file.
|
||||
15. Removed obsolete class1 devices support.
|
||||
16. Known bugs correction.
|
||||
|
||||
* LoRaMac
|
||||
1. MAC commands implemented
|
||||
* LinkCheckReq **YES**
|
||||
* LinkCheckAns **YES**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **YES**
|
||||
* DutyCycleReq **YES** (LoRaMac specification R2.2.1)
|
||||
* DutyCycleAns **YES** (LoRaMac specification R2.2.1)
|
||||
* Rx2SetupReq **YES** (LoRaMac specification R2.2.1)
|
||||
* Rx2SetupAns **YES** (LoRaMac specification R2.2.1)
|
||||
* DevStatusReq **YES**
|
||||
* DevStatusAns **YES**
|
||||
* JoinReq **YES**
|
||||
* JoinAccept **YES** (LoRaMac specification R2.2.1)
|
||||
* NewChannelReq **YES** (LoRaMac specification R2.2.1)
|
||||
* NewChannelAns **YES** (LoRaMac specification R2.2.1)
|
||||
2. Features implemented
|
||||
* Possibility to shut-down the device **YES**
|
||||
|
||||
Possible by issuing DutyCycleReq MAC command.
|
||||
* Duty cycle management enforcement **NO**
|
||||
* Acknowledgments retries **WORK IN PROGRESS**
|
||||
|
||||
Not fully debugged. Disabled by default.
|
||||
* Unconfirmed messages retries **WORK IN PROGRESS** (LoRaMac specification R2.2.1)
|
||||
3. Implemented LoRaMac specification R2.2.1 changes.
|
||||
4. Due to new specification the LoRaMacInitNwkIds LoRaMac API function had
|
||||
to be modified.
|
||||
|
||||
Previous function prototype:
|
||||
|
||||
void LoRaMacInitNwkIds( uint32_t devAddr, uint8_t *nwkSKey, uint8_t *appSKey );
|
||||
|
||||
New function prototype:
|
||||
|
||||
void LoRaMacInitNwkIds( uint32_t netID, uint32_t devAddr, uint8_t *nwkSKey, uint8_t *appSKey );
|
||||
5. Changed the LoRaMac channels management.
|
||||
6. LoRaMac channels definition has been moved to LoRaMac-board.h file
|
||||
located in each specific board directory.
|
||||
|
||||
### 2014-04-07, v2.2.0
|
||||
|
||||
* General
|
||||
1. Added IMST SK-iM880A starter kit board support to the project.
|
||||
* The application payload for the SK-iM880A platform is as follows:
|
||||
|
||||
LoRaMac port 3:
|
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00 }
|
||||
---------- ----- ----------
|
||||
| | |
|
||||
LED POTI VDD
|
||||
2. Ping-Pong applications have been split per supported board.
|
||||
3. Corrected the SX1272 output power management.
|
||||
Added a variable to store the current Radio channel.
|
||||
Added missing FSK bit definition.
|
||||
4. Made fifo functions coding style coherent with the project.
|
||||
5. UART driver is now independent of the used MCU
|
||||
|
||||
### 2014-03-28, v2.1.0
|
||||
|
||||
* General
|
||||
1. The timers and RTC management has been rewritten.
|
||||
2. Improved the UART and UP501 GPS drivers.
|
||||
3. Corrected GPIO pin names management.
|
||||
4. Corrected the antenna switch management in the SX1272 driver.
|
||||
5. Added to the radio driver the possibility to choose the preamble length
|
||||
and rxSingle symbol timeout in reception.
|
||||
6. Added Hex coder selector driver for the Bleeper board.
|
||||
7. Changed copyright Unicode character to (C) in all source files.
|
||||
|
||||
* LoRaMac
|
||||
1. MAC commands implemented
|
||||
* LinkCheckReq **YES**
|
||||
* LinkCheckAns **YES**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **YES**
|
||||
* DevStatusReq **YES**
|
||||
* DevStatusAns **YES**
|
||||
* JoinReq **YES**
|
||||
* JoinAccept **YES**
|
||||
2. Added acknowledgments retries management.
|
||||
Split the LoRaMacSendOnChannel function in LoRaMacPrepareFrame and
|
||||
LoRaMacSendFrameOnChannel. LoRaMacSendOnChannel now calls the 2 newly
|
||||
defined functions.
|
||||
**WARNING**: By default the acknowledgment retries specific code isn't
|
||||
enabled. The current http://iot.semtech.com server version doesn't support
|
||||
it.
|
||||
3. Corrected issues on JoinRequest and JoinAccept MAC commands.
|
||||
Added LORAMAC_EVENT_INFO_STATUS_MAC_ERROR event info status.
|
||||
|
||||
### 2014-02-21, v2.0.0
|
||||
|
||||
* General
|
||||
1. The LoRaMac applications now sends the LED status plus the sensors values.
|
||||
For the LoRaMote platform the application also sends the GPS coordinates.
|
||||
* The application payload for the Bleeper platform is as follows:
|
||||
|
||||
LoRaMac port 1:
|
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
---------- ---------- ---------- ---------- ----
|
||||
| | | | |
|
||||
LED PRESSURE TEMPERATURE ALTITUDE BATTERY
|
||||
(barometric)
|
||||
* The application payload for the LoRaMote platform is as follows:
|
||||
|
||||
LoRaMac port 2:
|
||||
|
||||
{ 0x00/0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||
---------- ---------- ---------- ---------- ---- ---------------- ---------------- ----------
|
||||
| | | | | | | |
|
||||
LED PRESSURE TEMPERATURE ALTITUDE BATTERY LATITUDE LONGITUDE ALTITUDE
|
||||
(barometric) (gps)
|
||||
2. Adapted applications to the new MAC layer API.
|
||||
3. Added sensors drivers implementation.
|
||||
4. Corrected new or known issues.
|
||||
* LoRaMac
|
||||
1. MAC commands implemented
|
||||
* LinkCheckReq **YES**
|
||||
* LinkCheckAns **YES**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **YES**
|
||||
* DevStatusReq **YES**
|
||||
* DevStatusAns **YES**
|
||||
* JoinReq **YES (Not tested)**
|
||||
* JoinAccept **YES (Not tested)**
|
||||
2. New MAC layer application API implementation.
|
||||
* Timers and RTC.
|
||||
1. Still some issues. They will be corrected on next revisions of the firmware.
|
||||
|
||||
### 2014-01-24, v1.1.0
|
||||
|
||||
* LoRaMac
|
||||
1. MAC commands implemented
|
||||
* LinkCheckReq **NO**
|
||||
* LinkCheckAns **NO**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **YES**
|
||||
* DevStatusReq **YES**
|
||||
* DevStatusAns **YES**
|
||||
2. Implemented an application LED control
|
||||
If the server sends on port 1 an application payload of one byte with
|
||||
the following contents:
|
||||
|
||||
0: LED off
|
||||
1: LED on
|
||||
The node transmits periodically on port 1 the LED status on 1st byte and
|
||||
the message "Hello World!!!!" the array looks like:
|
||||
|
||||
{ 0, 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '!', '!', '!' }
|
||||
* Timers and RTC.
|
||||
1. Corrected issues existing in the previous version
|
||||
2. Known bugs are:
|
||||
* There is an issue when launching an asynchronous Timer. Will be solved
|
||||
in a future version
|
||||
|
||||
### 2014-01-20, v1.1.RC1
|
||||
|
||||
* Added Doc directory. The directory contains:
|
||||
1. LoRa MAC specification
|
||||
2. Bleeper board schematic
|
||||
* LoRaMac has been updated according to Release1 of the specification. Main changes are:
|
||||
1. MAC API changed.
|
||||
2. Frame format.
|
||||
3. ClassA first ADR implementation.
|
||||
4. MAC commands implemented
|
||||
* LinkCheckReq **NO**
|
||||
* LinkCheckAns **NO**
|
||||
* LinkADRReq **YES**
|
||||
* LinkADRAns **NO**
|
||||
* DevStatusReq **NO**
|
||||
* DevStatusAns **NO**
|
||||
* Timers and RTC rewriting. Known bugs are:
|
||||
1. The Radio wakeup time is taken in account for all timings.
|
||||
2. When opening the second reception window the microcontroller sometimes doesn't enter in low power mode.
|
||||
|
||||
### 2013-11-28, v1.0.0
|
||||
|
||||
* Initial version of the LoRa MAC node firmware implementation.
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
@verbatim
|
||||
******************************************************************************
|
||||
* @file st_readme.txt
|
||||
* @author MCD Application Team
|
||||
* @brief This file lists the main modification done by STMicroelectronics on
|
||||
* LoRa for integration with STM32Cube solution.
|
||||
* For more details on LoRa implementation on STM32Cube, please refer
|
||||
* to UM2073 "STM32 LORA Expansion Package for STM32Cube "
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
@endverbatim
|
||||
|
||||
### V1.2.4/28-Nov-2019 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac from Semtech/StackForce develop branch (31-Oct-2019 commits, version 4.4.2)
|
||||
|
||||
+ Patterns/basic and Patterns/modem directory structure change
|
||||
|
||||
+ update files license
|
||||
|
||||
+ certification obtained with LoRAWAN version v1.0.2 in the following regions:
|
||||
- EU868
|
||||
- IN865
|
||||
- KR920
|
||||
- AS923
|
||||
- US915
|
||||
|
||||
|
||||
### V1.2.3/20-Sept-2019 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac from Semtech/StackForce develop branch (17-Jun-2019 commits, 4.4.2 release candidate)
|
||||
https://github.com/Lora-net/LoRaMac-node/tree/6231a5d65806142a6f887e6183227b8da9e49238
|
||||
|
||||
+ Various bug fixes and enhancements
|
||||
|
||||
+ Removed inclusions of radio.h, utilities.h, etc. from loraMac.h API
|
||||
+ Lora.c/h and lora-test.c/h moved from Certifications/ to Patterns/Basic
|
||||
|
||||
### V1.2.2/17-June-2019 ###
|
||||
===============================
|
||||
+ Trace logging & LoRa Mac version display updates
|
||||
+ Some function prototypes added
|
||||
|
||||
### V1.2.1/13-December-2018 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.4.2-rc.5 from Semtech/StackForce develop branch
|
||||
|
||||
### V1.2.0/10-July-2018 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.4.2-rc.1 from Semtech/StackForce develop branch
|
||||
|
||||
+ Supports Class B
|
||||
+ Features secure element API
|
||||
+ Added RU864 region
|
||||
+ Removed US915-Hybrid
|
||||
|
||||
### V1.1.5/30-March-2018 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.4.1 from Semtech/StackForce
|
||||
|
||||
### V1.1.4/08-January-2018 ###
|
||||
===============================
|
||||
+ Bug fix in McpsIndication related to downlink Application data buffer
|
||||
|
||||
### V1.1.3/20-December-2017 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac from Semtech/StackForce develop branch (10-Oct-2017 commits, 4.4.1 release candidate)
|
||||
https://github.com/Lora-net/LoRaMac-node/tree/ae0c9cc5d53ebbc11437dfe9711a1c3a1114dc5f
|
||||
|
||||
+ Merge pull request #302 from nestorayuso/patch-3
|
||||
|
||||
### V1.1.2/08-September-2017 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.4.0 release from Semtech/StackForce
|
||||
https://github.com/Lora-net/LoRaMac-node/tree/f42be67be402a40b3586724800771bfe13fb18e6
|
||||
|
||||
+ AckTimeoutRetriesCounter must be reset every time a new request (unconfirmed or confirmed) is performed.
|
||||
+ Added verification for the power parameter in order to check that it is greater or equal to 0.
|
||||
|
||||
+ Enhancement for regions without FSK modulation support.
|
||||
+ Bug fix for RX window 2 in class c mode.
|
||||
+ AdrAckReq bit must be set to false as soon as we reach the lowest datarate.
|
||||
+ MacCommandsBufferIndex must be reset when the mac commands are being sent on port 0.
|
||||
+ Fixed RegionCommonSetBandTxDone in order to also update band->LastTxDoneTime when performing the Join procedure.
|
||||
+ Added verification of payload size for Unconfirmed and Confirmed messages depending on Dwell time.
|
||||
|
||||
+ Added missing Rx1 timeout handling.
|
||||
+ Updated all regions to use MAX output power by default.
|
||||
+ Merge remote-tracking branch 'origin/develop' into develop
|
||||
+ Bug fix in KR920 - update the maxEIRP calculation for continuous wave
|
||||
+ Bug fix in IN865 - Update the band of the default channels
|
||||
+ Bug fix in AS923 - for RX use always the payload limitation of dwell 0
|
||||
+ Update function RegionCommonChanVerifyDr. Perform an 'AND' operation for security
|
||||
+ Move the verification of ADR parameters into the common section. Update all regions with the related changes
|
||||
+ Update comment for function RegionLinkAdrReq
|
||||
+ Apply variables to data structure LinkAdrReqParams_t
|
||||
+ Bug fix for KR920
|
||||
+ Rename data structure LinkAdrParams_t
|
||||
+ Issue(#238): Apply missing variable in sSetBandTxDoneParams
|
||||
+ Bug fix in processing MAC commands for case SRV_MAC_TX_PARAM_SETUP_REQ.
|
||||
+ Isse(#238): Apply missing variable in struct sBand
|
||||
+ Update the MAC to enable the server to control the Channels Mask and the number of transmissions even ADR is off
|
||||
+ Issue(#238): Update the backoff procedure for all regions. Move code parts into the common section
|
||||
+ Update implementation to allow automatic MAC answers on port 0
|
||||
+ Issue(#253): Delete all preconfigured channels when performing a join request
|
||||
+ Initialize variable phyParam in functions RegionXXGetPhyParam
|
||||
+ Remove assert_param from the radio drivers
|
||||
+ Synchronize function RegionXXTxConfig
|
||||
+ Update carrier sense functionality for LBT
|
||||
+ Issue(#259): Update comment for variable HasLoopedThroughMain
|
||||
+ Issue(#257): Fix typo in OnRxWindow2TimerEvent
|
||||
+ Change scientific notation to numeric notation
|
||||
+ Merge pull request #260 from clmklk/AU915
|
||||
|
||||
+ AU915: update Datarate limits according to LoRaWan 1.0.2rB
|
||||
+ AU915: update Downstream datarate table according to LoRaWan 1.0.2rB
|
||||
|
||||
+ Merge pull request #225 from OpenChirp/patch_1
|
||||
|
||||
### V1.1.1/01-June-2017 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac from Semtech/StackForce develop branch (30-May-2017 commits, 4.4.0 release candidate)
|
||||
https://github.com/Lora-net/LoRaMac-node/tree/e2f35db75c1b449379d3b520c2d4e5922a9f5c81
|
||||
|
||||
+ Issue(235): Update functions RegionXXNextChannel.
|
||||
+ Issue(238): Update initialization value of nextTxDelay.
|
||||
+ Issue(234): Report back the aggregated time off.
|
||||
+ Issue(232): Relocate function call to CalculateBackOff.
|
||||
+ Issue(239): Update band TX power to the maximum.
|
||||
+ Update LimitTxPower for US915.
|
||||
+ Bug fix in function RegionCN470Verify.
|
||||
+ Bug fix in function RegionAU915Verify.
|
||||
+ Issue(229): Fix issue when receiving frames in second RX2 in Class C.
|
||||
+ Add a ommand to get the next lower datarate.
|
||||
+ Group initializations
|
||||
+ Update regional definitions of KR920.
|
||||
+ Update regional definitions of EU868.
|
||||
+ Issue(239): Update regional definitions of AU915.
|
||||
+ Update regional definitions of AU915.
|
||||
+ Update regional definitions of AS923.
|
||||
+ Update TX power computations.
|
||||
|
||||
+ Remove duplicated call to ApplyDrOffset in function RegionRxConfig.
|
||||
+ Relocate the datarate, up- and downlink dwell time into a structure.
|
||||
+ Change API of RegionGetPhyParam and the related functions.
|
||||
+ Bug fix in function LoRaMacQueryTxPossible.
|
||||
+ Apply patch for dwell time and minimum datarate.
|
||||
+ Change the default datarate to DR_2 for AS923.
|
||||
+ Take dwell time for ADR calculations and datarate settings into account.
|
||||
+ Update LoRaMacQueryTxPossible to reset the MAC commands buffer.
|
||||
|
||||
+ Issue(#221): Add the dwell time in function ValidatePayloadLength.
|
||||
+ Increase the transmission and reception timeout for KR920.
|
||||
+ Bug fix in functions OnRxWindowXTimerEvent.
|
||||
+ Remove datarate assignment.
|
||||
+ Setup the downlink and uplink dwell time default value to 1.
|
||||
+ Add frequency range check for AS923
|
||||
+ Issue(#221): Bug fix in max payload size calculation.
|
||||
|
||||
+ GitHub reported issues corrections.
|
||||
+ Changed the AdrAckCounter handling as expected by the test houses.
|
||||
+ Fix an issue where the node stopped transmitting.
|
||||
+ Removed useless LoRaMacPayload buffer.
|
||||
+ MAC layer indications handling simplification.
|
||||
+ Relocate parameter settings from ResetMacParameters to the initialization.
|
||||
|
||||
### V1.1.0/27-February-2017 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.4.0 from Semtech/StackForce from the develop branch
|
||||
|
||||
### V1.0.3/01-January-2017 ###
|
||||
===============================
|
||||
+ Read date between 2 successive read time to make sure date is ok
|
||||
|
||||
### V1.0.2/15-November-2016 ###
|
||||
===============================
|
||||
+ Corrected 1 bug in LoRaMac-board.h: RX_WND_2_CHANNEL for EU is now back at DR_0
|
||||
+ Corrected 1 bug in LoRaMac.c for dataRate adaptation
|
||||
|
||||
### V1.0.1/15-September-2016 ###
|
||||
===============================
|
||||
+ Implements LoRa Mac 4.3.0 from Semtech/StackForce
|
||||
|
||||
### V1.0.0/01-July-2016 ###
|
||||
===============================
|
||||
+ First R1.0.0 customized version for STM32Cube solution.
|
||||
+ Comissioning_template.h in /Conf contains all Lora Ids to connect on LoRa network
|
||||
It is provided as a template. It must be moved to /Projects/inc/ as Comissioning.h
|
||||
+ All files in Conf/src are provided as template and must be copied in /Projects/src.
|
||||
+ All files in Conf/inc are provided as template and must be copied in /Projects/inc.
|
||||
#if 0 and #endif must be removed to enable the template in the user directory
|
||||
+ Implements LoRa Mac 4.2.0 from Semtech/StackForce
|
||||
+ \Lora\Mac\LoRaMac.c : replace floating exponent e3 and e6 by int number
|
||||
+ \Lora\Utilities\delay.c : cast uint32_t
|
||||
+ Modified intensively timeServer.c
|
||||
+ new low layer interfacing Cube HAL (hw_rtc.c, hw_gpio.c and hw_spi.c)
|
||||
+ added lora.c as an interface layer to ease product integration
|
||||
|
||||
|
||||
* <h3><center>© COPYRIGHT STMicroelectronics</center></h3>
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
--- Revised BSD License ---
|
||||
Copyright (c) 2013, SEMTECH S.A.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the Semtech corporation nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. 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.
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2013 Semtech
|
||||
|
||||
Description: Generic radio driver definition
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
||||
Maintainer: Miguel Luis and Gregory Cristian
|
||||
*/
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* Portions COPYRIGHT 2019 STMicroelectronics
|
||||
*
|
||||
* @file radio.h
|
||||
* @author MCD Application Team
|
||||
* @brief generic radio driver definition
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RADIO_H__
|
||||
#define __RADIO_H__
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
||||
/*!
|
||||
* Radio driver supported modems
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
MODEM_FSK = 0,
|
||||
MODEM_LORA,
|
||||
MODEM_BPSK,
|
||||
MODEM_SIGFOX_TX,
|
||||
MODEM_SIGFOX_RX,
|
||||
}RadioModems_t;
|
||||
|
||||
/*!
|
||||
* Radio driver internal state machine states definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RF_IDLE = 0, //!< The radio is idle
|
||||
RF_RX_RUNNING, //!< The radio is in reception state
|
||||
RF_TX_RUNNING, //!< The radio is in transmission state
|
||||
RF_CAD, //!< The radio is doing channel activity detection
|
||||
}RadioState_t;
|
||||
|
||||
/*!
|
||||
* \brief Radio driver callback functions
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*!
|
||||
* \brief Tx Done callback prototype.
|
||||
*/
|
||||
void ( *TxDone )( void );
|
||||
/*!
|
||||
* \brief Tx Timeout callback prototype.
|
||||
*/
|
||||
void ( *TxTimeout )( void );
|
||||
/*!
|
||||
* \brief Rx Done callback prototype.
|
||||
*
|
||||
* \param [IN] payload Received buffer pointer
|
||||
* \param [IN] size Received buffer size
|
||||
* \param [IN] rssi RSSI value computed while receiving the frame [dBm]
|
||||
* \param [IN] snr SNR value computed while receiving the frame [dB]
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: SNR value in dB
|
||||
*/
|
||||
void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
|
||||
/*!
|
||||
* \brief Rx Timeout callback prototype.
|
||||
*/
|
||||
void ( *RxTimeout )( void );
|
||||
/*!
|
||||
* \brief Rx Error callback prototype.
|
||||
*/
|
||||
void ( *RxError )( void );
|
||||
/*!
|
||||
* \brief FHSS Change Channel callback prototype.
|
||||
*
|
||||
* \param [IN] currentChannel Index number of the current channel
|
||||
*/
|
||||
void ( *FhssChangeChannel )( uint8_t currentChannel );
|
||||
|
||||
/*!
|
||||
* \brief CAD Done callback prototype.
|
||||
*
|
||||
* \param [IN] channelDetected Channel Activity detected during the CAD
|
||||
*/
|
||||
void ( *CadDone ) ( bool channelActivityDetected );
|
||||
}RadioEvents_t;
|
||||
|
||||
/*!
|
||||
* \brief Radio driver definition
|
||||
*/
|
||||
struct Radio_s
|
||||
{
|
||||
/*!
|
||||
* \brief Initializes the io
|
||||
*/
|
||||
// void ( *IoInit )( void );
|
||||
/*!
|
||||
* \brief Deinitializes the io
|
||||
*/
|
||||
// void ( *IoDeInit )( void );
|
||||
/*!
|
||||
* \brief Initializes the radio
|
||||
*
|
||||
* \param [IN] events Structure containing the driver callback functions
|
||||
* \param [OUT] returns radioWakeUpTime
|
||||
*/
|
||||
uint32_t ( *Init )( RadioEvents_t *events );
|
||||
/*!
|
||||
* Return current radio status
|
||||
*
|
||||
* \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING]
|
||||
*/
|
||||
RadioState_t ( *GetStatus )( void );
|
||||
/*!
|
||||
* \brief Configures the radio with the given modem
|
||||
*
|
||||
* \param [IN] modem Modem to be used [0: FSK, 1: LoRa]
|
||||
*/
|
||||
void ( *SetModem )( RadioModems_t modem );
|
||||
/*!
|
||||
* \brief Sets the channel frequency
|
||||
*
|
||||
* \param [IN] freq Channel RF frequency
|
||||
*/
|
||||
void ( *SetChannel )( uint32_t freq );
|
||||
/*!
|
||||
* \brief Checks if the channel is free for the given time
|
||||
*
|
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
|
||||
* \param [IN] freq Channel RF frequency
|
||||
* \param [IN] rssiThresh RSSI threshold
|
||||
* \param [IN] maxCarrierSenseTime Max time while the RSSI is measured
|
||||
*
|
||||
* \retval isFree [true: Channel is free, false: Channel is not free]
|
||||
*/
|
||||
bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime );
|
||||
/*!
|
||||
* \brief Generates a 32 bits random value based on the RSSI readings
|
||||
*
|
||||
* \remark This function sets the radio in LoRa modem mode and disables
|
||||
* all interrupts.
|
||||
* After calling this function either Radio.SetRxConfig or
|
||||
* Radio.SetTxConfig functions must be called.
|
||||
*
|
||||
* \retval randomValue 32 bits random value
|
||||
*/
|
||||
uint32_t ( *Random )( void );
|
||||
/*!
|
||||
* \brief Sets the reception parameters
|
||||
*
|
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
|
||||
* \param [IN] bandwidth Sets the bandwidth
|
||||
* FSK : >= 2600 and <= 250000 Hz
|
||||
* LoRa: [0: 125 kHz, 1: 250 kHz,
|
||||
* 2: 500 kHz, 3: Reserved]
|
||||
* \param [IN] datarate Sets the Datarate
|
||||
* FSK : 600..300000 bits/s
|
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
|
||||
* 10: 1024, 11: 2048, 12: 4096 chips]
|
||||
* \param [IN] coderate Sets the coding rate (LoRa only)
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
|
||||
* \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only)
|
||||
* FSK : >= 2600 and <= 250000 Hz
|
||||
* LoRa: N/A ( set to 0 )
|
||||
* \param [IN] preambleLen Sets the Preamble length
|
||||
* FSK : Number of bytes
|
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols)
|
||||
* \param [IN] symbTimeout Sets the RxSingle timeout value
|
||||
* FSK : timeout in number of bytes
|
||||
* LoRa: timeout in symbols
|
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
|
||||
* \param [IN] payloadLen Sets payload length when fixed length is used
|
||||
* \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON]
|
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [0: OFF, 1: ON]
|
||||
* \param [IN] hopPeriod Number of symbols between each hop
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: Number of symbols
|
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only)
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [0: not inverted, 1: inverted]
|
||||
* \param [IN] rxContinuous Sets the reception in continuous mode
|
||||
* [false: single mode, true: continuous mode]
|
||||
*/
|
||||
void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth,
|
||||
uint32_t datarate, uint8_t coderate,
|
||||
uint32_t bandwidthAfc, uint16_t preambleLen,
|
||||
uint16_t symbTimeout, bool fixLen,
|
||||
uint8_t payloadLen,
|
||||
bool crcOn, bool freqHopOn, uint8_t hopPeriod,
|
||||
bool iqInverted, bool rxContinuous );
|
||||
/*!
|
||||
* \brief Sets the transmission parameters
|
||||
*
|
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
|
||||
* \param [IN] power Sets the output power [dBm]
|
||||
* \param [IN] fdev Sets the frequency deviation (FSK only)
|
||||
* FSK : [Hz]
|
||||
* LoRa: 0
|
||||
* \param [IN] bandwidth Sets the bandwidth (LoRa only)
|
||||
* FSK : 0
|
||||
* LoRa: [0: 125 kHz, 1: 250 kHz,
|
||||
* 2: 500 kHz, 3: Reserved]
|
||||
* \param [IN] datarate Sets the Datarate
|
||||
* FSK : 600..300000 bits/s
|
||||
* LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
|
||||
* 10: 1024, 11: 2048, 12: 4096 chips]
|
||||
* \param [IN] coderate Sets the coding rate (LoRa only)
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
|
||||
* \param [IN] preambleLen Sets the preamble length
|
||||
* FSK : Number of bytes
|
||||
* LoRa: Length in symbols (the hardware adds 4 more symbols)
|
||||
* \param [IN] fixLen Fixed length packets [0: variable, 1: fixed]
|
||||
* \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON]
|
||||
* \param [IN] freqHopOn Enables disables the intra-packet frequency hopping
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [0: OFF, 1: ON]
|
||||
* \param [IN] hopPeriod Number of symbols between each hop
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: Number of symbols
|
||||
* \param [IN] iqInverted Inverts IQ signals (LoRa only)
|
||||
* FSK : N/A ( set to 0 )
|
||||
* LoRa: [0: not inverted, 1: inverted]
|
||||
* \param [IN] timeout Transmission timeout [ms]
|
||||
*/
|
||||
void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||
uint32_t bandwidth, uint32_t datarate,
|
||||
uint8_t coderate, uint16_t preambleLen,
|
||||
bool fixLen, bool crcOn, bool freqHopOn,
|
||||
uint8_t hopPeriod, bool iqInverted, uint32_t timeout );
|
||||
/*!
|
||||
* \brief Checks if the given RF frequency is supported by the hardware
|
||||
*
|
||||
* \param [IN] frequency RF frequency to be checked
|
||||
* \retval isSupported [true: supported, false: unsupported]
|
||||
*/
|
||||
bool ( *CheckRfFrequency )( uint32_t frequency );
|
||||
/*!
|
||||
* \brief Computes the packet time on air in ms for the given payload
|
||||
*
|
||||
* \Remark Can only be called once SetRxConfig or SetTxConfig have been called
|
||||
*
|
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
|
||||
* \param [IN] pktLen Packet payload length
|
||||
*
|
||||
* \retval airTime Computed airTime (ms) for the given packet payload length
|
||||
*/
|
||||
uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen );
|
||||
/*!
|
||||
* \brief Sends the buffer of size. Prepares the packet to be sent and sets
|
||||
* the radio in transmission
|
||||
*
|
||||
* \param [IN]: buffer Buffer pointer
|
||||
* \param [IN]: size Buffer size
|
||||
*/
|
||||
void ( *Send )( uint8_t *buffer, uint8_t size );
|
||||
/*!
|
||||
* \brief Sets the radio in sleep mode
|
||||
*/
|
||||
void ( *Sleep )( void );
|
||||
/*!
|
||||
* \brief Sets the radio in standby mode
|
||||
*/
|
||||
void ( *Standby )( void );
|
||||
/*!
|
||||
* \brief Sets the radio in reception mode for the given time
|
||||
* \param [IN] timeout Reception timeout [ms]
|
||||
* [0: continuous, others timeout]
|
||||
*/
|
||||
void ( *Rx )( uint32_t timeout );
|
||||
/*!
|
||||
* \brief Start a Channel Activity Detection
|
||||
*/
|
||||
void ( *StartCad )( void );
|
||||
/*!
|
||||
* \brief Sets the radio in continuous wave transmission mode
|
||||
*
|
||||
* \param [IN]: freq Channel RF frequency
|
||||
* \param [IN]: power Sets the output power [dBm]
|
||||
* \param [IN]: time Transmission mode timeout [s]
|
||||
*/
|
||||
void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time );
|
||||
/*!
|
||||
* \brief Reads the current RSSI value
|
||||
*
|
||||
* \retval rssiValue Current RSSI value in [dBm]
|
||||
*/
|
||||
int16_t ( *Rssi )( RadioModems_t modem );
|
||||
/*!
|
||||
* \brief Writes the radio register at the specified address
|
||||
*
|
||||
* \param [IN]: addr Register address
|
||||
* \param [IN]: data New register value
|
||||
*/
|
||||
void ( *Write )( uint16_t addr, uint8_t data );
|
||||
/*!
|
||||
* \brief Reads the radio register at the specified address
|
||||
*
|
||||
* \param [IN]: addr Register address
|
||||
* \retval data Register value
|
||||
*/
|
||||
uint8_t ( *Read )( uint16_t addr );
|
||||
/*!
|
||||
* \brief Writes multiple radio registers starting at address
|
||||
*
|
||||
* \param [IN] addr First Radio register address
|
||||
* \param [IN] buffer Buffer containing the new register's values
|
||||
* \param [IN] size Number of registers to be written
|
||||
*/
|
||||
// void ( *WriteBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
/*!
|
||||
* \brief Reads multiple radio registers starting at address
|
||||
*
|
||||
* \param [IN] addr First Radio register address
|
||||
* \param [OUT] buffer Buffer where to copy the registers data
|
||||
* \param [IN] size Number of registers to be read
|
||||
*/
|
||||
// void ( *ReadBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size );
|
||||
/*!
|
||||
* \brief Sets the maximum payload length.
|
||||
*
|
||||
* \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa]
|
||||
* \param [IN] max Maximum payload length in bytes
|
||||
*/
|
||||
void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max );
|
||||
/*!
|
||||
* \brief Sets the network to public or private. Updates the sync byte.
|
||||
*
|
||||
* \remark Applies to LoRa modem only
|
||||
*
|
||||
* \param [IN] enable if true, it enables a public network
|
||||
*/
|
||||
void ( *SetPublicNetwork )( bool enable );
|
||||
/*!
|
||||
* \brief Gets the time required for the board plus radio to get out of sleep.[ms]
|
||||
*
|
||||
* \retval time Radio plus board wakeup time in ms.
|
||||
*/
|
||||
uint32_t ( *GetWakeupTime )( void );
|
||||
/*!
|
||||
* \brief Process radio irq
|
||||
*/
|
||||
void ( *IrqProcess )( void );
|
||||
/*
|
||||
* The next functions are available only on SX126x radios.
|
||||
*/
|
||||
/*!
|
||||
* \brief Sets the radio in reception mode with Max LNA gain for the given time
|
||||
*
|
||||
* \remark Available on SX126x radios only.
|
||||
*
|
||||
* \param [IN] timeout Reception timeout [ms]
|
||||
* [0: continuous, others timeout]
|
||||
*/
|
||||
void ( *RxBoosted )( uint32_t timeout );
|
||||
/*!
|
||||
* \brief Sets the Rx duty cycle management parameters
|
||||
*
|
||||
* \remark Available on SX126x radios only.
|
||||
*
|
||||
* \param [in] rxTime Structure describing reception timeout value
|
||||
* \param [in] sleepTime Structure describing sleep timeout value
|
||||
*/
|
||||
void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime );
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Sets the Transmitter in continuous PRBS mode
|
||||
*
|
||||
* \remark power and datarate shall be configured prior calling TxPrbs
|
||||
*/
|
||||
void (*TxPrbs) ( void );
|
||||
/*!
|
||||
* @brief Sets the Transmitter in continuous unmodulated Carrier mode
|
||||
*/
|
||||
void (*TxCw) ( void );
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Radio driver
|
||||
*
|
||||
* \remark This variable is defined and initialized in the specific radio
|
||||
* board implementation
|
||||
*/
|
||||
extern const struct Radio_s Radio;
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
|
||||
#endif // __RADIO_H__
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file mw_log_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief Interface layer CM4 System to MBMUX (Mailbox Multiplexer)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MW_LOG_CONF_H__
|
||||
#define __MW_LOG_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include "trace.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define MW_LOG_ENABLED
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
#ifdef MW_LOG_ENABLED
|
||||
#define PPRINTF(...) do{ } while( 0!= TraceSend(TIME_STAMP_OFF, 0, __VA_ARGS__) ) //Polling Mode
|
||||
#define TPRINTF(...) do{ {TraceSend(TIME_STAMP_ON, 0, __VA_ARGS__);} }while(0)//with timestamp
|
||||
#define PRINTF(...) do{ {TraceSend(TIME_STAMP_OFF, 0, __VA_ARGS__);} }while(0)
|
||||
#define MW_LOG(VL, TS, ...) do{ {TraceSend(TS, VL, __VA_ARGS__);} }while(0)
|
||||
|
||||
#else
|
||||
#define PPRINTF(...)
|
||||
#define TPRINTF(...)
|
||||
#define PRINTF(...)
|
||||
#define MW_LOG(VL, TS, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MW_LOG_CONF_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,51 @@
|
|||
/*******************************************************************************
|
||||
* @file radio_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief driver sx1276 board (sx1276mb1mas for EU and sx1276mb1las for US)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RADIO_CONF_H__
|
||||
#define __RADIO_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "platform.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Defines ------------------------*/
|
||||
#define RADIO_RX_BUF_SIZE 255
|
||||
|
||||
/* Function mapping */
|
||||
#define RADIO_DELAY_MS HAL_Delay
|
||||
#define RADIO_MEMSET8( dest, value, size ) UTIL_MEM_cpy_8( dest, value, size)
|
||||
|
||||
#define LET_SUBGHZ_MW_USING_DGB_LINE1_PIN
|
||||
#define LET_SUBGHZ_MW_USING_DGB_LINE2_PIN
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __RADIO_CONF_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* @file radio_mw_version.h
|
||||
* @author MCD Application Team
|
||||
* @brief defines the radio driver version
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __RADIO_MW_VERSION_H__
|
||||
#define __RADIO_MW_VERSION_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* __SUBGH_RADIO_TYPE: 0x01 WTM32WL
|
||||
0x61 sx126x
|
||||
0x72 sx1272
|
||||
0x76 sx1276 */
|
||||
|
||||
#define __SUBGH_RADIO_TYPE (0x01U) /*!< [31:24] main version */
|
||||
#define __SUBGH_MW_VERSION_MAIN (0x01U) /*!< [23:16] main version */
|
||||
#define __SUBGH_MW_VERSION_SUB1 (0x00U) /*!< [15:8] sub1 version */
|
||||
#define __SUBGH_MW_VERSION_SUB2 (0x00U) /*!< [7:0] sub2 version */
|
||||
#define __SUBGH_MW_VERSION ((__SUBGH_RADIO_TYPE <<24)\
|
||||
|(__SUBGH_MW_VERSION_MAIN << 16)\
|
||||
|(__SUBGH_MW_VERSION_SUB1 << 8 )\
|
||||
|(__SUBGH_MW_VERSION_SUB2))
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__RADIO_MW_VERSION_H__*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file adc.c
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of the ADC instances
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "platform.h"
|
||||
#include "adc.h"
|
||||
#include "dma.h"
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
ADC_HandleTypeDef hadc1;
|
||||
DMA_HandleTypeDef hdma_adc1;
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief ADC1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void MX_ADC1_Init(void)
|
||||
{
|
||||
/* USER CODE BEGIN ADC1_Init 0 */
|
||||
|
||||
/* USER CODE END ADC1_Init 0 */
|
||||
|
||||
|
||||
|
||||
/* USER CODE BEGIN ADC1_Init 1 */
|
||||
|
||||
/* USER CODE END ADC1_Init 1 */
|
||||
/** Common config
|
||||
*/
|
||||
hadc1.Instance = ADC1;
|
||||
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
|
||||
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
|
||||
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; /* Sequencer set to fully configurable: only the rank 1 is enabled (no scan sequence on several ranks) */
|
||||
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
hadc1.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
|
||||
hadc1.Init.NbrOfConversion = 1; /* Parameter discarded because sequencer is disabled. Parameter relevancy depending on setting of parameter "ScanConvMode" */
|
||||
hadc1.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
|
||||
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* Software start to trig the 1st conversion manually, without external event */
|
||||
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig of conversion by software start (no external event) */
|
||||
hadc1.Init.DMAContinuousRequests = DISABLE; /* ADC with DMA transfer: continuous requests to DMA disabled (default state) since DMA is not used in this example. */
|
||||
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
|
||||
hadc1.Init.SamplingTimeCommon1 = LL_ADC_SAMPLINGTIME_160CYCLES_5;
|
||||
hadc1.Init.OversamplingMode = DISABLE;
|
||||
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
|
||||
if (HAL_ADC_Init(&hadc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
if (HAL_ADCEx_Calibration_Start(&hadc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN ADC1_Init 2 */
|
||||
|
||||
/* USER CODE END ADC1_Init 2 */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ADC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hadc: ADC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
|
||||
/*##-1- Enable peripherals and GPIO Clocks #################################*/
|
||||
/* Enable clock of GPIO associated to the peripheral channels */
|
||||
/* Enable clock of ADCx peripheral (core clock) */
|
||||
__HAL_RCC_ADC_CLK_ENABLE();
|
||||
|
||||
/* Note: In case of usage of asynchronous clock for ADC, with ADC setting */
|
||||
/* "AdcHandle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIVx", */
|
||||
/* the clock source has to be enabled at RCC top level using function */
|
||||
/* "HAL_RCCEx_PeriphCLKConfig()" or macro "__HAL_RCC_ADC_CONFIG()" */
|
||||
/* (refer to comments in driver file header). */
|
||||
|
||||
/*##-4- Configure the NVIC #################################################*/
|
||||
/* NVIC configuration for ADC interrupt */
|
||||
/* Priority: high-priority */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hadc: ADC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
if (hadc->Instance == ADC1)
|
||||
{
|
||||
/* USER CODE BEGIN ADC1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END ADC1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_ADC_CLK_DISABLE();
|
||||
|
||||
/**ADC1 GPIO Configuration
|
||||
PC3 ------> ADC1_IN4
|
||||
*/
|
||||
/* USER CODE BEGIN ADC1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END ADC1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file adc_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief Read status related to the chip (battery level, VREF, chip temperature)
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "adc_if.h"
|
||||
#include "app_system.h"
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "adc.h"
|
||||
#endif
|
||||
|
||||
/* External variables ---------------------------------------------------------*/
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
#endif
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/*from dtatsheet*/
|
||||
#define TEMPSENSOR_TYP_CAL1_V (( int32_t) 760) /* Internal temperature sensor, parameter V30 (unit: mV). Refer to device datasheet for min/typ/max values. */
|
||||
#define TEMPSENSOR_TYP_AVGSLOPE (( int32_t) 2500) /* Internal temperature sensor, parameter Avg_Slope (unit: uV/DegCelsius). Refer to device datasheet for min/typ/max values. */
|
||||
#define TEMPSENSOR_CAL_VREF ((uint32_t) 3000) /* Vdda value with which temperature sensor has been calibrated in production (+-10 mV). */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
#define __LL_ADC_CALC_VREFANALOG_VOLTAGE_TEMPORARY(__VREFINT_ADC_DATA__,\
|
||||
__ADC_RESOLUTION__) \
|
||||
(((uint32_t)(*VREFINT_CAL_ADDR) * VREFINT_CAL_VREF) \
|
||||
/ __LL_ADC_CONVERT_DATA_RESOLUTION((__VREFINT_ADC_DATA__), \
|
||||
(__ADC_RESOLUTION__), \
|
||||
LL_ADC_RESOLUTION_12B) \
|
||||
)
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static uint32_t ADC_ReadChannels(uint32_t channel);
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function initializes the ADC
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void SYS_InitMeasurement(void)
|
||||
{
|
||||
hadc1.Instance = ADC1;
|
||||
}
|
||||
|
||||
void SYS_DeInitMeasurement(void)
|
||||
{
|
||||
}
|
||||
|
||||
int16_t SYS_GetTemperatureLevel(void)
|
||||
{
|
||||
int16_t temperatureDegreeC = 6400; /*25degreeC in q7.8*/
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
uint32_t measuredLevel = 0;
|
||||
uint16_t batteryLevelmV = SYS_GetBatteryLevel();
|
||||
|
||||
measuredLevel = ADC_ReadChannels(ADC_CHANNEL_TEMPSENSOR);
|
||||
|
||||
/* #warning "to be replaced by __LL_ADC_CALC_TEMPERATURE when calibration data will be set in prod"*/
|
||||
temperatureDegreeC = __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(TEMPSENSOR_TYP_AVGSLOPE,
|
||||
TEMPSENSOR_TYP_CAL1_V,
|
||||
TEMPSENSOR_CAL1_TEMP,
|
||||
batteryLevelmV,
|
||||
measuredLevel,
|
||||
LL_ADC_RESOLUTION_12B);
|
||||
/*to be replaced */
|
||||
APP_LOG("temp= %d\n\r", temperatureDegreeC);
|
||||
|
||||
/* from int16 to q8.7*/
|
||||
temperatureDegreeC <<= 8;
|
||||
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
return (int16_t) temperatureDegreeC;
|
||||
}
|
||||
/**
|
||||
* @brief This function return the battery level
|
||||
* @param none
|
||||
* @retval the battery level in mV
|
||||
*/
|
||||
uint16_t SYS_GetBatteryLevel(void)
|
||||
{
|
||||
uint16_t batteryLevelmV = 3300;
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
uint32_t measuredLevel = 0;
|
||||
|
||||
measuredLevel = ADC_ReadChannels(ADC_CHANNEL_VREFINT);
|
||||
|
||||
if (measuredLevel == 0)
|
||||
{
|
||||
batteryLevelmV = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
batteryLevelmV = (3300 * 1510) / measuredLevel;
|
||||
/* #warning "to be replaced by __LL_ADC_CALC_VREFANALOG_VOLTAGE when calibration data will be set in prod" */
|
||||
}
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
return batteryLevelmV;
|
||||
}
|
||||
|
||||
/* Private function definition -----------------------------------------------*/
|
||||
/**
|
||||
* @brief This function reads the ADC channel
|
||||
* @param Channel
|
||||
* @retval Value
|
||||
*/
|
||||
static uint32_t ADC_ReadChannels(uint32_t channel)
|
||||
{
|
||||
uint32_t ADCxConvertedValues = 0;
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
MX_ADC1_Init();
|
||||
/** Configure Regular Channel */
|
||||
sConfig.Channel = channel;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
if (HAL_ADC_Start(&hadc1) != HAL_OK)
|
||||
{
|
||||
/* Start Error */
|
||||
Error_Handler();
|
||||
}
|
||||
/** Wait for end of conversion */
|
||||
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
|
||||
|
||||
/* Workaround for tempsensor value*/
|
||||
if (channel == ADC_CHANNEL_TEMPSENSOR)
|
||||
{
|
||||
if (HAL_ADC_Start(&hadc1) != HAL_OK)
|
||||
{
|
||||
/* Start Error */
|
||||
Error_Handler();
|
||||
}
|
||||
/** Wait for end of conversion */
|
||||
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
/** Wait for end of conversion */
|
||||
HAL_ADC_Stop(&hadc1) ; /* it calls also ADC_Disable() */
|
||||
|
||||
ADCxConvertedValues = HAL_ADC_GetValue(&hadc1);
|
||||
|
||||
HAL_ADC_DeInit(&hadc1);
|
||||
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
return ADCxConvertedValues;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file dma.c
|
||||
* @author MCD Application Team
|
||||
* @brief configuration of all the requested memory to memory DMA transfers
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2019 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under Ultimate Liberty license
|
||||
* SLA0044, the "License"; You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* www.st.com/SLA0044
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "dma.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure DMA */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/**
|
||||
* Enable DMA controller clock
|
||||
*/
|
||||
void MX_DMA_Init(void)
|
||||
{
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel1_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
#endif
|
||||
/* DMA1_Channel7_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
|
@ -29,9 +29,9 @@ void board_init(void)
|
|||
{
|
||||
HAL_Init();
|
||||
SystemClock_Config();
|
||||
MX_LPUART1_UART_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART2_UART_Init();
|
||||
|
||||
SystemApp_Init();
|
||||
MX_LoRaWAN_Init();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,6 +75,7 @@ void SystemClock_Config(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue