/********************************* (C) ROTEK *********************************** * @module settings_api * @file settings_api.c * @version 1.0.0 * @date XX.XX.XXXX * $brief Settings ******************************************************************************* * @history Version Author Comment * XX.XX.XXXX 1.0.0 Telenkov D.A. First release. ******************************************************************************* */ #include "stm32f4xx.h" #include "settings_api.h" #include "common_config.h" #ifndef BT6702_SERVICE #include "snmp_api.h" #include "trap_api.h" #include "log.h" #endif #include "sys_api.h" #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "main.h" #include "parameters.h" #include "mbedtls/certs.h" #include #include #ifdef PRINTF_STDLIB #include #endif #ifdef PRINTF_CUSTOM #include "tinystdio.h" #endif //#define DBG if(0) #if defined ( __ICCARM__ ) #define DEVICE_MAC "00-00-00-00-00-03" #endif SemaphoreHandle_t flash_mutex; /** * @brief Флаг подтверждения новых сетевых параметров пользователем */ bool fConfirmWebParams = false; /** * @brief Общая структура настроек */ SETTINGS_t sSettings; /** * @brief Установить параметры обновления ПО по умолчанию */ void SETTINGS_SetBootParamsDef(void) { sSettings.bootParams.loadMode = 0; sSettings.bootParams.bootTry = 0; } /** * @brief Установить параметры сетевого подключения по умолчанию */ void SETTINGS_SetWebParamsDef(void) { strcpy(sSettings.sWebParams.ip, "192.168.0.254"); strcpy(sSettings.sWebParams.gate, "192.168.0.1"); strcpy(sSettings.sWebParams.mask, "255.255.255.0"); sSettings.sWebParams.dhcpEnable = 0; } /** * @brief Установить временные параметры сетевого подключения по умолчанию */ void SETTINGS_SetTempWebParamsDef(void) { strcpy(sSettings.sWebTempParams.ip, "192.168.0.254"); strcpy(sSettings.sWebTempParams.gate, "192.168.0.1"); strcpy(sSettings.sWebTempParams.mask, "255.255.255.0"); sSettings.sWebTempParams.dhcpEnable = 0; } /** * @brief Установить параметры SNMP по умолчанию */ void SETTINGS_SetSnmpDef(void) { strcpy(sSettings.sSnmp.sysDesc.description, ""); sSettings.sSnmp.sysDesc.len = 0; strcpy(sSettings.sSnmp.readCommunity, "public"); strcpy(sSettings.sSnmp.writeCommunity, "public"); strcpy(sSettings.sSnmp.sysContact.contact, ""); sSettings.sSnmp.sysContact.len = 0; strcpy(sSettings.sSnmp.sysName.name, ""); sSettings.sSnmp.sysName.len = 0; strcpy(sSettings.sSnmp.sysLocation.location, ""); sSettings.sSnmp.sysLocation.len = 0; strcpy(sSettings.sSnmp.managerIP, "0.0.0.0"); strcpy(sSettings.sSnmp.managerIP2, "0.0.0.0"); strcpy(sSettings.sSnmp.managerIP3, "0.0.0.0"); strcpy(sSettings.sSnmp.managerIP4, "0.0.0.0"); strcpy(sSettings.sSnmp.managerIP5, "0.0.0.0"); } /** * @brief Установить Информацию об устройстве по умолчанию */ void SETTINGS_SetInfoDef(void) { SYS_t *sSys = NULL; sSys = pvPortMalloc(sizeof(*sSys)); if (sSys) { SYS_Load(sSys); strcpy(sSettings.sInfo.mac, sSys->mac); strcpy(sSettings.sInfo.serialNumber, sSys->serial); strcpy(sSettings.sInfo.productionData, sSys->proddate); strcpy(sSettings.sFlags.testState, sSys->testState); vPortFree(sSys); } else { strcpy(sSettings.sInfo.productionData, "09.07.2017"); strcpy(sSettings.sInfo.mac, DEVICE_MAC); strcpy(sSettings.sInfo.serialNumber, DEVICE_SERIAL); strcpy(sSettings.sFlags.testState, "T2OK"); } strcpy(sSettings.sInfo.comments, ""); } /** * @brief Настройки ИБП по умолчанию */ void SETTINGS_SetUPSSettingsDef(void) { sSettings.UPS_Setting.Ucellmin = 1.67; sSettings.UPS_Setting.Ucellmax = 2.27; #ifdef HARDWARE_BT6709 sSettings.UPS_Setting.Uakb = 24; sSettings.UPS_Setting.ups_power = 1000; sSettings.UPS_Setting.set_data = 0; sSettings.UPS_Setting.life_time = 5; sSettings.UPS_Setting.common_capacity = 9; #endif sSettings.UPS_Setting.type_ups = ups_kestar; } /** * @brief Установить наcтройки менеджера Аварий по умолчанию */ void SETTINGS_SetAlarmManagerDef(void) { sSettings.sAlarmManager.load_range.high = 70.0; sSettings.sAlarmManager.load_range.low = 0; sSettings.sAlarmManager.load_range.hyst = 1; sSettings.sAlarmManager.ac_output_range.high = 250.0; sSettings.sAlarmManager.ac_output_range.low = 150.0; sSettings.sAlarmManager.ac_output_range.hyst = 20.0; sSettings.sAlarmManager.Temprature_range.high = 70.0; sSettings.sAlarmManager.Temprature_range.low = -40.0; sSettings.sAlarmManager.Temprature_range.hyst = 1; } /** * @brief Установить флаги по умолчанию */ void SETTINGS_SetFlagsDef(void) { sSettings.sFlags.netsettingsChanged = false; } /** * @brief Установить значение сервисных настроек по умолчанию */ void SETTINGS_SetServiceDef(void) { uint8_t user_id; for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) { switch (user_id) { /* First users in the system is always ADMIN. * Others are USER */ case 0: sSettings.sAuth[user_id].level = ADMIN; strcpy(sSettings.sAuth[user_id].login, "admin"); #if defined HARDWARE_BT6707 || HARDWARE_BT6709 strcpy(sSettings.sAuth[user_id].password, "12345"); #elif HARDWARE_BT6703 strcpy(sSettings.sAuth[user_id].password, "R04ekR4MP2"); #endif break; case 1: default: sSettings.sAuth[user_id].level = USER; strcpy(sSettings.sAuth[user_id].login, "user"); #if defined HARDWARE_BT6707 || HARDWARE_BT6709 strcpy(sSettings.sAuth[user_id].password, "1234"); #elif HARDWARE_BT6703 strcpy(sSettings.sAuth[user_id].password, "R03ekR4MP2"); #endif break; } } } /** * @brief Установить параметры SNTP по умолчанию */ void SETTINGS_SetSntpDef(void) { sSettings.sSNTP.sntpEnable = true; strcpy(sSettings.sSNTP.ip, "88.147.254.235"); sSettings.sSNTP.timeZone = 3.0; strcpy(sSettings.sSNTP.data, "none"); } #ifndef HARDWARE_BT6709 /** * @brief Установить параметры настроек сухих контактов / реле по умолчанию */ void SETTINGS_SetINOUTSDef(void) { #if defined HARDWARE_BT6707 sSettings.sInOuts.ro_type_source[0] = AC_PRESENT; sSettings.sInOuts.ro_type_source[1] = DC_PRESENT; sSettings.sInOuts.ro_type_source[2] = CHARGE_AKB; #elif HARDWARE_BT6703 sSettings.sInOuts.ro_type_source[0] = CRITICAL; sSettings.sInOuts.ro_type_source[1] = SNMP_SET; #endif sSettings.sInOuts.din_type_act[0] = DI_CONN; } #endif #ifdef HARDWARE_BT6703 /** * @brief Установить параметры RADIUS по умолчанию */ void SETTINGS_SetRADIUSDef(void) { sSettings.sRADIUS.Auth_enable = true; //sSettings.sRADIUS.RDSEnable = false; // todo вернуть на значение false sSettings.sRADIUS.RDSEnable = false; strcpy(sSettings.sRADIUS.ServerIP, "0.0.0.0"); //strcpy(sSettings.sRADIUS.ServerIP, "192.168.14.234"); sSettings.sRADIUS.port = 1812; sSettings.sRADIUS.key_access = 123; strcpy(sSettings.sRADIUS.rds_password, "R02ekR4MP2"); } /** * @brief Установить параметры сертификата сервера по умолчанию */ void SETTINGS_SetSSLcrtDef(void){ memset(sSettings.our_srv_crt, 0, sizeof(sSettings.our_srv_crt)); memcpy(sSettings.our_srv_crt, (unsigned char *) mbedtls_test_srv_crt, mbedtls_test_srv_crt_len); //memcpy(sSettings.our_srv_key, (unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len); } #endif #if defined HARDWARE_BT6707 || HARDWARE_BT6709 /** * @brief Установить параметры Telnet */ void SETTINGS_SetTelnetDef(void){ sSettings.sTelnet.TelnetEnable = true; sSettings.sTelnet.port = 23; } #endif #if defined HARDWARE_BT6709 /** * @brief Установить параметры SSH */ void SETTINGS_SetSSHDef(void){ sSettings.sSSH.SSHEnable = true; sSettings.sSSH.port = 22; } /** * @brief Установить параметры списка доверительных хостов */ void SETTINGS_SetWhiteListDef(void){ for(uint8_t i = 0; i < MAX_WHITE_LIST; i++){ strcpy(sSettings.sWhiteListTemp[i].ip_range, ""); SetWhiteListSTR(sSettings.sWhiteListTemp[i].ip_range, i); strcpy(sSettings.sWhiteList[i].ip_range, sSettings.sWhiteListTemp[i].ip_range); sSettings.sWhiteList[i].ip = sSettings.sWhiteListTemp[i].ip; sSettings.sWhiteList[i].mask = sSettings.sWhiteListTemp[i].mask; } } /** * @brief Установить параметры разрешения уведомлений по умолчанию */ void SETTINGS_SetFlagNotificationDef(void) { uint8_t i; for(i = 0; i < ALL_TRAPS; i++ ) { sSettings.sFlagNotification[i] = 1; } } #endif /** * @brief Сброс настроек в значения по умолчанию */ void SETTINGS_SetDefault(void) { SETTINGS_SetWebParamsDef(); SETTINGS_SetTempWebParamsDef(); SETTINGS_SetSnmpDef(); SETTINGS_SetServiceDef(); SETTINGS_SetSntpDef(); #ifndef HARDWARE_BT6709 SETTINGS_SetINOUTSDef(); #endif SETTINGS_SetUPSSettingsDef(); #ifdef HARDWARE_BT6703 SETTINGS_SetRADIUSDef(); SETTINGS_SetSSLcrtDef(); #endif #if defined HARDWARE_BT6707 || HARDWARE_BT6709 SETTINGS_SetTelnetDef(); #endif #if defined HARDWARE_BT6709 SETTINGS_SetSSHDef(); SETTINGS_SetWhiteListDef(); SETTINGS_SetFlagNotificationDef(); #endif sSettings.CritSecCRC = SETTINGS_GetCritSecCRC(); } /** * @brief Сброс всех настроек в значения по умолчанию кроме сетевых настроек */ void SETTINGS_SetPartDefault(void) { SETTINGS_SetBootParamsDef(); SETTINGS_SetSnmpDef(); SETTINGS_SetFlagsDef(); SETTINGS_SetAlarmManagerDef(); SETTINGS_SetUPSSettingsDef(); // SETTINGS_SetServiceDef(); SETTINGS_SetSntpDef(); #ifndef HARDWARE_BT6709 SETTINGS_SetINOUTSDef(); #endif // SETTINGS_SetRADIUSDef(); #if defined HARDWARE_BT6709 SETTINGS_SetWhiteListDef(); SETTINGS_SetFlagNotificationDef(); #endif sSettings.CritSecCRC = SETTINGS_GetCritSecCRC(); sSettings.controlWorld = SETTINGS_CONTROL_WORD; } /** * @brief Сброс всех настроек в значения по умолчанию */ void SETTINGS_SetAllDefault(void) { SETTINGS_SetBootParamsDef(); SETTINGS_SetWebParamsDef(); SETTINGS_SetTempWebParamsDef(); SETTINGS_SetSnmpDef(); SETTINGS_SetInfoDef(); SETTINGS_SetFlagsDef(); SETTINGS_SetServiceDef(); SETTINGS_SetSntpDef(); SETTINGS_SetAlarmManagerDef(); SETTINGS_SetUPSSettingsDef(); #ifndef HARDWARE_BT6709 SETTINGS_SetINOUTSDef(); #endif #ifdef HARDWARE_BT6703 SETTINGS_SetRADIUSDef(); SETTINGS_SetSSLcrtDef(); #endif #if defined HARDWARE_BT6707 || HARDWARE_BT6709 SETTINGS_SetTelnetDef(); #endif #ifdef HARDWARE_BT6709 SETTINGS_SetSSHDef(); SETTINGS_SetWhiteListDef(); SETTINGS_SetFlagNotificationDef(); #endif sSettings.CritSecCRC = SETTINGS_GetCritSecCRC(); sSettings.controlWorld = SETTINGS_CONTROL_WORD; } /** * @brief Установка настроек для отладки */ void SETTINGS_SetDefaultDebug(void) { SETTINGS_SetWebParamsDef(); SETTINGS_SetTempWebParamsDef(); SETTINGS_SetSnmpDef(); SETTINGS_SetBootParamsDef(); SETTINGS_SetFlagsDef(); //SETTINGS_SetServiceDef(); SETTINGS_SetSntpDef(); #ifndef HARDWARE_BT6709 SETTINGS_SetINOUTSDef(); #endif SETTINGS_SetUPSSettingsDef(); SETTINGS_SetAlarmManagerDef(); //SETTINGS_SetInfoDef(); #ifdef HARDWARE_BT6703 SETTINGS_SetRADIUSDef(); SETTINGS_SetSSLcrtDef(); #endif #if defined HARDWARE_BT6707 || HARDWARE_BT6709 SETTINGS_SetTelnetDef(); #endif #if defined HARDWARE_BT6709 SETTINGS_SetSSHDef(); SETTINGS_SetWhiteListDef(); SETTINGS_SetFlagNotificationDef(); #endif sSettings.CritSecCRC = SETTINGS_GetCritSecCRC(); sSettings.controlWorld = SETTINGS_CONTROL_WORD; } /** * @brief Запись структуры настроек во flesh */ void SETTINGS_Save(void) { xSemaphoreTake(flash_mutex, portMAX_DELAY); /* Calc critical section CRC and store to the settings structure */ sSettings.CritSecCRC = SETTINGS_GetCritSecCRC(); SETTINGS_WriteToFlash((uint8_t*)&sSettings, sizeof(sSettings)); xSemaphoreGive(flash_mutex); } /** * @brief Загрузка структуры настроек из flesh */ void SETTINGS_Load(void) { uint32_t loadCRC; // CRC из flash uint32_t newCRC; // CRC загруженной структуры настроек bool need_default = false; WEB_PARAMS_t sWebParamsBackup; BOOT_PARAMS_t bootParamsBackup; SETTINGS_ReadFromFlash((uint8_t*)&sSettings, sizeof(sSettings)); /* Считываем CRC из флеш памяти */ loadCRC = (*(uint32_t*)CRC_ADDRESS); /* Рассчитываем CRC для структуры настроек */ newCRC = SETTINGS_GetCRC(); if (loadCRC != newCRC) { /* SETTINGS_SetAllDefault(); SETTINGS_Save();*/ need_default = true; } /* CRC совпала, проверяем контрольное слово если слово не совпадает то это значит, что поплыла структура нстроек, прошиваем дефолт */ else if (sSettings.controlWorld != SETTINGS_CONTROL_WORD) { need_default = true; } /* Прошиваем дефолтные настройки если нужно */ if (need_default) { /* Бэкапим сетевые параметры загрузчика */ memcpy(&sWebParamsBackup, &sSettings.sWebParams, sizeof(sWebParamsBackup)); /* Бэкапим флаги загрузчика */ memcpy(&bootParamsBackup, &sSettings.bootParams, sizeof(bootParamsBackup)); loadCRC = sSettings.CritSecCRC; newCRC = SETTINGS_GetCritSecCRC(); SETTINGS_SetAllDefault(); if (loadCRC == newCRC) { /* Применяем флаги загрузчика */ memcpy(&sSettings.bootParams, &bootParamsBackup, sizeof(sSettings.bootParams)); /* Применяем сетевые параметры загрузчика */ memcpy(&sSettings.sWebParams, &sWebParamsBackup, sizeof(sSettings.sWebParams)); } SETTINGS_Save(); } } /** * @brief */ void SETTINGS_WriteToFlash(uint8_t *data, uint32_t size) { uint32_t baseAddress = SETTINGS_SECTOR; uint32_t checkCrc = 0; uint32_t crc = SETTINGS_GetCRC(); bool fAlarm = 0; FLASH_Status status; for (uint8_t i = 0; i < 3; i++) { fAlarm = 0; FLASH_Unlock(); SETTINGS_EraseFlashSector(); for (uint32_t i = 0; i < size; i++) if ((status = FLASH_ProgramByte(baseAddress++, *data++)) != FLASH_COMPLETE) { DBG printf("FLASH_ProgramByte error: status = %d\r\n", status); break; } if ((status = FLASH_ProgramWord((uint32_t)CRC_ADDRESS, crc)) != FLASH_COMPLETE) { DBG printf("FLASH_ProgramWord error: status = %d\r\n", status); } FLASH_Lock(); /* Считываем что записали */ SETTINGS_ReadFromFlash((uint8_t*)&sSettings, sizeof(sSettings)); checkCrc = SETTINGS_GetCRC(); /* Проверяем CRC того что было записано */ if (checkCrc == crc) break; else fAlarm = 1; // Авария } /* Произошел сбой при записи - висим */ if (fAlarm) while (1) {}; } /** * @brief */ void SETTINGS_ReadFromFlash(uint8_t *data, uint32_t size) { uint32_t baseAddress = SETTINGS_SECTOR; for (uint32_t i = 0; i < size; i++) *data++ = (*(uint32_t*)baseAddress++);; } /** * @brief Очистка сектора настроек * @retval */ void SETTINGS_EraseFlashSector(void) { FLASH_Status status; if ((status = FLASH_EraseSector(FLASH_Sector_1, VoltageRange_3)) != FLASH_COMPLETE) { DBG printf("SETTINGS_EraseFlashSector error: status = %d/r/n", status); } } /** * @brief * @retval */ uint32_t SETTINGS_GetCRC(void) { CRC_ResetDR(); return CRC_CalcBlockCRC((uint32_t*)&sSettings, sizeof(sSettings)/4 - 1); } /** * @brief * @retval */ uint32_t SETTINGS_GetCritSecCRC(void) { CRC_ResetDR(); uint32_t critsec_len = (uint32_t)((uint8_t *)(&sSettings.CritSecCRC) - (uint8_t *)&sSettings) / 4; return CRC_CalcBlockCRC((uint32_t *)&sSettings, critsec_len); } /** * @brief Сброс флага boottry в регистре RTC */ void SETTINGS_ResetBootTry(void) { uint8_t bootTry = RTC_ReadBackupRegister(RTC_BKP_DR2); if (bootTry > 0 ) { bootTry = 0; RTC_WriteBackupRegister(RTC_BKP_DR2, 0); /* Check FW update flag */ if (RTC_ReadBackupRegister(RTC_BKP_DR3)) { /* Отправка трапа об успешном обновлении ПО */ #ifndef BT6702_SERVICE SNMP_SendUserTrap(FW_VERSION_UPDATED); log_event_data(LOG_UPDATE_SOFT, "Успешно"); #endif /* Clear FW update flag */ RTC_WriteBackupRegister(RTC_BKP_DR3, 0); } } /* if (sSettings.bootParams.bootTry != 0) { sSettings.bootParams.bootTry = 0; // Отправка трапа об успешном обновлении ПО SNMP_SendUserTrap(FW_VERSION_UPDATED); //taskENTER_CRITICAL(); SETTINGS_Save(); //taskEXIT_CRITICAL(); } */ } /** * @brief Преобразует mac адрес строкового формата в массив uint8_t * @param mac - буфер для вывода mac адреса */ void SETTINGS_GetMac(uint8_t *mac) { char dummy[2]; char *macPtr = sSettings.sInfo.mac; #if defined ( __ICCARM__ ) macPtr = DEVICE_MAC; #endif for (uint8_t i = 0; i < 6; i++) { strncpy(dummy, macPtr+i*3, 2); mac[i] = (uint8_t)strtol(dummy, NULL, 16); } } /** * @brief Установить дату производства */ void SETTINGS_SetProDate(char *proDate, uint8_t len) { SYS_t *sSys = NULL; sSys = pvPortMalloc(sizeof(*sSys)); if (sSys) { SYS_Load(sSys); strcpy(sSys->proddate, proDate); SYS_Save(sSys); memset(sSettings.sInfo.productionData, 0, 40); memcpy(sSettings.sInfo.productionData, proDate, len); vPortFree(sSys); SETTINGS_Save(); } } /** * @brief Установить статус тестирования "T2OK" */ void SETTINGS_SetT2OK(void) { SYS_t *sSys = NULL; sSys = pvPortMalloc(sizeof(*sSys)); if (sSys) { SYS_Load(sSys); memset(sSettings.sFlags.testState, 0, 16); memcpy(sSettings.sFlags.testState, "T2OK", 4); strcpy(sSys->testState, sSettings.sFlags.testState); SYS_Save(sSys); vPortFree(sSys); SETTINGS_Save(); } } /** * @brief Включить DHCP */ void SETTINGS_SetDHCPOn(void) { sSettings.sWebParams.dhcpEnable = 1; } void init_settings(void) { flash_mutex = xSemaphoreCreateMutex(); } /********************************* (C) ROTEK **********************************/