add CMOX-HMAC feature
This commit is contained in:
parent
83a763a760
commit
0d300c9db0
|
@ -79,6 +79,7 @@ typedef enum
|
|||
CFG_SEQ_Task_LoRaStoreContextEvent,
|
||||
CFG_SEQ_Task_LoRaStopJoinEvent,
|
||||
/* USER CODE BEGIN CFG_SEQ_Task_Id_t */
|
||||
CFG_SEQ_Task_YunhornSTSEventRFAC,
|
||||
CFG_SEQ_Task_YunhornSTSEventP1,
|
||||
CFG_SEQ_Task_YunhornSTSEventP2,
|
||||
/* USER CODE END CFG_SEQ_Task_Id_t */
|
||||
|
|
|
@ -215,10 +215,16 @@
|
|||
#define MinorVer 02U
|
||||
#define SubMinorVer 23U
|
||||
#define FirmwareVersion 3U
|
||||
#define STS_NVM_CFG_SIZE 32U
|
||||
#define STS_CFG_PCFG_SIZE 28U
|
||||
#define STS_CFG_CMD_SIZE 30U
|
||||
#define STS_CFG_CMD_SHORT_LEN 8U
|
||||
#define STS_MODE_COLOR_CMD_LEN 5U
|
||||
|
||||
#define YUNHORN_STS_M7_NVM_CFG_SIZE 3U
|
||||
#define YUNHORN_STS_M7_CFG_CMD_SIZE 9U
|
||||
#define YUNHORN_STS_MAX_NVM_CFG_SIZE 32U
|
||||
|
||||
#define YUNHORN_STS_MAX_NVM_CFG_SIZE 64U
|
||||
#define YUNHORN_STS_AC_CODE_SIZE 20U
|
||||
#include "yunhorn_sts_motion_sensor.h"
|
||||
#define YUNHORN_STS_M7_LORA_APP_DATA_PORT 20U
|
||||
#define YUNHORN_STS_M7_LORA_APP_HTBT_PORT 21U
|
||||
|
@ -307,7 +313,7 @@
|
|||
* DEVICE TYPE On-chip Flash
|
||||
* Address range 0800 0000H - 0803 FFFFH Size: 0x0004 0000
|
||||
*/
|
||||
|
||||
#define STS_BURN_IN_RFAC ((uint32_t) 2)
|
||||
#define FLASH_USER_START_ADDR ((void *) 0x0803F800U) // Last 2kB of flash
|
||||
#define FLASH_USER_CONFIG_SIZE ((void *) 0x000007FFU) //0x400=1KB=1024
|
||||
#define FLASH_USER_END_ADDR (FLASH_USER_START_ADDR + FLASH_USER_CONFIG - 1)
|
||||
|
|
|
@ -367,29 +367,59 @@ typedef struct
|
|||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
|
||||
enum {
|
||||
enum nvm_order {
|
||||
NVM_MTM1=0,
|
||||
NVM_MTM2,
|
||||
NVM_VER,
|
||||
NVM_HWV,
|
||||
NVM_PERIODICITY_H,
|
||||
NVM_PERIODICITY_L,
|
||||
NVM_PERIODICITY,
|
||||
NVM_UNIT,
|
||||
NVM_LEN
|
||||
NVM_SAMPLING,
|
||||
NVM_S_UNIT,
|
||||
NVM_WORK_MODE,
|
||||
NVM_SERVICE_MASK,
|
||||
NVM_RESERVE01, //10
|
||||
NVM_LEN, //11, 32=0x20
|
||||
NVM_CFG_START, //12, p[0] bytes for configs,
|
||||
//13, p[1]
|
||||
//14, p[2]
|
||||
// ...
|
||||
//39, P[27]
|
||||
NVM_FALL_DETECTION_ACC_THRESHOLD=40, //40
|
||||
NVM_FALL_DETECTION_DEPTH_THRESHOLD, //41
|
||||
NVM_FALL_DETECTION_RESERVE, //42
|
||||
NVM_OCCUPANCY_OVERTIME_THRESHOLD, //43
|
||||
NVM_AC_CODE_START=44 //STORED, NO UPLOAD
|
||||
//63, 20 bytes for AC code
|
||||
};
|
||||
|
||||
typedef struct sts_cfg_nvm {
|
||||
uint8_t mtmcode1;
|
||||
uint8_t mtmcode2;
|
||||
uint8_t version;
|
||||
uint8_t hardware_ver;
|
||||
uint8_t periodicity_h; //count of duty cycle duration high {0,9}
|
||||
uint8_t periodicity_l; //count of duty cycle duration low {0,9}
|
||||
uint8_t unit; // time unit of duty cycle duration, in 'S', 'M','H' seconds, minutes, hours
|
||||
uint8_t length;
|
||||
uint8_t p[YUNHORN_STS_MAX_NVM_CFG_SIZE-8];
|
||||
uint8_t periodicity; //count of uplink duty cycle duration high {99}
|
||||
uint8_t unit; // uplink time unit of duty cycle duration, in 'S', 'M','H' seconds, minutes, hours
|
||||
uint8_t sampling; // heart-beat interval or count of sampling duty cycle duration high {99}
|
||||
uint8_t s_unit; // Heart-beat interval or sampling time unit of duty cycle duration, in 'S', 'M','H' seconds, minutes, hours
|
||||
uint8_t work_mode;
|
||||
uint8_t sts_service_mask;
|
||||
uint8_t reseve01;
|
||||
uint8_t length; // length of following parameters except AC CODE(20bytes)
|
||||
uint8_t p[STS_CFG_PCFG_SIZE];
|
||||
uint8_t fall_detection_acc_threshold; // 0 - 9: 0:disable: 1-9 accelaration mg/s2
|
||||
uint8_t fall_detection_depth_threshold; // 0 - 9: 0:disable: 1-9 fall down depth * 10 cm
|
||||
uint8_t fall_detection_reserve;
|
||||
uint8_t occupancy_overtime_threshold; // 0 - 9£º 0£ºdisable, 1-9 occupy over time threshold * 10 min
|
||||
uint8_t ac[YUNHORN_STS_AC_CODE_SIZE]; // authorization code, 20 bytes MCU UUID coded
|
||||
} sts_cfg_nvm_t;
|
||||
|
||||
|
||||
#define STS_SERVICE_MASK_L0 (0) // Service normal , no mask off
|
||||
#define STS_SERVICE_MASK_L1 (1) // service mask level 1, sensing data upload in silence mode, node appearance silence (no LED, No display, no sound, no vibration)
|
||||
#define STS_SERVICE_MASK_L2 (2) // service mask level 2, NO sensing data upload (event or periodicity)
|
||||
#define STS_SERVICE_MASK_L3 (3) // service mask level 3, NO responsing to cloud control command, or config change/responding, EXCEPT STS_SERVICE_MASK_ON_OFF cmd
|
||||
|
||||
|
||||
/**
|
||||
* @brief Store/Write/Flash Configuration in RW RAM
|
||||
*/
|
||||
|
@ -443,6 +473,8 @@ void STS_MOTION_SENSOR_Initialization(void);
|
|||
void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size);
|
||||
void STS_SENSOR_Function_Test_Process(void);
|
||||
|
||||
void STS_YunhornSTSEventRFAC_Process(void);
|
||||
void STS_YunhornAuthenticationCode_Process(void);
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
/*
|
||||
|
|
|
@ -39,15 +39,32 @@
|
|||
/* USER CODE BEGIN Includes */
|
||||
#include "yunhorn_sts_sensors.h"
|
||||
#include "yunhorn_sts_motion_sensor.h"
|
||||
#include "sts_cmox_hmac_sha.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* External variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EV */
|
||||
volatile uint8_t mems_int1_detected = 0;
|
||||
volatile uint32_t periodicity_length=0;
|
||||
volatile uint8_t sts_service_mask;
|
||||
volatile uint32_t rfac_timer=0;
|
||||
extern hmac_result_t hmac_result;
|
||||
volatile uint8_t sts_work_mode =0;
|
||||
volatile uint8_t sts_ac_code[YUNHORN_STS_AC_CODE_SIZE]={0x0};
|
||||
volatile uint8_t heart_beat_timer=0, sts_lorawan_joined=0;
|
||||
volatile sts_cfg_nvm_t sts_cfg_nvm={sts_mtmcode1,sts_mtmcode2, sts_version, sts_hardware_ver,
|
||||
0x00,0x05,'M',0x03,{0x08,0x04,0x02}};
|
||||
0x00,'M', 0x05,'M', 0x04,0x00,0x00,0x20,
|
||||
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
|
||||
0x01,0x03,0x00,0x02,
|
||||
{0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0}
|
||||
};
|
||||
|
||||
volatile uint32_t SamplingPeriodicity = 1000; //unit ms
|
||||
volatile uint32_t HeartBeatPeriodicity = 120000; //unit ms
|
||||
volatile uint8_t STS_LoRa_WAN_Joined = 0;
|
||||
volatile uint8_t periodicity_level=0;
|
||||
char outbuf[128]="";
|
||||
volatile uint8_t upload_message_timer =0;
|
||||
#ifdef YUNHORN_STS_M7_ENABLED
|
||||
extern volatile uint8_t sensor_data_ready;
|
||||
extern volatile STS_M7_SensorDataTypeDef sts_m7_sensorData;
|
||||
|
@ -240,6 +257,38 @@ static void OnRxTimerLedEvent(void *context);
|
|||
*/
|
||||
static void OnJoinTimerLedEvent(void *context);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Yunhorn STS Occupancy RSS WakeUP timer callback function
|
||||
* @param context ptr of STS RSS WakeUp context
|
||||
*/
|
||||
//static void OnYunhornSTSOORSSWakeUpTimerEvent(void *context);
|
||||
|
||||
/**
|
||||
* @brief Yunhorn STS Heart Beat Periodicity Chagne function
|
||||
* @param duration of periodicty in ms (1/1000 sec)
|
||||
*/
|
||||
static void OnYunhornSTSHeartBeatPeriodicityChanged(uint32_t periodicity);
|
||||
|
||||
/**
|
||||
* @brief Yunhorn STS Heart Beat callback function
|
||||
* @param context ptr of STS Sampling Check context
|
||||
*/
|
||||
static void OnYunhornSTSHeartBeatTimerEvent(void *context);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Yunhorn STS Uploading Message periodically
|
||||
* @param context ptr of context
|
||||
*/
|
||||
//static void OnYunhornSTSUploadingMessageEvent(void *context);
|
||||
|
||||
/**
|
||||
* @brief Yunhorn RFAC Handle process
|
||||
* @param void
|
||||
*/
|
||||
static void STS_YUNHORN_RFAC_HANDLE_PROCESS(void);
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
@ -342,6 +391,12 @@ static UTIL_TIMER_Object_t RxLedTimer;
|
|||
*/
|
||||
static UTIL_TIMER_Object_t JoinLedTimer;
|
||||
|
||||
/**
|
||||
* @brief Timer to handle the YunHorn STS Sensor Heart Beat Process
|
||||
*/
|
||||
static UTIL_TIMER_Object_t YunhornSTSHeartBeatTimer;
|
||||
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
|
@ -394,6 +449,7 @@ void LoRaWAN_Init(void)
|
|||
UTIL_TIMER_Create(&TxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnTxTimerLedEvent, NULL);
|
||||
UTIL_TIMER_Create(&RxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnRxTimerLedEvent, NULL);
|
||||
UTIL_TIMER_Create(&JoinLedTimer, LED_PERIOD_TIME, UTIL_TIMER_PERIODIC, OnJoinTimerLedEvent, NULL);
|
||||
UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, HeartBeatPeriodicity, UTIL_TIMER_ONESHOT, OnYunhornSTSHeartBeatTimerEvent, NULL);
|
||||
|
||||
/* USER CODE END LoRaWAN_Init_1 */
|
||||
|
||||
|
@ -440,6 +496,8 @@ void LoRaWAN_Init(void)
|
|||
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP1), UTIL_SEQ_RFU, STS_MOTION_SENSOR_WakeUp_Process);
|
||||
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP2), UTIL_SEQ_RFU, STS_SENSOR_Function_Test_Process);
|
||||
|
||||
|
||||
UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer);
|
||||
STS_REBOOT_CONFIG_Init();
|
||||
|
||||
/* USER CODE END LoRaWAN_Init_Last */
|
||||
|
@ -591,6 +649,26 @@ static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params)
|
|||
/* USER CODE END OnRxData_1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Yunhorn STS Sensor Heart Beat Timer callback function
|
||||
* @param context ptr of STS Sampling Check context
|
||||
*/
|
||||
static void OnYunhornSTSHeartBeatTimerEvent(void *context)
|
||||
{
|
||||
heart_beat_timer = 1;
|
||||
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0);
|
||||
UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer);
|
||||
|
||||
if ((STS_LoRa_WAN_Joined ) && (sts_ac_code[0]==0x0))
|
||||
{
|
||||
/* RFAC Challenge */
|
||||
if (rfac_timer < (STS_BURN_IN_RFAC+3)) {
|
||||
rfac_timer ++;
|
||||
}
|
||||
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventRFAC), CFG_SEQ_Prio_0);
|
||||
}
|
||||
}
|
||||
|
||||
void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
||||
{
|
||||
uint8_t i=0;
|
||||
|
@ -611,7 +689,14 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
|
||||
OnSystemReset();
|
||||
} else if ((char)tlv_buf[CFG_CMD3] == 'S') { // Self Function Testing "YZS"
|
||||
|
||||
i = 0;
|
||||
memset(outbuf,0x0, sizeof(outbuf));
|
||||
|
||||
STS_SENSOR_Function_Test_Process();
|
||||
|
||||
HAL_Delay(5000);
|
||||
i=21;
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
STS_SENSOR_Function_Test_Process();
|
||||
|
||||
} else if ((char)tlv_buf[CFG_CMD3] == 'C') { // Self Function Testing "YZC" LORAWAN CLASS A/B/C
|
||||
|
@ -627,10 +712,28 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
}
|
||||
break;
|
||||
case 'M': //"YM"
|
||||
if ((char)tlv_buf[CFG_CMD3] >= '0' && (char)tlv_buf[CFG_CMD3]<='9') // Service Mask "YZM"
|
||||
{
|
||||
sts_service_mask = (uint8_t)(tlv_buf[CFG_CMD3]-0x30)&0xFF;
|
||||
sts_cfg_nvm.sts_service_mask = (uint8_t)sts_service_mask;
|
||||
outbuf[i++] = (uint8_t) 'Y';
|
||||
outbuf[i++] = (uint8_t) 'M';
|
||||
outbuf[i++] = (uint8_t) (sts_service_mask+0x30);
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
APP_LOG(TS_OFF, VLEVEL_L, ">>>>>>>>>>>>>>>>>>>>> Mask = [ %02x ] \r\n", sts_service_mask);
|
||||
OnStoreSTSCFGContextRequest();
|
||||
#ifdef YUNHORN_STS_O6_ENABLED
|
||||
if (sts_service_mask != STS_SERVICE_MASK_L0) STS_Lamp_Bar_Set_Dark();
|
||||
STS_Combined_Status_Processing();
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V': //"YV"
|
||||
if ((char)tlv_buf[CFG_CMD3] == 'H') { // "YVH" REPORT FIRMWARE VERSION "YVH"
|
||||
// FIRMWARE VERSION REPORT
|
||||
i=0;
|
||||
outbuf[i++] = (uint8_t) 'V';
|
||||
outbuf[i++] = (uint8_t) sts_mtmcode1;
|
||||
outbuf[i++] = (uint8_t) sts_mtmcode2;
|
||||
|
@ -647,17 +750,22 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
|
||||
uint8_t cfg_in_nvm[YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0};
|
||||
OnRestoreSTSCFGContextRequest((uint8_t *)cfg_in_nvm);
|
||||
|
||||
i=0;
|
||||
outbuf[i++] = (uint8_t) 'C';
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_MTM1]; //MTM Code
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_MTM2]; //MTM Code
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_VER]; //STS Version
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_PERIODICITY_H]; //Periodicity count high
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_PERIODICITY_L]; //Periodicity count low
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_UNIT]; //Periodicity unit
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_LEN]; //length of following cfg value
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_MTM1]; //MTM Code
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_MTM2]; //MTM Code
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_VER]; //STS Version
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_HWV]; //STS Version
|
||||
outbuf[i++] = (uint8_t) (cfg_in_nvm[NVM_PERIODICITY]); //UPLINK Periodicity
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_UNIT]; //UPLINK Periodicity unit
|
||||
outbuf[i++] = (uint8_t) (cfg_in_nvm[NVM_SAMPLING]); //Heart-beat or SAMPLING Periodicity
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_S_UNIT]; //Heart-beat or SAMPLING Periodicity unit
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_WORK_MODE]; // STS WORK MODE
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_SERVICE_MASK]; //service mask
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_RESERVE01]; //service mask
|
||||
outbuf[i++] = (uint8_t) cfg_in_nvm[NVM_LEN]; //length of following cfg value
|
||||
|
||||
for (uint8_t j=1; j <= cfg_in_nvm[NVM_LEN]; j++) {
|
||||
for (uint8_t j=0; j <= cfg_in_nvm[NVM_LEN]; j++) {
|
||||
outbuf[i++] = (uint8_t) (cfg_in_nvm[NVM_LEN+j]);
|
||||
}
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
|
@ -707,25 +815,21 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
break;
|
||||
|
||||
case 'D':
|
||||
if ((((char)tlv_buf[CFG_CMD3] >= '0') && ((char)tlv_buf[CFG_CMD3] <='9')
|
||||
&& ((char)tlv_buf[CFG_CMD4] >='0') && ((char)tlv_buf[CFG_CMD4] <='9')) &&
|
||||
if ((((char)tlv_buf[CFG_CMD3] >= '0') && ((char)tlv_buf[CFG_CMD3] <='9')
|
||||
&& ((char)tlv_buf[CFG_CMD4] >='0') && ((char)tlv_buf[CFG_CMD4] <='9')) &&
|
||||
(((char)tlv_buf[CFG_CMD5] == 'M' || ((char)tlv_buf[CFG_CMD5] =='H') ||((char)tlv_buf[CFG_CMD5] =='S'))))
|
||||
{
|
||||
periodicity_length = (tlv_buf[CFG_CMD3]-0x30)*10+ (tlv_buf[CFG_CMD4]-0x30);
|
||||
uint8_t periodicity_unit = (char)tlv_buf[CFG_CMD5];
|
||||
|
||||
|
||||
if ((char)tlv_buf[CFG_CMD5] == 'M') {
|
||||
uint32_t periodicity_length = (tlv_buf[CFG_CMD3]-0x30)*10+ (tlv_buf[CFG_CMD4]-0x30);
|
||||
|
||||
if ((char)tlv_buf[CFG_CMD5] == 'M') {
|
||||
periodicity_length *= 60;
|
||||
} else if ((char)tlv_buf[CFG_CMD5] == 'H') {
|
||||
} else if ((char)tlv_buf[CFG_CMD5] == 'H') {
|
||||
periodicity_length *= 3600;
|
||||
} else if ((char)tlv_buf[CFG_CMD5] == 'S') {
|
||||
|
||||
if (periodicity_length < 10) periodicity_length = 10;
|
||||
|
||||
}
|
||||
|
||||
OnTxPeriodicityChanged(periodicity_length*1000); //translate to 1000ms=1s
|
||||
TxPeriodicity = periodicity_length*1000; //translate to 1000ms=1s
|
||||
HeartBeatPeriodicity = TxPeriodicity;
|
||||
|
||||
OnTxPeriodicityChanged(TxPeriodicity);
|
||||
i = 0;
|
||||
outbuf[i++] = (uint8_t) tlv_buf[CFG_CMD1];
|
||||
outbuf[i++] = (uint8_t) tlv_buf[CFG_CMD2];
|
||||
|
@ -735,25 +839,22 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
// Save config to NVM
|
||||
sts_cfg_nvm.mtmcode1 = sts_mtmcode1;
|
||||
sts_cfg_nvm.mtmcode2 = sts_mtmcode2;
|
||||
sts_cfg_nvm.version = sts_version;
|
||||
sts_cfg_nvm.hardware_ver = sts_hardware_ver;
|
||||
sts_cfg_nvm.periodicity_h = (tlv_buf[CFG_CMD3]-0x30);
|
||||
sts_cfg_nvm.periodicity_l = (tlv_buf[CFG_CMD4]-0x30);
|
||||
if (((char)tlv_buf[CFG_CMD5] == 'S') && (periodicity_length == 10))
|
||||
{
|
||||
sts_cfg_nvm.periodicity_h = 0X01;
|
||||
sts_cfg_nvm.periodicity_l = 0X00;
|
||||
}
|
||||
sts_cfg_nvm.unit = periodicity_unit;
|
||||
|
||||
sts_cfg_nvm.mtmcode1 = (uint8_t)sts_mtmcode1;
|
||||
sts_cfg_nvm.mtmcode2 = (uint8_t)sts_mtmcode2;
|
||||
sts_cfg_nvm.version = (uint8_t)sts_version;
|
||||
sts_cfg_nvm.hardware_ver = (uint8_t)sts_hardware_ver;
|
||||
sts_cfg_nvm.periodicity = (uint8_t)((tlv_buf[CFG_CMD3]-0x30)*10+(tlv_buf[CFG_CMD4]-0x30));
|
||||
sts_cfg_nvm.unit = (uint8_t)tlv_buf[CFG_CMD5];
|
||||
sts_cfg_nvm.work_mode = (uint8_t)sts_work_mode;
|
||||
sts_cfg_nvm.sts_service_mask = (uint8_t)sts_service_mask;
|
||||
|
||||
OnStoreSTSCFGContextRequest();
|
||||
APP_LOG(TS_OFF, VLEVEL_L, "###### YUNHORN Periodicity Changed to [ %d ] Seconds\r\n", periodicity_length);
|
||||
|
||||
} else {
|
||||
APP_LOG(TS_OFF, VLEVEL_M, "###### YUNHORN Periodicity Changed to [ %d ] Seconds\r\n", periodicity_length);
|
||||
|
||||
} else {
|
||||
STS_SENSOR_Upload_Config_Invalid_Message();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -761,7 +862,7 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
break;
|
||||
}
|
||||
} // END OF *** BOARD LEVEL CONTROL OR REPORT
|
||||
else if (((char)tlv_buf[CFG_CMD1] == 'P') && (tlv_buf_size >= 4)) // BEGIN OF PARAMETER CONFIG
|
||||
else if (((char)tlv_buf[CFG_CMD1] == 'P') && (tlv_buf_size >= 3)) // BEGIN OF PARAMETER CONFIG
|
||||
{
|
||||
/*
|
||||
* YUNHORN STS PRODUCT SUBMODULE, MEMS OR SENSOR HEAD LEVEL PARAMETER TUNING SECTION
|
||||
|
@ -844,9 +945,43 @@ void USER_APP_AUTO_RESPONDER_Parse(char *tlv_buf, size_t tlv_buf_size)
|
|||
STS_SENSOR_Upload_Config_Invalid_Message();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
STS_SENSOR_Upload_Config_Invalid_Message();
|
||||
}
|
||||
} else if (((char)tlv_buf[CFG_CMD1] == 'A') && ((char)tlv_buf[CFG_CMD2] == 'C') && (tlv_buf_size == (YUNHORN_STS_AC_CODE_SIZE+2))) // BEGIN OF *** BOARD LEVEL AUTHORIZATION CODE
|
||||
{
|
||||
// 'AC'+ AC_CODE(20bytes)
|
||||
|
||||
for (uint8_t j=0; j< YUNHORN_STS_AC_CODE_SIZE; j++)
|
||||
{
|
||||
sts_ac_code[j] = (uint8_t) tlv_buf[2+j];
|
||||
}
|
||||
|
||||
STS_YUNHORN_RFAC_HANDLE_PROCESS();
|
||||
|
||||
if ((hmac_result.ac_pass == 1U))
|
||||
{
|
||||
for (uint8_t j=0; j < YUNHORN_STS_AC_CODE_SIZE; j++)
|
||||
{
|
||||
sts_cfg_nvm.ac[j] = sts_ac_code[j];
|
||||
}
|
||||
|
||||
sts_service_mask = STS_SERVICE_MASK_L0;
|
||||
|
||||
sts_cfg_nvm.sts_service_mask = sts_service_mask;
|
||||
OnStoreSTSCFGContextRequest();
|
||||
|
||||
|
||||
} else {
|
||||
sts_service_mask = STS_SERVICE_MASK_L2;
|
||||
|
||||
}
|
||||
|
||||
i=0;
|
||||
for (uint8_t j=0; j <(tlv_buf_size) ; j++) {
|
||||
outbuf[i++] = (uint8_t) tlv_buf[j];
|
||||
}
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, (char*)outbuf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // END OF USER_APP_AUTO_RESPONDER_Parse
|
||||
|
||||
|
@ -855,6 +990,13 @@ void STS_SENSOR_Upload_Config_Invalid_Message(void)
|
|||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, 5, "PVXXX");
|
||||
}
|
||||
|
||||
void STS_YUNHORN_RFAC_HANDLE_PROCESS(void)
|
||||
{
|
||||
|
||||
STS_YunhornAuthenticationCode_Process();
|
||||
|
||||
}
|
||||
|
||||
void STS_SENSOR_Upload_Message(uint8_t appDataPort, uint8_t appBufferSize, char *appDataBuffer)
|
||||
{
|
||||
LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR;
|
||||
|
@ -1369,43 +1511,48 @@ static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size)
|
|||
void OnStoreSTSCFGContextRequest(void)
|
||||
{
|
||||
/* USER CODE BEGIN OnStoreContextRequest_1 */
|
||||
uint8_t i=0, nvm_store_value[YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0};
|
||||
|
||||
#ifdef YUNHORN_STS_M7_ENABLED
|
||||
sts_cfg_nvm.length = (uint8_t) NVM_CFG_PARAMETER_SIZE;
|
||||
nvm_store_value[i++] = (uint8_t) sts_mtmcode1;
|
||||
nvm_store_value[i++] = (uint8_t) sts_mtmcode2;
|
||||
nvm_store_value[i++] = (uint8_t) sts_cfg_nvm.version;
|
||||
nvm_store_value[i++] = (uint8_t) sts_hardware_ver;
|
||||
nvm_store_value[i++] = (uint8_t) sts_cfg_nvm.periodicity_h;
|
||||
nvm_store_value[i++] = (uint8_t) sts_cfg_nvm.periodicity_l;
|
||||
nvm_store_value[i++] = (uint8_t) sts_cfg_nvm.unit;
|
||||
nvm_store_value[i++] = (uint8_t) sts_cfg_nvm.length;
|
||||
for (uint8_t j=0;j< NVM_CFG_PARAMETER_SIZE; j++) {
|
||||
nvm_store_value[i+j] = (uint8_t) (sts_cfg_nvm.p[j]);
|
||||
uint8_t i=0, j=0, nvm_store_value[YUNHORN_STS_MAX_NVM_CFG_SIZE]="";
|
||||
|
||||
#if (defined(YUNHORN_STS_O6_ENABLED) || defined(YUNHORN_STS_R0_ENABLED))
|
||||
sts_cfg_nvm.length = STS_NVM_CFG_SIZE;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.mtmcode1;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.mtmcode2;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.version;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.hardware_ver;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.periodicity;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.unit;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.sampling;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.s_unit;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.work_mode;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.sts_service_mask;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.reseve01;
|
||||
nvm_store_value[i++] = (uint8_t) STS_NVM_CFG_SIZE; //sts_cfg_nvm.length;
|
||||
|
||||
for (j = 0; j < STS_CFG_PCFG_SIZE; j++) {
|
||||
nvm_store_value[i++] = (sts_cfg_nvm.p[j]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef YUNHORN_STS_O0_ENABLED
|
||||
nvm_store_value[i++] = sts_cfg_nvm.fall_detection_acc_threshold;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.fall_detection_depth_threshold;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.fall_detection_reserve;
|
||||
nvm_store_value[i++] = sts_cfg_nvm.occupancy_overtime_threshold;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef YUNHORN_STS_R0_ENABLED
|
||||
|
||||
#endif
|
||||
for (j = 0; j < YUNHORN_STS_AC_CODE_SIZE; j++) {
|
||||
nvm_store_value[i++] = (sts_cfg_nvm.ac[j]);
|
||||
}
|
||||
#endif
|
||||
/* USER CODE END OnStoreContextRequest_1 */
|
||||
/* store nvm in flash */
|
||||
if (FLASH_IF_Erase(STS_CONFIG_NVM_BASE_ADDRESS, FLASH_PAGE_SIZE) == FLASH_IF_OK)
|
||||
|
||||
if (FLASH_IF_Erase(STS_CONFIG_NVM_BASE_ADDRESS, FLASH_PAGE_SIZE) == FLASH_IF_OK)
|
||||
{
|
||||
FLASH_IF_Write(STS_CONFIG_NVM_BASE_ADDRESS, (const void *)nvm_store_value, YUNHORN_STS_MAX_NVM_CFG_SIZE);
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE BEGIN OnStoreContextRequest_Last */
|
||||
|
||||
#ifdef YUNHORN_STS_M7_ENABLED
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* USER CODE END OnStoreContextRequest_Last */
|
||||
}
|
||||
|
||||
|
@ -1430,42 +1577,50 @@ void OnRestoreSTSCFGContextRequest(uint8_t *cfg_in_nvm)
|
|||
|
||||
void STS_REBOOT_CONFIG_Init(void)
|
||||
{
|
||||
/* USER CODE BEGIN OnRestoreContextRequest_1 */
|
||||
uint8_t i=0, nvm_stored_value[YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0}, nvm_store_size=YUNHORN_STS_MAX_NVM_CFG_SIZE;
|
||||
/* USER CODE BEGIN OnRestoreContextRequest_1 */
|
||||
uint8_t nvm_stored_value[YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0};
|
||||
|
||||
/* USER CODE END OnRestoreContextRequest_1 */
|
||||
UTIL_MEM_cpy_8(nvm_stored_value, (void *)STS_CONFIG_NVM_BASE_ADDRESS, nvm_store_size);
|
||||
UTIL_MEM_cpy_8(nvm_stored_value, (void *)STS_CONFIG_NVM_BASE_ADDRESS, YUNHORN_STS_MAX_NVM_CFG_SIZE);
|
||||
/* USER CODE BEGIN OnRestoreContextRequest_Last */
|
||||
#ifdef YUNHORN_STS_M7_ENABLED
|
||||
|
||||
if ((nvm_stored_value[0] == 0xFF) || (nvm_stored_value[1] == 0xFF) ||(nvm_stored_value[2] == 0xFF))
|
||||
|
||||
#if (defined(YUNHORN_STS_O6_ENABLED) || defined(YUNHORN_STS_R0_ENABLED) || defined(YUNHORN_STS_M7_ENABLED))
|
||||
if ((nvm_stored_value[NVM_MTM1] != sts_mtmcode1) || (nvm_stored_value[NVM_MTM2] != sts_mtmcode2) || (nvm_stored_value[NVM_VER] != sts_version))
|
||||
{
|
||||
APP_LOG(TS_OFF, VLEVEL_L, "Initial Boot with Empty Config, Flash with default config....\r\n");
|
||||
OnStoreSTSCFGContextRequest();
|
||||
} else
|
||||
APP_LOG(TS_OFF, VLEVEL_L, "\r\nInitial Boot with Empty Config, Flash with default config....\r\n");
|
||||
OnStoreSTSCFGContextRequest();
|
||||
UTIL_MEM_set_8((void *)sts_ac_code, 0x00, YUNHORN_STS_AC_CODE_SIZE);
|
||||
HAL_Delay(1000);
|
||||
} else
|
||||
{
|
||||
sts_cfg_nvm.mtmcode1 = (uint8_t)nvm_stored_value[NVM_MTM1];
|
||||
sts_cfg_nvm.mtmcode2 = (uint8_t)nvm_stored_value[NVM_MTM2];
|
||||
sts_cfg_nvm.version = (uint8_t)nvm_stored_value[NVM_VER];
|
||||
sts_cfg_nvm.hardware_ver = (uint8_t)nvm_stored_value[NVM_HWV];
|
||||
sts_cfg_nvm.periodicity_h = (uint8_t)(nvm_stored_value[NVM_PERIODICITY_H]);
|
||||
sts_cfg_nvm.periodicity_l = (uint8_t)(nvm_stored_value[NVM_PERIODICITY_L]);
|
||||
sts_cfg_nvm.unit = (uint8_t)(nvm_stored_value[NVM_UNIT]);
|
||||
sts_cfg_nvm.length = (uint8_t)(nvm_stored_value[NVM_LEN]&0x1F); //MAX 32 bytes
|
||||
for (uint8_t j=0; j< sts_cfg_nvm.length; j++) {
|
||||
sts_cfg_nvm.p[j] = (uint8_t)nvm_stored_value[NVM_LEN+1+j];
|
||||
}
|
||||
sts_cfg_nvm.mtmcode1 = (uint8_t)nvm_stored_value[NVM_MTM1];
|
||||
sts_cfg_nvm.mtmcode2 = (uint8_t)nvm_stored_value[NVM_MTM2];
|
||||
sts_cfg_nvm.version = (uint8_t)nvm_stored_value[NVM_VER];
|
||||
sts_cfg_nvm.hardware_ver = (uint8_t)nvm_stored_value[NVM_HWV];
|
||||
sts_cfg_nvm.periodicity = (uint8_t)(nvm_stored_value[NVM_PERIODICITY]); //TxPeriodicity interval
|
||||
sts_cfg_nvm.unit = (uint8_t)(nvm_stored_value[NVM_UNIT]);
|
||||
sts_cfg_nvm.sampling = (uint8_t)(nvm_stored_value[NVM_SAMPLING]); //Heart-beat or sampling interval
|
||||
sts_cfg_nvm.s_unit = (uint8_t)(nvm_stored_value[NVM_S_UNIT]);
|
||||
sts_cfg_nvm.work_mode = (uint8_t)(nvm_stored_value[NVM_WORK_MODE]);
|
||||
sts_cfg_nvm.sts_service_mask = (uint8_t)(nvm_stored_value[NVM_SERVICE_MASK]);
|
||||
sts_cfg_nvm.reseve01 = (uint8_t)(nvm_stored_value[NVM_RESERVE01]);
|
||||
sts_cfg_nvm.length = (uint8_t)(nvm_stored_value[NVM_LEN]&0x3F); //MAX 32 bytes
|
||||
|
||||
for (uint8_t j=0; j< sts_cfg_nvm.length; j++) {
|
||||
sts_cfg_nvm.p[j] = (uint8_t)nvm_stored_value[NVM_CFG_START+j];
|
||||
}
|
||||
|
||||
sts_cfg_nvm.fall_detection_acc_threshold = (uint8_t)nvm_stored_value[NVM_FALL_DETECTION_ACC_THRESHOLD];
|
||||
sts_cfg_nvm.fall_detection_depth_threshold = (uint8_t)nvm_stored_value[NVM_FALL_DETECTION_DEPTH_THRESHOLD];
|
||||
sts_cfg_nvm.fall_detection_reserve = (uint8_t)nvm_stored_value[NVM_FALL_DETECTION_RESERVE];
|
||||
sts_cfg_nvm.occupancy_overtime_threshold = (uint8_t)nvm_stored_value[NVM_OCCUPANCY_OVERTIME_THRESHOLD];
|
||||
|
||||
for (uint8_t j=0; j< YUNHORN_STS_AC_CODE_SIZE; j++) {
|
||||
sts_cfg_nvm.ac[j] = (uint8_t)nvm_stored_value[NVM_AC_CODE_START +j];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef YUNHORN_STS_O0_ENABLED
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef YUNHORN_STS_R0_ENABLED
|
||||
|
||||
#endif
|
||||
|
||||
OnRestoreSTSCFGContextProcess();
|
||||
|
||||
/* USER CODE END OnRestoreContextRequest_Last */
|
||||
|
@ -1473,24 +1628,62 @@ void STS_REBOOT_CONFIG_Init(void)
|
|||
|
||||
void OnRestoreSTSCFGContextProcess(void)
|
||||
{
|
||||
periodicity_length = (sts_cfg_nvm.periodicity_h)*10+(sts_cfg_nvm.periodicity_l);
|
||||
uint32_t periodicity = (sts_cfg_nvm.periodicity); //TxPeriodicty interval
|
||||
if ((char)sts_cfg_nvm.unit =='M') {
|
||||
periodicity_length *= 60;
|
||||
periodicity *= 60;
|
||||
} else if ((char) sts_cfg_nvm.unit =='H') {
|
||||
periodicity_length *= 3600;
|
||||
periodicity *= 3600;
|
||||
} else if ((char) sts_cfg_nvm.unit =='S') {
|
||||
periodicity_length *= 1;
|
||||
periodicity *= 1;
|
||||
}
|
||||
|
||||
periodicity_length = (periodicity_length>10)? periodicity_length : 10;
|
||||
if (sts_lorawan_joined)
|
||||
{
|
||||
OnTxPeriodicityChanged(periodicity_length*1000);
|
||||
} else
|
||||
{
|
||||
OnTxPeriodicityChanged(TxPeriodicity);
|
||||
periodicity = (periodicity > 10)? periodicity : 10; // in seconds unit
|
||||
TxPeriodicity= periodicity*1000; // to ms
|
||||
OnTxPeriodicityChanged(TxPeriodicity); // in msec unit
|
||||
|
||||
uint32_t samplingperiodicity = (sts_cfg_nvm.sampling); //Heart-beat or Sampling interval
|
||||
if ((char)sts_cfg_nvm.s_unit =='M') {
|
||||
samplingperiodicity *= 60;
|
||||
} else if ((char) sts_cfg_nvm.s_unit =='H') {
|
||||
samplingperiodicity *= 3600;
|
||||
} else if ((char) sts_cfg_nvm.s_unit =='S') {
|
||||
samplingperiodicity *= 1;
|
||||
}
|
||||
|
||||
|
||||
//Heart-beat or Sampling interval
|
||||
samplingperiodicity = (samplingperiodicity > 0)? samplingperiodicity : 1; // in seconds unit
|
||||
#ifdef YUNHORN_STS_O6_ENABLED
|
||||
OnYunhornSTSSamplingPeriodicityChanged(samplingperiodicity*1000); // in m-sec unit
|
||||
#endif
|
||||
|
||||
#ifdef YUNHORN_STS_R0_ENABLED
|
||||
OnYunhornSTSHeartBeatPeriodicityChanged(samplingperiodicity*1000);
|
||||
#endif
|
||||
|
||||
sts_work_mode = sts_cfg_nvm.work_mode;
|
||||
sts_service_mask = sts_cfg_nvm.sts_service_mask;
|
||||
|
||||
#ifdef YUNHORN_STS_O6_ENABLED
|
||||
sts_lamp_bar_color = STS_GREEN;
|
||||
sts_fall_detection_acc_threshold = (uint8_t)sts_cfg_nvm.fall_detection_acc_threshold*10;
|
||||
sts_fall_detection_depth_threshold = (uint8_t)sts_cfg_nvm.fall_detection_depth_threshold*10; //in cm
|
||||
// **** = sts_cfg_nvm.fall_detection_reserve;
|
||||
sts_occupancy_overtime_threshold = (uint8_t)sts_cfg_nvm.occupancy_overtime_threshold*10; // minutes
|
||||
#endif
|
||||
|
||||
|
||||
for (uint8_t j=0; j< YUNHORN_STS_AC_CODE_SIZE; j++)
|
||||
{
|
||||
sts_ac_code[j] = sts_cfg_nvm.ac[j];
|
||||
}
|
||||
|
||||
#ifdef YUNHORN_STS_O6_ENABLED
|
||||
if ((sts_version == sts_cfg_nvm.version)&& (NVM_CFG_PARAMETER_SIZE == sts_cfg_nvm.length))
|
||||
{
|
||||
STS_PRESENCE_SENSOR_Init();
|
||||
STS_PRESENCE_SENSOR_RSS_Init();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef YUNHORN_STS_M7_ENABLED
|
||||
if ((sts_version == sts_cfg_nvm.version)&& (NVM_CFG_PARAMETER_SIZE == sts_cfg_nvm.length)) {
|
||||
|
@ -1565,3 +1758,38 @@ void STS_SENSOR_Function_Test_Process(void)
|
|||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, i, outbuf);
|
||||
|
||||
}
|
||||
|
||||
void STS_YunhornAuthenticationCode_Process(void)
|
||||
{
|
||||
if (sts_ac_code[0] == 0x00) {
|
||||
APP_LOG(TS_OFF,VLEVEL_M, "Initial AC CODE blank... \r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
|
||||
if (sts_service_mask == STS_SERVICE_MASK_L2) {
|
||||
sts_ac_code[0] = 0x0;
|
||||
}
|
||||
APP_LOG(TS_OFF, VLEVEL_H, "STS_SERVICE_MASK:%d \r\n",sts_service_mask);
|
||||
}
|
||||
|
||||
void STS_YunhornSTSEventRFAC_Process(void)
|
||||
{
|
||||
if (sts_ac_code[0] ==0x0)
|
||||
{
|
||||
if ((rfac_timer >= STS_BURN_IN_RFAC) && (rfac_timer < (STS_BURN_IN_RFAC +3)))
|
||||
{
|
||||
APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------RFAC Process\r\n");
|
||||
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, 4, "RFAC");
|
||||
}
|
||||
if ((rfac_timer > (STS_BURN_IN_RFAC + 2)))
|
||||
{
|
||||
APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------Verify RFAC Success or Not\r\n");
|
||||
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
|
||||
if (sts_service_mask == STS_SERVICE_MASK_L2) {
|
||||
sts_ac_code[0] = 0x0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue