diff --git a/Core/Inc/utilities_def.h b/Core/Inc/utilities_def.h index 6c1679c..4b9c8ba 100644 --- a/Core/Inc/utilities_def.h +++ b/Core/Inc/utilities_def.h @@ -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 */ diff --git a/Core/Inc/yunhorn_sts_prd_conf.h b/Core/Inc/yunhorn_sts_prd_conf.h index 853aad9..2d1f378 100644 --- a/Core/Inc/yunhorn_sts_prd_conf.h +++ b/Core/Inc/yunhorn_sts_prd_conf.h @@ -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) diff --git a/Core/Inc/yunhorn_sts_sensors.h b/Core/Inc/yunhorn_sts_sensors.h index 7bf7afe..3f0e9b1 100644 --- a/Core/Inc/yunhorn_sts_sensors.h +++ b/Core/Inc/yunhorn_sts_sensors.h @@ -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 */ /* diff --git a/LoRaWAN/App/lora_app.c b/LoRaWAN/App/lora_app.c index f14394f..641eab5 100644 --- a/LoRaWAN/App/lora_app.c +++ b/LoRaWAN/App/lora_app.c @@ -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; + } + } + } + +}