Prechádzať zdrojové kódy

add new device BT6706!!!!!!!

balbekova 7 rokov pred
rodič
commit
c8b7500d54

+ 9 - 1
.cproject

@@ -67,6 +67,7 @@
 		<buildTargets>
 			<target name="distclean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
 				<buildCommand>make</buildCommand>
+				<buildArguments/>
 				<buildTarget>distclean</buildTarget>
 				<stopOnError>true</stopOnError>
 				<useDefaultCommand>true</useDefaultCommand>
@@ -74,12 +75,19 @@
 			</target>
 			<target name="HARDWARE=bt6702 VERBOSE=1 DEBUG=0 PRINTF=custom MAC=EC-4C-4D-00-00-0A" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
 				<buildCommand>make</buildCommand>
-				<buildArguments/>
 				<buildTarget>HARDWARE=bt6702 VERBOSE=1 DEBUG=0 PRINTF=custom MAC=EC-4C-4D-00-00-0A</buildTarget>
 				<stopOnError>true</stopOnError>
 				<useDefaultCommand>true</useDefaultCommand>
 				<runAllBuilders>true</runAllBuilders>
 			</target>
+			<target name="HARDWARE=bt6706 VERBOSE=1 DEBUG=0 PRINTF=custom MAC=EC-4C-4D-00-00-0A" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
+				<buildCommand>make</buildCommand>
+				<buildArguments/>
+				<buildTarget>HARDWARE=bt6706 VERBOSE=1 DEBUG=0 PRINTF=custom MAC=EC-4C-4D-00-00-0A</buildTarget>
+				<stopOnError>true</stopOnError>
+				<useDefaultCommand>true</useDefaultCommand>
+				<runAllBuilders>true</runAllBuilders>
+			</target>
 		</buildTargets>
 	</storageModule>
 </cproject>

+ 5 - 0
.gdbinit_bt6706

@@ -0,0 +1,5 @@
+target remote localhost:3333
+file build/bt6702/stm32bt6706/stm32bt6706.elf
+load
+break Reset_Handler
+

+ 4 - 0
.gdbinit_bt6706_noflash

@@ -0,0 +1,4 @@
+target remote localhost:3333
+file build/bt6702/stm32bt6706/stm32bt6706.elf
+break Reset_Handler
+monitor halt

+ 10 - 2
Makefile

@@ -36,12 +36,20 @@ erase:
 iapflash:
 	st-flash --reset write output/iap.bin 0x8000000
 
-fwflash:	
+fwflash_6702:	
 	st-flash --reset write output/stm32bt6702.bin 0x8020000
 
-fullflash:
+fullflash_6702:
 	st-flash --reset write output/iap.bin 0x8000000
 	sleep 1
 	st-flash --reset write output/stm32bt6702.bin 0x8020000
+	
+fwflash_6706:	
+	st-flash --reset write output/stm32bt6706.bin 0x8020000
+
+fullflash_6706:
+	st-flash --reset write output/iap.bin 0x8000000
+	sleep 1
+	st-flash --reset write output/stm32bt6706.bin 0x8020000	
 
 

+ 2 - 0
config/board.h

@@ -3,6 +3,8 @@
 
 #if defined HARDWARE_BT6702
 #include "board_bt6702.h"
+#elif defined HARDWARE_BT6706
+#include "board_bt6706.h"
 #endif
 
 #define EXPAND_AS_ENUM(name, ...) name,

+ 67 - 0
config/board_bt6706.h

@@ -0,0 +1,67 @@
+/*
+ * board_bt6706.h
+ *
+ *  Created on: 08.11.2017
+ *      Author: balbekova
+ */
+
+#ifndef BOARD_BT6706_H_
+#define BOARD_BT6706_H_
+
+#define SERVICE_RS232_UART_TABLE(X)     \
+X( SERVICE_TXDINT,   GPIOD,   5, AF_USART1) \
+X( SERVICE_RXDINT,   GPIOD,   6, AF_USART1)
+
+#define RS232_UART_TABLE(X)     \
+X( TXDINT,   GPIOA,   9, AF_USART2) \
+X( RXDINT,   GPIOA,   10, AF_USART2)
+
+#define SPI2_TABLE(X) \
+X( SPI2_MISO,   GPIOB,  14, AF_SPI2) \
+X( SPI2_MOSI,   GPIOB,  15, AF_SPI2) \
+X( SPI2_SCK,    GPIOB,  10, AF_SPI2) \
+X( SPI2_NSS,    GPIOB,  9,  GPIO_OUT | GPIO_SET)
+
+#define MCU_PERIPHERALS(X)  \
+SERVICE_RS232_UART_TABLE(X)\
+RS232_UART_TABLE(X) \
+SPI2_TABLE(X)
+
+#define DI_TABLE(X)                  \
+X( DIN1,       GPIOA,   0, GPIO_IN)
+
+#define RELAYS(X) \
+X( DOUT1,      GPIOE,  3, GPIO_OUT)\
+X( DOUT2,      GPIOE,  4, GPIO_OUT)\
+X( DOUT3,      GPIOE,  5, GPIO_OUT)\
+
+#define LEDS(X) \
+X( LED_INIT_R,  GPIOA,  4,  GPIO_OUT | GPIO_INV) \
+X( LED_INIT_G,  GPIOA,  3,  GPIO_OUT | GPIO_INV) \
+X( LED_MAJOR_R, GPIOA,  5,  GPIO_OUT | GPIO_INV) \
+X( LED_MINOR_G, GPIOE,  11, GPIO_OUT | GPIO_INV) \
+X( LED_MINOR_R, GPIOE,  12, GPIO_OUT | GPIO_INV)
+
+#define JUMPERS(X) \
+X( MODE_JUMPER, GPIOE,  6,  GPIO_IN_PU | GPIO_INV)
+
+#define BUTTONS(X) \
+X( KEY_DEF,     GPIOE,  7,  GPIO_IN )//| GPIO_INV
+
+#define WDG_PIN(X) \
+X( _WDG,     GPIOE,   15, GPIO_OUT)
+
+#define GPIO_TABLE(X)   \
+MCU_PERIPHERALS(X)  \
+DI_TABLE(X)         \
+RELAYS(X) \
+LEDS(X)             \
+JUMPERS(X) \
+BUTTONS(X)      \
+WDG_PIN(X)
+
+
+#define MAX_IRQ_HANDLERS 4
+
+
+#endif /* BOARD_BT6706_H_ */

+ 5 - 5
config/common_config.h

@@ -114,21 +114,21 @@
 /**
   * @brief  SNMP протокол
   */
-#if defined HARDWARE_BT6702
+//#if defined HARDWARE_BT6702
 #define SNMP_ENABLE
-#endif
+//#endif
 
 /**
   * @brief  UPS
   */
-#if defined HARDWARE_BT6702
+//#if defined HARDWARE_BT6702
 #define UPS_ENABLE
-#endif
+//#endif
     
 /**
   * @brief  Мониторинг FreeRtos
   */
-//#define DEBUG_FREERTOS
+#define DEBUG_FREERTOS
     
 
 

+ 335 - 0
docs/SmartUPS _bt6706.MIB

@@ -0,0 +1,335 @@
+RoTeK-swt-BT-BT-6702-signals-MIB DEFINITIONS ::= BEGIN
+
+    rotek           OBJECT IDENTIFIER ::= { enterprises 41752 }
+    swt             OBJECT IDENTIFIER ::= { rotek 911 }
+    BT-6702         OBJECT IDENTIFIER ::= { swt 3 }
+    signals         OBJECT IDENTIFIER ::= { BT-6702 1 }
+    traps           OBJECT IDENTIFIER ::= { BT-6702 2 }
+
+	
+	FWVersion OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "FWVersion" 
+    ::= { signals 1 }
+
+	RestoreSignal OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  write
+    STATUS  current
+    DESCRIPTION
+    "Restore settings
+    1 - restore settings"
+    ::= { signals 2 }
+	
+	RebootSignal OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  write
+    STATUS  current
+    DESCRIPTION
+    "Reboot device: 
+    1 - reboot"
+    ::= { signals 3 }
+    
+    UPSModel OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "UPS model" 
+    ::= { signals 4 }
+    
+    DO1 OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read-write
+    STATUS  current
+    DESCRIPTION
+    "0 - open relay1
+    1 - close relay1" 
+    ::= { signals 5 }
+    
+    DO2 OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read-write
+    STATUS  current
+    DESCRIPTION
+    "0 - open relay2 
+    1 - close relay2" 
+    ::= { signals 6 }
+    
+    BatTest OBJECT-TYPE
+    SYNTAX  INTEGER
+    ACCESS  write
+    STATUS  current
+    DESCRIPTION
+    "0 - cancel test
+    1-99 - run test to x minutes
+    100 - run test to 10 seconds
+    999 - test till charging"
+    ::= { signals 7 }
+    
+    Shutdown OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  write
+    STATUS  current
+    DESCRIPTION
+    "Control of shut down UPS load:
+	0 - stop shut down load
+	n - shut down load in n minutes
+	n: 0.2, 0.3, .., 1, 2, .., 10"
+    ::= { signals 8 }
+	
+	DI0 OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "State of dry input
+    0 - close dry input
+    1 - open dry input" 
+    ::= { signals 9 }
+	
+	IntTemp OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Internal temperature" 
+    ::= { signals 10 }
+	
+	InFreq OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Input frequency, Hz" 
+    ::= { signals 11 }
+	
+	InVoltVAC OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Input voltage" 
+    ::= { signals 12 }
+	
+	OutVoltVAC OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Output voltage" 
+    ::= { signals 13 }
+	
+	Power OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Power, %" 
+    ::= { signals 14 }
+	
+	BatCap OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Battery capacity, %" 
+    ::= { signals 15 }
+    
+    BatTime OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Rest working time of battery, min" 
+    ::= { signals 16 }
+		
+	ConnectMonitor OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "Connect status:
+	0 - normal;
+	1 - connect fail" 
+    ::= { signals 17 }
+    
+    Alarms OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read
+    STATUS  current
+    DESCRIPTION
+    "bit 7 - utility fail
+	bit 6 - battery low
+	bit 5 - bypass/boost or buck active
+	bit 4 - UPS fail
+	bit 3 - UPS Type is Standby (0 is On_line)
+	bit 2 - Test in Progress
+	bit 1 - Shutdown Active
+	bit 0 - Beeper On" 
+    ::= { signals 18 }
+
+    DO3 OBJECT-TYPE
+    SYNTAX  OCTET STRING
+    ACCESS  read-write
+    STATUS  current
+    DESCRIPTION
+    "0 - open relay2 
+    1 - close relay2" 
+    ::= { signals 19 }
+
+-- DEVICE TRAPS
+
+	FWVersionUpdate  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { FWVersion }
+     DESCRIPTION
+     ::= { traps 1 }
+
+    FWVersionUpdated  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { FWVersion }
+     DESCRIPTION
+     ::= { traps 2 }
+
+	DeviceRestored  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { RestoreSignal }
+     DESCRIPTION
+     ::= { traps 3 }
+
+    DeviceRebooted  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { RebootSignal }
+     DESCRIPTION
+     ::= { traps 4 }
+
+	DI0Norm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { DI0 }
+     DESCRIPTION
+     ::= { traps 5 }
+
+    DI0Alarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { DI0 }
+     DESCRIPTION
+     ::= { traps 6 }
+     
+     DO1Toggled  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { DO1 }
+     DESCRIPTION
+     ::= { traps 7 }
+
+    DO2Toggled  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { DO2 }
+     DESCRIPTION
+     ::= { traps 8 }
+
+    DO3Toggled  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { DO3 }
+     DESCRIPTION
+     ::= { traps 9 }
+
+	BatteryTemperatureNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { IntTemp }
+     DESCRIPTION
+     ::= { traps 10 }
+
+    BatteryTemperatureAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { IntTemp }
+     DESCRIPTION
+     ::= { traps 11 }
+	 
+	LineAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { InVoltVAC }
+     DESCRIPTION
+     ::= { traps 12 }
+
+    LineNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { InVoltVAC }
+     DESCRIPTION
+     ::= { traps 13 } 
+
+	LowBatAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { BatCap }
+     DESCRIPTION
+     ::= { traps 14 }
+
+    LowBatNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { BatCap }
+     DESCRIPTION
+     ::= { traps 15 }
+	 
+	PowerAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { Power }
+     DESCRIPTION
+     ::= { traps 16 }
+
+    PowerNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { Power }
+     DESCRIPTION
+     ::= { traps 17 }
+
+	ConnectMonitorAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { ConnectMonitor }
+     DESCRIPTION
+     ::= { traps 18 }
+	 
+	ConnectMonitorNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { ConnectMonitor }
+     DESCRIPTION
+     ::= { traps 19 }
+     
+     BatteryConnectAlarm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { BatCap }
+     DESCRIPTION
+     ::= { traps 20 }
+
+    BatteryConnectNorm  NOTIFICATION-TYPE
+     STATUS               current
+     ENTERPRISE           traps
+     OBJECTS              { BatCap }
+     DESCRIPTION
+     ::= { traps 21 }	
+	
+END
+
+

+ 1 - 1
modules/Ethernet/lwipopts.h

@@ -156,7 +156,7 @@ a lot of data that needs to be copied, this should be set high. */
 
 /* ---------- Statistics options ---------- */
 #define LWIP_STATS                      1
-#define LWIP_STATS_DISPLAY              0
+#define LWIP_STATS_DISPLAY              1
 #define LWIP_PROVIDE_ERRNO              1
 
 #define LWIP_NETIF_LINK_CALLBACK        0

+ 43 - 2
modules/Ethernet/private_mib.c

@@ -31,6 +31,12 @@ static s16_t signal_get_value(struct snmp_node_instance* instance, void* value);
 static snmp_err_t signal_set_value(struct snmp_node_instance* instance, u16_t len, void* value);
 static snmp_err_t signal_set_test(struct snmp_node_instance* instance, u16_t len, void* value);
 
+#ifdef HARDWARE_BT6706
+/* signal .1.3.6.1.4.1.41752.911.3.1.19  */
+static const struct snmp_scalar_node signal19 = SNMP_SCALAR_CREATE_NODE(19, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_OCTET_STRING, signal_get_value, signal_set_test, signal_set_value);
+
+#endif
+
 /* signal .1.3.6.1.4.1.41752.911.3.1.18  */
 static const struct snmp_scalar_node signal18 = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_OCTET_STRING, signal_get_value);
 
@@ -62,7 +68,7 @@ static const struct snmp_scalar_node signal10 = SNMP_SCALAR_CREATE_NODE_READONLY
 static const struct snmp_scalar_node signal9 = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_OCTET_STRING, signal_get_value);
 
 /* signal .1.3.6.1.4.1.41752.911.3.1.8  */
-static const struct snmp_scalar_node signal8 = SNMP_SCALAR_CREATE_NODE(8, SNMP_NODE_INSTANCE_WRITE_ONLY, SNMP_ASN1_TYPE_INTEGER, NULL, signal_set_test, signal_set_value);
+static const struct snmp_scalar_node signal8 = SNMP_SCALAR_CREATE_NODE(8, SNMP_NODE_INSTANCE_WRITE_ONLY, SNMP_ASN1_TYPE_OCTET_STRING, NULL, signal_set_test, signal_set_value);
 
 /* signal .1.3.6.1.4.1.41752.911.3.1.7  */
 static const struct snmp_scalar_node signal7 = SNMP_SCALAR_CREATE_NODE(7, SNMP_NODE_INSTANCE_WRITE_ONLY, SNMP_ASN1_TYPE_INTEGER, NULL, signal_set_test, signal_set_value);
@@ -108,7 +114,10 @@ static const struct snmp_node* const signals_nodes[] = {
 	&signal15.node.node,
 	&signal16.node.node,
 	&signal17.node.node,
-	&signal18.node.node
+	&signal18.node.node,
+#ifdef HARDWARE_BT6706
+	&signal19.node.node
+#endif
 };
 static const struct snmp_tree_node signals_node = SNMP_CREATE_TREE_NODE(1, signals_nodes);
 
@@ -206,6 +215,11 @@ static s16_t signal_get_value(struct snmp_node_instance* instance, void* value)
 	case 18: /* Alarms */
 		GetAlarmStr((char*)paramStr, &paramLength);
 		break;
+#ifdef HARDWARE_BT6706
+	case 19: /* DO2*/
+		GetDOUTStatusStr((char*)paramStr, &paramLength, 2);
+		break;
+#endif
 	default:
 	break;
     }
@@ -318,6 +332,20 @@ static snmp_err_t signal_set_value(struct snmp_node_instance* instance, u16_t le
   			log_event_data(LOG_SHUTDOWN_UPS, "Администратор");
   	  }
   	  break;
+#ifdef HARDWARE_BT6706
+	case 19: /* DO2*/
+		if(sSettings.sInOuts.ro_type_source[2] == SNMP_SET){
+			  val_string = (char*)value;
+			  SetROStr(val_string, 2);
+			  if(val_string[0] == 0x31)
+				  strcat(str, "Замкнуто");
+			  else
+				  strcat(str, "Разомкнуто");
+			//  SNMP_SendUserTrap(DO1_TOGGLED);
+			  log_event_data(LOG_DO2_STATE, str);
+		  }
+		break;
+#endif
       default :
     	  return SNMP_ERR_GENERROR;
       break;
@@ -386,6 +414,19 @@ static snmp_err_t signal_set_test(struct snmp_node_instance* instance, u16_t len
   		   }
   		}
   	  break;
+#ifdef HARDWARE_BT6706
+	case 19: /* DO2*/
+		if ( len <= 1 )
+		{
+		   val_string = (char*)value;
+		   val_string[len] = 0;
+		   if(atoi(val_string) <= 1){
+			   if(sSettings.sInOuts.ro_type_source[2] == SNMP_SET)
+				 ret = SNMP_ERR_NOERROR;
+		   }
+		}
+		break;
+#endif
     };
 
 

+ 8 - 0
modules/Ethernet/trap_api.c

@@ -96,6 +96,14 @@ void SNMP_InitTrapsBase(void)
     traps[DO1_TOGGLED].trapEnable = true;
     traps[DO1_TOGGLED].handle = GetDOUT1StatusStr; /* State DO1 */
 
+#ifdef HARDWARE_BT6706
+    /* 8. DO1Toggle */ // +
+    traps[DO2_TOGGLED].trapId = DO2_TOGGLED;
+    traps[DO2_TOGGLED].varbindId = 19;
+    traps[DO2_TOGGLED].trapEnable = true;
+    traps[DO2_TOGGLED].handle = GetDOUT2StatusStr; /* State DO2 */
+#endif
+
   /* 9. BatteryTemperatureNorm */ // +
   traps[BATTERY_TEMPERATURE_NORM].trapId = BATTERY_TEMPERATURE_NORM;
   traps[BATTERY_TEMPERATURE_NORM].varbindId = 10;

+ 3 - 0
modules/Ethernet/trap_api.h

@@ -33,6 +33,9 @@ typedef enum
   DI0_ALARM,
   DO0_TOGGLED,
   DO1_TOGGLED,
+#ifdef HARDWARE_BT6706
+  DO2_TOGGLED,
+#endif
   BATTERY_TEMPERATURE_NORM,
   BATTERY_TEMPERATURE_ALARM,
   LINE_ALARM,

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 62 - 2060
modules/HTTP_Server/fsdata.c


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 121 - 705
modules/HTTP_Server/http_server.c


+ 4 - 0
modules/HTTP_Server/http_server.h

@@ -1,3 +1,5 @@
+#ifdef HARDWARE_BT6706
+
 #include "lwip/opt.h"
 #include "lwip/arch.h"
 #include "lwip/api.h"
@@ -179,3 +181,5 @@ SSL_SERVER_STATE SSL_Write(mbedtls_ssl_context *ssl, char *data, int datalen);
 #ifdef __cplusplus
 }
 #endif
+
+#endif

+ 2661 - 0
modules/HTTP_Server/my_ssl_server.c

@@ -0,0 +1,2661 @@
+/*
+ * ssl_server.c
+ *
+ *  Created on: 08.11.2017
+ *      Author: balbekova
+ */
+#ifdef HARDWARE_BT6702
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+#include "lwip/tcp.h"
+
+#include "my_ssl_server.h"
+#include "web_params_api.h"
+#include "parameters.h"
+#include "urlcode.h"
+#include "trap_params.h"
+#include "fsdata.c"
+#include "settings_api.h"
+#include "netconf.h"
+#include "common_config.h"
+#include "testing.h"
+#include "rtc.h"
+#include "rng.h"
+#include "megatec.h"
+#include "log.h"
+#include "hal.h"
+#include "radius_user.h"
+#include "sntp_api.h"
+
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+#include <string.h>
+#include <stdlib.h>
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "fr_timers.h"
+
+static int fs_open(char *name, struct fs_file *file);
+static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len);
+static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len);
+static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len);
+static void http_sent_log_err(void * arg, err_t err);
+static void send_data(struct tcp_pcb *pcb, struct http_state *hs);
+static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len);
+static uint32_t Parse_Content_Length(char *data, uint32_t len);
+static void HTTP_SetUserCookie(char *str, uint8_t user_id);
+static void HTTP_UpdateUserLoginTime(uint8_t user_id);
+static void HTTP_ForceUserLogout(uint8_t user_id);
+void LogoutTimerCallback(TimerHandle_t pxTimer);
+void LoginTimerCallback(TimerHandle_t pxTimer);
+int HTTP_ChangeUserPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+char* send_file(char *filename, char *pnonmatch,  struct fs_file *file, uint16_t *Len);
+static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value);
+bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen);
+
+
+SET_PAGE_t SET_PAGE = SET_PAGE_IDLE;
+
+#define SEND_BUF_MAX_LEN   2000
+#define RECIVE_BUF_MAX_LEN   1500
+char sendBuf[SEND_BUF_MAX_LEN];
+uint16_t sendBufLoadLen = 0;
+
+uint16_t printLen = 0;
+
+char receiveBuf[RECIVE_BUF_MAX_LEN];
+uint16_t receivedBufLen = 0;
+
+#define MAX_POST_REQ_LEN 256
+char post_req_data[MAX_POST_REQ_LEN];
+uint32_t post_data_count = 0;
+uint32_t log_post_reqn;
+
+/* Logout timeout, 30 minutes */
+#define WEB_LOGOUT_TIME  configTICK_RATE_HZ*60*30
+
+/* Max user active sessions count */
+#define WEB_USER_MAX_SESSION_COUNT  5
+
+struct {
+    //auth_session_t session[WEB_USER_MAX_SESSION_COUNT];
+    char cookie[MAX_WEB_COOKIE_LEN];
+    TimerHandle_t LogoutTimer;
+} users[MAX_WEB_USERS];
+
+TimerHandle_t RepeatLoginTimer;
+
+/* Repeat Login timeout, 1 minutes */
+#define REPEAT_LOGIN_TIME  configTICK_RATE_HZ*60*1
+
+uint8_t cnt_err_psw = 0;
+
+bool Authenticated = false;
+
+/* Level of currently logged-in user */
+uint8_t seclevel = 0xFF;
+
+/* Max HTTP file name length including "/" */
+#define MAX_FILENAME_LEN    32
+/* Max HTTP Etag field length */
+#define MAX_ETAG_LEN        48
+static const char If_None_Match[] = "If-None-Match: ";
+static const char Etag[] = "ETag: ";
+
+static volatile uint32_t DataFlag2=0;
+static volatile uint32_t DataFlag=0;
+static volatile uint32_t size =0;
+static uint32_t TotalReceived=0;
+static volatile uint32_t TotalData=0;
+
+static uint32_t ContentLengthOffset =0, BrowserFlag=0;
+
+static const char Content_Length[17] =
+/* Content Length */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67,0x74, 0x68, 0x3a, 0x20, };
+
+const char HTTP_304_NOT_MODIFIED[] = "HTTP/1.1 304 Not Modified\r\n\r\n";
+const char HTTP_200_OK[] = "HTTP/1.1 200 OK\r\n\r\n";
+/* utf-8 marker to support MS Excel */
+const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF, 0x00};
+
+unsigned long log_ptr = 0;
+unsigned long log_size = 0;
+bool fLogTransInprog = false;
+
+
+static bool fl_raddius_net_err = false;
+
+/**
+  * @brief  Общая структура настроек
+  */
+extern SETTINGS_t sSettings;
+
+/**
+  * @brief  closes tcp connection
+  * @param  pcb: pointer to a tcp_pcb struct
+  * @param  hs: pointer to a http_state struct
+  * @retval
+  */
+static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
+{
+  tcp_arg(pcb, NULL);
+  tcp_sent(pcb, NULL);
+  tcp_recv(pcb, NULL);
+  mem_free(hs);
+  tcp_close(pcb);
+}
+
+/**
+  * @brief callback function for handling TCP HTTP traffic
+  * @param arg: pointer to an argument structure to be passed to callback function
+  * @param pcb: pointer to a tcp_pcb structure
+  * @param p: pointer to a packet buffer
+  * @param err: LwIP error code
+  * @retval err
+  */
+static err_t http_recv(void *arg, struct tcp_pcb *pcb,  struct pbuf *p, err_t err)
+{
+	  char *data;
+	  struct http_state *hs;
+	  struct fs_file file = {0, 0};
+	  char buf[150];
+
+	  hs = arg;
+
+	  if (err == ERR_OK && p != NULL)
+	  {
+	    tcp_recved(pcb, p->tot_len);
+
+		if (hs->file == NULL)
+	    {
+	      data = p->payload;
+		  receivedBufLen = p->tot_len;
+		  memcpy(receiveBuf, p->payload , receivedBufLen);
+
+	      // На производстве
+		  if (strncmp(data, "GET /setProdate.cgi", 19) == 0 && strncmp(sSettings.sFlags.testState, "T2OK", 4) == 0)
+		  {
+	        HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
+
+			hs->file = sendBuf;
+	        hs->left = sendBufLoadLen;
+			send_data(pcb, hs);
+			tcp_sent(pcb, http_sent);
+		  }
+		  else {
+			  strcpy(sendBuf, "HTTP/1.1 200 OK\r\n");
+			  strcat(sendBuf, "\r\n\r\n");
+			  memset(buf, 0, 100);
+			 // strcat(sendBuf,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=https://192.168.14.35\"/></head></html>\r\n\r\n");
+			  if (sSettings.sFlags.netsettingsChanged == true)
+				  sprintf(buf, "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=https://%s\"/></head></html>\r\n\r\n", sSettings.sWebTempParams.ip);
+			  else
+				  sprintf(buf, "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=https://%s\"/></head></html>\r\n\r\n", sSettings.sWebParams.ip);
+			  strcat(sendBuf,buf);
+			 // strcat(sendBuf,"1");
+
+			  sendBufLoadLen = strlen(sendBuf);
+			  hs->file = sendBuf;
+			  hs->left = sendBufLoadLen;
+				send_data(pcb, hs);
+ 			    tcp_sent(pcb, http_sent);
+		  }
+		}
+	    pbuf_free(p);
+	    close_conn(pcb,hs);
+	  }
+	  if (err == ERR_OK && p == NULL)
+	  {
+	    close_conn(pcb, hs);
+	  }
+	  return ERR_OK;
+}
+
+
+/**
+  * @brief Error callback for log file transfer
+  */
+static void http_sent_log_err(void * arg, err_t err)
+{
+    (void)err;
+    (void)arg;
+    /* Clear file transfer in progress flag */
+    fLogTransInprog = false;
+}
+
+
+/**
+  * @brief Sent callback for log file transfer (messages as is, not ordered)
+  */
+static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+  struct http_state *hs;
+  uint32_t nbytes = 0;
+  static bool start = true;
+  (void)len;
+
+  hs = arg;
+
+  if (hs->left > 0)
+  {
+    send_data(pcb, hs);
+  }
+  else
+  {
+	  memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
+      if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) {
+          nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start);
+      }
+      else if (log_ptr < log_size) {
+          nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
+      }
+      else {
+          nbytes = 0;
+      }
+      log_ptr += nbytes;
+
+      start = false;
+      if (nbytes == 0) {
+          /* File transfer finished. */
+          start = true;
+          close_conn(pcb, hs);
+
+          /* Clear file transfer in progress flag */
+          fLogTransInprog = false;
+
+          return ERR_OK;
+      }
+
+      hs->file = logFileBuf;
+      hs->left = nbytes;
+      send_data(pcb, hs);
+      tcp_sent(pcb, http_sent_log);
+
+  }
+  return ERR_OK;
+}
+
+/**
+  * @brief Sent callback for log file transfer (messages as is, not ordered)
+  */
+static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+  struct http_state *hs;
+  uint32_t nbytes = 0;
+  static bool start = true;
+  (void)len;
+
+  hs = arg;
+
+  if (hs->left > 0)
+  {
+    send_data(pcb, hs);
+  }
+  else
+  {
+	  memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
+      if (log_ptr + FILE_BUF_MAX_LEN <= log_size) {
+          nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start);
+      }
+      else if (log_ptr < log_size) {
+          nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
+      }
+      else {
+          nbytes = 0;
+      }
+      log_ptr += nbytes;
+
+      start = false;
+      if (nbytes == 0) {
+          /* File transfer finished. */
+          start = true;
+          close_conn(pcb, hs);
+
+          /* Clear file transfer in progress flag */
+          fLogTransInprog = false;
+
+          return ERR_OK;
+      }
+
+      hs->file = logFileBuf;
+      hs->left = nbytes;
+      send_data(pcb, hs);
+      tcp_sent(pcb, http_sent_history);
+
+  }
+  return ERR_OK;
+}
+
+
+/**
+  * @brief  callback function for handling connection errors
+  * @param  arg: pointer to an argument to be passed to callback function
+  * @param  err: LwIP error code
+  * @retval none
+  */
+static void conn_err(void *arg, err_t err)
+{
+  struct http_state *hs;
+
+  hs = arg;
+  mem_free(hs);
+}
+
+/**
+  * @brief callback function called after a successfull TCP data packet transmission
+  * @param arg: pointer to an argument to be passed to callback function
+  * @param pcb: pointer on tcp_pcb structure
+  * @param len
+  * @retval err : LwIP error code
+  */
+static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
+{
+  struct http_state *hs;
+
+  hs = arg;
+
+  if (hs->left > 0)
+  {
+    send_data(pcb, hs);
+  }
+  else
+  {
+    close_conn(pcb, hs);
+  }
+  return ERR_OK;
+}
+
+/**
+  * @brief sends data found in  member "file" of a http_state struct
+  * @param pcb: pointer to a tcp_pcb struct
+  * @param hs: pointer to a http_state struct
+  * @retval none
+  */
+static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
+{
+  err_t err;
+  u16_t len;
+
+  /* We cannot send more data than space available in the send
+     buffer */
+  if (tcp_sndbuf(pcb) < hs->left)
+  {
+    len = tcp_sndbuf(pcb);
+  }
+  else
+  {
+    len = hs->left;
+  }
+  err = tcp_write(pcb, hs->file, len, 0);
+  if (err == ERR_OK)
+  {
+    hs->file += len;
+    hs->left -= len;
+  }
+}
+
+/**
+  * @brief tcp poll callback function
+  * @param arg: pointer to an argument to be passed to callback function
+  * @param pcb: pointer on tcp_pcb structure
+  * @retval err_t
+  */
+static err_t http_poll(void *arg, struct tcp_pcb *pcb)
+{
+  if (arg == NULL)
+  {
+    tcp_close(pcb);
+  }
+  else
+  {
+    send_data(pcb, (struct http_state *)arg);
+  }
+  return ERR_OK;
+}
+
+/**
+  * @brief  callback function on TCP connection setup ( on port 80)
+  * @param  arg: pointer to an argument structure to be passed to callback function
+  * @param  pcb: pointer to a tcp_pcb structure
+  * &param  err: Lwip stack error code
+  * @retval err
+  */
+static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
+{
+  struct http_state *hs;
+
+  /* Allocate memory for the structure that holds the state of the connection */
+  hs = mem_malloc(sizeof(struct http_state));
+
+  if (hs == NULL)
+  {
+    return ERR_MEM;
+  }
+
+  /* Initialize the structure. */
+  hs->file = NULL;
+  hs->left = 0;
+
+  /* Tell TCP that this is the structure we wish to be passed for our
+     callbacks. */
+  tcp_arg(pcb, hs);
+
+  /* Tell TCP that we wish to be informed of incoming data by a call
+     to the http_recv() function. */
+  tcp_recv(pcb, http_recv);
+
+  tcp_err(pcb, conn_err);
+
+  tcp_poll(pcb, http_poll, 10);
+  return ERR_OK;
+}
+
+/**
+  * @brief  Opens a file defined in fsdata.c ROM filesystem
+  * @param  name : pointer to a file name
+  * @param  file : pointer to a fs_file structure
+  * @retval  1 if success, 0 if fail
+  */
+static int fs_open(char *name, struct fs_file *file)
+{
+  struct fsdata_file_noconst *f;
+
+  for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next)
+  {
+    if (!strcmp(name, f->name))
+    {
+      file->data = f->data;
+      file->len = f->len;
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/**
+  * @brief  Initialize the HTTP server (start its thread)
+  * @param  none
+  * @retval None
+  */
+void HTTP_Init()
+{
+
+    struct tcp_pcb *pcb;
+
+    pcb = tcp_new();
+    tcp_bind(pcb, IP_ADDR_ANY, 80);
+    pcb = tcp_listen(pcb);
+    tcp_accept(pcb, http_accept);
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+int HTTP_SettingsPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  char tempStr[30];
+  strncpy(tempStr, bufIn, 30);
+
+  /* В запросе нет параметров, нужно формировать JSON ответ */
+  if (strpbrk(tempStr,"?") == 0)
+  {
+	memset(bufOut, 0, SEND_BUF_MAX_LEN);
+	HTTP_GetSettings(bufOut);
+    *lenBufOut = strlen(bufOut);
+	return SEND_REQUIRED_YES;
+  }
+  /* В запросе есть параметры, нужно парсить и сохранять настройки */
+  else
+  {
+	//HTTP_SetSettings(bufIn, lenBufIn);
+    return SEND_REQUIRED_NO;
+  }
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+int HTTP_InfoPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  char tempStr[30];
+  strncpy(tempStr, bufIn, 30);
+
+  /* В запросе нет параметров, нужно формировать JSON ответ */
+  if (strpbrk(tempStr,"?") == 0)
+  {
+	memset(bufOut, 0, SEND_BUF_MAX_LEN);
+
+	HTTP_GetInfo(bufOut);
+
+    *lenBufOut = strlen(bufOut);
+
+	return SEND_REQUIRED_YES;
+  }
+  /* В запросе есть параметры, нужно парсить и сохранять настройки */
+  else
+  {
+	//HTTP_SetInfo(bufIn, lenBufIn);
+	return SEND_REQUIRED_NO;
+/*
+	HTTP_SetSettings(bufIn, lenBufIn);
+    return SEND_REQUIRED_NO;
+*/
+  }
+}
+
+int HTTP_HistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  uint8_t i, valueLen = 0;
+  char value[20];
+  uint32_t nbytes = 0;
+
+  (void)lenBufIn;
+
+  memset(bufOut, 0, FILE_BUF_MAX_LEN);
+
+  ClearParamString(bufIn);
+
+  memset(value, 0, 20);
+  GetParamValue(bufIn, "page=", value, &valueLen);
+
+  if (strcmp(value, "all") == 0)
+  {
+	  if (!LOG_IsInit()) {
+		  return SEND_REQUIRED_NO;
+	  }
+
+      if (fLogTransInprog == false) {
+
+        // Send log as raw data
+        log_ptr = 0;
+
+        log_size = History_GetTotalSTRCount() * STRING_SIZE_HISTORY + sizeof(UTF8_BOM)-1;
+        sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM);
+
+        *lenBufOut = strlen(bufOut);
+
+        // Set file transfer in progress flag
+        fLogTransInprog = true;
+
+        return SEND_REQUIRED_FILE;
+     }
+     else {
+          // We send nothing if file transfer already in progress
+          return SEND_REQUIRED_NO;
+     }
+  }
+  else {
+	  if (!LOG_IsInit()) {
+		  return SEND_REQUIRED_NO;
+	  }
+	  else {
+		  HTTP_GetHistoryPage(bufOut, atoi(value));
+		  *lenBufOut = strlen(bufOut);
+
+		  return SEND_REQUIRED_YES;
+	  }
+  }
+}
+
+int HTTP_UpsHistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  uint8_t i, valueLen = 0;
+  char value[20];
+  uint32_t nbytes = 0;
+
+  (void)lenBufIn;
+
+  memset(bufOut, 0, FILE_BUF_MAX_LEN);
+
+  ClearParamString(bufIn);
+
+  memset(value, 0, 20);
+  GetParamValue(bufIn, "page=", value, &valueLen);
+
+  if (strcmp(value, "all") == 0)
+  {
+	  if (!LOG_IsInit()) {
+		  return SEND_REQUIRED_NO;
+	  }
+
+      if (fLogTransInprog == false) {
+
+        // Send log as raw data
+        log_ptr = 0;
+
+        log_size = LOG_GetTotalSTRCount() * STRING_SIZE + sizeof(UTF8_BOM)-1;
+        sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM);
+
+        *lenBufOut = strlen(bufOut);
+
+        // Set file transfer in progress flag
+        fLogTransInprog = true;
+
+        return SEND_REQUIRED_FILE;
+     }
+     else {
+          // We send nothing if file transfer already in progress
+          return SEND_REQUIRED_NO;
+     }
+  }
+  else {
+	  if (!LOG_IsInit()) {
+		  return SEND_REQUIRED_NO;
+	  }
+	  else {
+		  HTTP_GetUpsHistoryPage(bufOut, atoi(value));
+		  *lenBufOut = strlen(bufOut);
+
+		  return SEND_REQUIRED_YES;
+	  }
+  }
+}
+
+/**
+  * @brief  Установка даты производства
+  */
+// TODO Убрать заглушку!
+void HTTP_Prodate(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  uint8_t valueLen = 0;
+  char value[20];
+
+  memset(bufOut, 0, SEND_BUF_MAX_LEN);
+
+  ClearParamString(bufIn);
+
+  memset(value, 0, 20);
+  GetParamValue(bufIn, "prodate=", value, &valueLen);
+  /*
+  printf("Prodate: ");
+  printf(value);
+  printf("\r\n");
+  */
+
+  /* Устанавливаем дату производства */
+  SETTINGS_SetProDate(value, valueLen);
+
+  /* Пока отправляем true */
+  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\nTrue");
+  *lenBufOut = strlen(bufOut);
+
+  TEST_SetServerFlag();
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+void HTTP_SetSettings(char *buf, uint16_t lenBuf)
+{
+  uint8_t valueLen = 0;
+  const uint8_t len = MAX_WEB_PARAM_LEN;
+  char value[MAX_WEB_PARAM_LEN];
+  char str[MAX_WEB_PARAM_LEN];
+
+  //printf(buf);
+
+  //ClearParamString(buf);
+
+  memset(value, 0, len);
+  memset(str, 0, MAX_WEB_PARAM_LEN);
+
+  /* SNMP */
+  GetParamValue(buf, "read_community=", value, &valueLen);
+  SetReadCommunity(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "write_community=", value, &valueLen);
+  SetWriteCommunity(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "managerIP=", value, &valueLen);
+  SetManagerIp(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "managerIP2=", value, &valueLen);
+  SetManagerIp2(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "managerIP3=", value, &valueLen);
+  SetManagerIp3(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "managerIP4=", value, &valueLen);
+  SetManagerIp4(value);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "managerIP5=", value, &valueLen);
+  SetManagerIp5(value);
+  memset(value, 0, len);
+
+  /* Сетевые параметры */
+  GetParamValue(buf, "dhcp=", value, &valueLen);
+  SetDhcpStateStr(value);
+
+  if (strncmp(value, "on", 2) != 0)  // Если dhcp off устанавливаем параметры
+    {
+    memset(value, 0, len);
+
+    GetParamValue(buf, "ipaddr=", value, &valueLen);
+    SetIPStr(value);
+    memset(value, 0, len);
+
+    GetParamValue(buf, "gw=", value, &valueLen);
+    SetGatewayStr(value);
+    memset(value, 0, len);
+
+    GetParamValue(buf, "mask=", value, &valueLen);
+    SetMaskStr(value);
+    memset(value, 0, len);
+  }
+  memset(value, 0, len);
+
+  GetParamValue(buf, "swauth=", value, &valueLen);
+  SetAuthEnableStateStr(value);
+
+  if (strncmp(value, "on", 2) == 0){
+		/* параметры RADIUS*/
+	  memset(value, 0, len);
+		GetParamValue(buf, "rs_enabled=", value, &valueLen);
+		SetRDSEnableStateStr(value);
+
+		if (strncmp(value, "on", 2) == 0)  // Если raddius off устанавливаем параметры
+		{
+			memset(value, 0, len);
+			GetParamValue(buf, "rs_server=", value, &valueLen);
+			SetRDSIpStr(value);
+			memset(value, 0, len);
+
+			GetParamValue(buf, "rs_port=", value, &valueLen);
+			SetRDSPortStr(value);
+			memset(value, 0, len);
+
+			GetParamValue(buf, "rs_pwd=", value, &valueLen);
+			SetRDSPasswordkStr(value);
+			memset(value, 0, len);
+
+			GetParamValue(buf, "rs_key=", value, &valueLen);
+			SetRDSKeyAccesstStr(value);
+			memset(value, 0, len);
+		}
+  }
+  memset(value, 0, len);
+
+  // Параметры реле и сухих контактов
+  GetParamValue(buf, "di1=", value, &valueLen);
+  SetDINTypeActStr(value, 0);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "ro1=", value, &valueLen);
+  SetROTypeActStr(value, 0);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "ro2=", value, &valueLen);
+  SetROTypeActStr(value, 1);
+  memset(value, 0, len);
+
+  GetParamValue(buf, "utc=", value, &valueLen);
+  SetSntpTimeZoneStr(value);
+  memset(value, 0, len);
+
+  // Параметры даты и времени
+  GetParamValue(buf, "ntp=", value, &valueLen);
+
+  if (strncmp(value, "1", 1) == 0)  // Если ntp on устанавливаем параметры
+  {
+	bool old_sntp = false;
+	bool enable_old_sntp = sSettings.sSNTP.sntpEnable;
+    memset(str, 0, len);
+    GetParamValue(buf, "ntpservip=", str, &valueLen);
+    if(strncmp(str, sSettings.sSNTP.ip, valueLen))
+    	old_sntp = true;
+    SetSntpServerIpStr(str);
+    SetSntpStateStr(value);
+    if(sSettings.sSNTP.sntpEnable != enable_old_sntp)
+    	old_sntp = true;
+	if(old_sntp){
+		SNTP_Init();
+		//vTaskDelay(7000);
+		SNTP_Poll();
+	}
+    memset(value, 0, len);
+    memset(str, 0, len);
+  }
+  else if (strncmp(value, "0", 1) == 0){
+	  SetSntpStateStr(value);
+	  memset(value, 0, len);
+      GetParamValue(buf, "date=", value, &valueLen);
+      SetDateStr(value);
+      memset(value, 0, len);
+      GetParamValue(buf, "time=", value, &valueLen);
+      memset(str, 0, len);
+      url_decode(str, sizeof(str), value);
+      SetTimeStr(str);
+      memset(value, 0, len);
+      memset(str, 0, len);
+  }
+
+  /* Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся */
+  if (GetStateWebReinit() == true)
+  {
+	SetWebReinitFlag(true);
+	HTTP_SaveSettings();
+    /* Блокируем управление ключем на тау секунд*/
+    //IO_KeyBlockOn();
+    vTaskDelay(1010);
+    Reboot();
+  }
+
+  HTTP_SaveSettings();
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+void HTTP_SetInfo(char *buf, uint16_t lenBuf)
+{
+  uint8_t valueLen = 0;
+  const uint8_t len = 110;
+  char value[110];
+  char str[110];
+
+ // ClearParamString(buf);
+
+  memset(value, 0, len);
+
+  /* Владелец */
+  GetParamValue(buf, "owner=", value, &valueLen);
+  url_decode(str, sizeof(str), value);
+  SetOwner(str);
+  memset(value, 0, len);
+
+  /* Владелец */
+  GetParamValue(buf, "sysLocation=", value, &valueLen);
+  url_decode(str, sizeof(str), value);
+  SetLocation(str);
+  memset(value, 0, len);
+
+  /* Комментарий */
+  GetParamValue(buf, "comment=", value, &valueLen);
+  url_decode(str, sizeof(str), value);
+  SetComment(str);
+  memset(value, 0, len);
+
+  HTTP_SaveSettings();
+}
+
+/**
+  * @brief  Запуск/останов теста UPS
+  */
+void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+	  uint8_t valueLen = 0;
+	  char tempValue[20];
+	  char tempValue2[20];
+	  int8_t res = 0;
+	  char log_string[50];
+
+	  memset(tempValue, 0, 20);
+	  memset(tempValue2, 0, 20);
+	  memset(log_string, 0,50);
+
+	  strcpy(bufOut, HTTP_200_OK);
+
+	  GetParamValue(bufIn, "func=", tempValue, &valueLen);
+	  if (strcmp(tempValue, "stop") == 0){
+		  res = ups_metac_service_pdu(ups_cancel_test);
+		  if(res == 1 || res == 0){
+			  strcat(bufOut, "Тест остановлен!");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Останов)");
+			  log_event_data(LOG_TEST_UPS, log_string);
+		  }
+		  if(res == -1)
+			  strcat(bufOut, "Тест не удалось остановить!");
+		  *lenBufOut = strlen(bufOut);
+	  }
+	  else if (strcmp(tempValue, "discharge") == 0){
+		  res = ups_metac_service_pdu(ups_test_low_bat);
+		  if(res == 1 || res == 0){
+			  strcat(bufOut, "Тест запущен!");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
+		  }
+		  if(res == -1)
+			  strcat(bufOut, "Тест не удалось запустить!");
+		  *lenBufOut = strlen(bufOut);
+	  }
+	  else if (strncmp(tempValue, "time", 6) == 0){
+		  GetParamValue(bufIn, "=", tempValue2, &valueLen);
+		  TimeParam = atoi(tempValue2);
+		  res = ups_metac_service_pdu(ups_test_time);
+		  if(res == 1 || res == 0){
+			  strcat(bufOut, "Тест запущен!");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
+		  }
+		  if(res == -1)
+			  strcat(bufOut, "Тест не удалось запустить!");
+		  *lenBufOut = strlen(bufOut);
+	  }
+}
+
+/**
+  * @brief  Выклюение UPS
+  */
+void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+	  uint8_t valueLen = 0;
+	  char *valueLenEnd = 0;
+	  char tempValue[50];
+	  char tempValue2[50];
+	  int8_t res = 0;
+	  char log_string[50];
+
+	  memset(tempValue, 0, 50);
+	  memset(log_string, 0,50);
+
+	  strcpy(bufOut, HTTP_200_OK);
+
+	  GetParamValue(bufIn, "func=", tempValue, &valueLen);
+	  if (strcmp(tempValue, "reboot") == 0){
+		  res = ups_metac_service_pdu(ups_cancel_shut_down);
+		  if(res == 1){
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Останов)");
+			  log_event_data(LOG_SHUTDOWN_UPS, log_string);
+			  strcat(bufOut, "Выключение нагрузки ИБП отменено!");
+		  }
+		  else
+			  strcat(bufOut, "Выключение нагрузки ИБП не удалось отменить!");
+		  *lenBufOut = strlen(bufOut);
+	  }
+	  else if (strncmp(tempValue, "off", 5) == 0){
+		  memset(tempValue2, 0, 50);
+		  GetParamValue(bufIn, "after=", tempValue2, &valueLen);
+		  TimeParamFloat = atof(tempValue2);
+		  res = ups_metac_service_pdu(ups_shutdown);
+		  if(res == 1){
+			  strcat(bufOut, "Отключение нагрузки ИБП!");
+			  log_event_data(LOG_SHUTDOWN_UPS, name_login);
+		  }else
+			  strcat(bufOut, "Отключение нагрузки ИБП не удалось!");
+		  *lenBufOut = strlen(bufOut);
+	  }
+}
+
+
+/**
+  * @brief  Проверка пароля для перехода в режим bootloader
+  * @retval None
+  */
+void HTTP_ConfirmBootPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+  char tempStr[50];
+  strncpy(tempStr, bufIn, 50);
+  char value[20];
+  uint8_t valueLen;
+
+  memset(value, 0, 20);
+
+  /* Запускаем задачу отложенной перезагрузки. Контроллер должен успеть
+     отправить ответ серверу о статусе пароля */
+  HTTP_StartResetTask(true);
+}
+
+void LoginTimerCallback(TimerHandle_t pxTimer) {
+	cnt_err_psw = 0;
+	DBG printf("cnt_err_psw %d", cnt_err_psw);
+	xTimerStop(RepeatLoginTimer, 0);
+}
+
+/**
+  * @brief  Проверка пароля для входа в Web
+  * @retval None
+  */
+int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+	  char tempStr[50];
+	  char login[20];
+	  char password[20];
+	  uint8_t valueLen, user_id;
+	  char *strPtr = 0;
+	  char WebPassword[MAX_WEB_PASSWD_LEN];
+	  char WebLogin[MAX_WEB_LOGIN_LEN];
+
+	  memset(login, 0, 20);
+	  memset(password, 0, 20);
+	  memset(tempStr, 0, 50);
+
+	  memset(name_login, 0, 50);
+
+	  /* Get first 50 bytes of string */
+	  strncpy(tempStr, bufIn, 49);
+
+	  /* Add " " to the string in order GetParamValue() can be able to parse the param */
+	  strcat(tempStr, " ");
+	  GetParamValue(tempStr, "login=", login, &valueLen);
+	  GetParamValue(tempStr, "password=", password, &valueLen);
+
+	  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){
+		  switch(RC_Login(login, password)){
+		  case RC_ERROR:
+			  Authenticated = false;
+			  break;
+		  case RC_LOGIN_ADMIN_OK:
+			  Authenticated = true;
+			  user_id = 0;
+			  break;
+		  case RC_LOGIN_USER_OK:
+			  Authenticated = true;
+			  user_id = 1;
+			  break;
+		  case RC_NET_ERR:
+			  Authenticated = false;
+			  fl_raddius_net_err = true;
+			  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
+			  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Ошибка соединения с RADIUS сервером</h2></center></html>");
+			  *lenBufOut = strlen(bufOut);
+			  return SEND_REQUIRED_NO;
+			  break;
+		  case RC_ACC_DENIED:
+			  Authenticated = false;
+			  break;
+		  default:
+			  break;
+		  }
+	  }
+	  else{
+		  for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
+
+		        GetUserLogin(user_id, WebLogin, &valueLen);
+		        GetUserPassword(user_id, WebPassword, &valueLen);
+
+		        /* Check login and password */
+		        if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
+		            (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
+
+		            /* Login and pass are valid */
+
+	            /* TODO replace global flag with user-pass-cookie */
+		        	if(cnt_err_psw < 4){
+		        		cnt_err_psw = 0;
+		        		Authenticated = true;
+		        	}
+		        	else{
+		        		Authenticated = false;
+		        	}
+		        	break;
+		        }
+		        else{
+		        	Authenticated = false;
+		        }
+		  }
+	  }
+
+	  if(Authenticated){
+		  /* Generate cookie */
+		  sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
+
+		  /* Set users cookie */
+		  HTTP_SetUserCookie(tempStr, user_id);
+
+		  HTTP_UpdateUserLoginTime(user_id);
+
+		  /* Send login and cookie back */
+		  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
+		  strcat(bufOut, login);
+		  strcat(bufOut, "\r\nSet-Cookie: id=");
+		  strcat(bufOut, tempStr);
+		  sprintf(tempStr, "%d", user_id);
+		  strcat(bufOut, "\r\nSet-Cookie: role=");
+		  strcat(bufOut, tempStr);
+		  if(sSettings.sRADIUS.Auth_enable)
+			strcat(bufOut, "\r\nSet-Cookie: auth=1");
+		else
+			strcat(bufOut, "\r\nSet-Cookie: auth=0");
+		  strcat(bufOut, "\r\n\r\n");
+		  strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
+
+		  *lenBufOut = strlen(bufOut);
+		  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){
+			  snprintf(name_login, (strlen(login)+1), login);
+		  }
+		  else{
+			  fl_raddius_net_err = false;
+			  switch (user_id) {
+				  case 0:
+					  snprintf(name_login, sizeof(name_login), "Администратор");
+					  break;
+				  case 1:
+					  snprintf(name_login, sizeof(name_login), "Пользователь");
+					  break;
+				  default:
+					  snprintf(name_login, (strlen(login)+1), login);
+					  break;
+			  }
+		  }
+
+
+		  log_event_data(LOG_LOGIN, name_login);
+		  /* Запускаем задачу-таймер логаута. */
+		  /* TODO отправить ответ серверу о статусе пароля */
+		  return SEND_REQUIRED_YES;
+	  }
+	  else{
+		  if(cnt_err_psw <= 4)
+				cnt_err_psw ++;
+			DBG printf("cnt_err_psw %d", cnt_err_psw);
+			if(cnt_err_psw == 4)
+				xTimerStart(RepeatLoginTimer, 0);
+		  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
+		  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){
+			  if(cnt_err_psw < 4)
+				  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
+			  else
+				  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Вход заблокирован!</h2></center></head><center><h2>Повторите попытку через 1 минуту</h2></center></html>");
+		  }
+		  else{
+			  if(cnt_err_psw < 4)
+				  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
+			  else
+				  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Вход заблокирован!</h2></center></head><center><h2>Повторите попытку через 1 минуту</h2></center></html>");
+		  }
+		  *lenBufOut = strlen(bufOut);
+		  return SEND_REQUIRED_NO;
+	  }
+}
+
+void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut)
+{
+	char tempStr[50];
+	uint8_t valueLen;
+	char WebLogin[MAX_WEB_LOGIN_LEN];
+
+	GetUserLogin(ADMIN, WebLogin, &valueLen);
+
+	memset(tempStr, 0, 50);
+	memset(name_login, 0, 50);
+
+	/* TODO replace global flag with user-pass-cookie */
+	Authenticated = true;
+
+	/* Generate cookie */
+	sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
+
+	/* Set users cookie */
+	HTTP_SetUserCookie(tempStr, ADMIN);
+
+	HTTP_UpdateUserLoginTime(ADMIN);
+
+	/* Send login and cookie back */
+	strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
+	strcat(bufOut, WebLogin);
+	strcat(bufOut, "\r\nSet-Cookie: id=");
+	strcat(bufOut, tempStr);
+	strcat(bufOut, "\r\nSet-Cookie: role=0");
+	if(sSettings.sRADIUS.Auth_enable)
+		strcat(bufOut, "\r\nSet-Cookie: auth=1");
+	else
+		strcat(bufOut, "\r\nSet-Cookie: auth=0");
+	strcat(bufOut, "\r\n\r\n");
+	strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
+
+	*lenBufOut = strlen(bufOut);
+
+	snprintf(name_login, sizeof(name_login), "Администратор");
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+uint8_t GetParamValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
+{
+  char *beginValue = 0;
+  char *endValue = 0;
+  int  len = 0;
+  char *strPtr = 0;
+
+  strPtr = strstr(inStr, paramName);
+
+  if (strPtr != 0)
+  {
+    beginValue = strpbrk(strPtr,"=");
+    endValue = strpbrk(strPtr,"&");
+    if (endValue == 0)
+      endValue = strpbrk(strPtr," ");
+    len = endValue - beginValue - 1;
+    strncpy(paramValue, beginValue + 1, len);
+    *endValue = '0';
+    *beginValue = '0';
+	*paramLen = len;
+	return 1;
+  }
+  else
+  {
+	*paramLen = 0;
+	return 0;
+  }
+}
+
+/**
+  * @brief
+  * @retval None
+  */
+uint8_t GetCookieValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
+{
+  char *beginValue = 0;
+  char *endValue = 0;
+  int  len = 0;
+  char *strPtr = 0;
+
+  strPtr = strstr(inStr, paramName);
+
+  if (strPtr != 0)
+  {
+    beginValue = strpbrk(strPtr,"=");
+    endValue = strpbrk(strPtr,";");
+    if (endValue == 0)
+      endValue = strpbrk(strPtr,"\n");
+    len = endValue - beginValue - 1;
+    strncpy(paramValue, beginValue + 1, len);
+    *endValue = '0';
+    *beginValue = '0';
+    *paramLen = len;
+    return 1;
+  }
+  else
+  {
+    *paramLen = 0;
+    return 0;
+  }
+}
+
+char* Parce_Boundary(const char* data, uint32_t len, char* dst, uint8_t dstlen) {
+    char *ptr = NULL;
+    char *boundary = NULL;
+    uint8_t i = 0;
+
+    for (uint32_t j = 0; j < len; j++) {
+        if (strncmp ((char*)(data + j), "boundary=", 9) == 0) {
+            boundary = (char*)data + j + 9;
+            break;
+        }
+    }
+
+    if (!boundary) return NULL;
+
+    *dst++ = '-';
+    *dst++ = '-';
+
+    ptr = boundary;
+    while ((*ptr != 0x0d) && (i < dstlen - 4))
+    {
+        *dst++ = *ptr++;
+        i++;
+    }
+    //*dst++ = '-';
+    //*dst++ = '-';
+    *dst = '\0';
+
+    if (i > 0)
+        return boundary;
+    else
+        return NULL;
+}
+
+void ClearParamString(char *inBuf)
+{
+  uint16_t len;
+  char *str;
+
+  str = strstr(inBuf, "HTTP");
+
+  if (str != 0)
+  {
+    len = str - inBuf;
+	memset(str, 0, RECIVE_BUF_MAX_LEN - len - 1);
+  }
+}
+
+/**
+  * @brief Чтение Cookie пользователя
+  */
+static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len)
+{
+    sprintf(str, "%s", users[user_id].cookie);
+    *len = strlen(str);
+}
+
+/**
+  * @brief Установка Cookie пользователя
+  */
+static void HTTP_SetUserCookie(char *str, uint8_t user_id)
+{
+    strcpy(users[user_id].cookie, str);
+}
+
+/**
+  * @brief Обновление времени последней активности пользователя
+  */
+static void HTTP_UpdateUserLoginTime(uint8_t user_id)
+{
+    xTimerStart(users[user_id].LogoutTimer, 0);
+}
+
+/**
+  * @brief  Extract the Content_Length data from HTML data
+  * @param  data : pointer on receive packet buffer
+  * @param  len  : buffer length
+  * @retval size : Content_length in numeric format
+  */
+static uint32_t Parse_Content_Length(char *data, uint32_t len)
+{
+  uint32_t i=0,size=0, S=1;
+  int32_t j=0;
+  char sizestring[6], *ptr;
+
+  ContentLengthOffset =0;
+
+  /* find Content-Length data in packet buffer */
+  for (i=0;i<len;i++)
+  {
+    if (strncmp ((char*)(data+i), Content_Length, 16)==0)
+    {
+      ContentLengthOffset = i+16;
+      break;
+    }
+  }
+  /* read Content-Length value */
+  if (ContentLengthOffset)
+  {
+    i=0;
+    ptr = (char*)(data + ContentLengthOffset);
+    while(*(ptr+i)!=0x0d)
+    {
+      sizestring[i] = *(ptr+i);
+      i++;
+      ContentLengthOffset++;
+    }
+    if (i>0)
+    {
+      /* transform string data into numeric format */
+      for(j=i-1;j>=0;j--)
+      {
+        size += (sizestring[j]-0x30)*S;
+        S=S*10;
+      }
+    }
+  }
+  return size;
+}
+
+/**
+  * @brief Принудительный логаут пользователя
+  */
+static void HTTP_ForceUserLogout(uint8_t user_id)
+{
+    char cookie[MAX_WEB_COOKIE_LEN];
+
+    /* Flush user cookie by random value */
+    sprintf(cookie, "%X", (unsigned int)GetRandomNumber());
+    HTTP_SetUserCookie(cookie, user_id);
+}
+
+/**
+  * @brief >Callback таймера логаута пользователя
+  */
+void LogoutTimerCallback(TimerHandle_t pxTimer) {
+    uint8_t user_id = (uint8_t)pvTimerGetTimerID( pxTimer );
+	if( sSettings.sRADIUS.Auth_enable )
+		HTTP_ForceUserLogout(user_id);
+}
+
+/**
+  * @brief  Смена пароля пользователя
+  * @retval None
+  */
+int HTTP_ChangeUserPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
+{
+    char tempStr[110];
+
+    char value[20];
+    char login[20];
+    char password[20];
+    uint8_t valueLen, valueLen2, user_id;
+    char WebLogin[MAX_WEB_LOGIN_LEN];
+
+    (void)lenBufIn;
+
+    memset(login, 0, 20);
+    memset(password, 0, 20);
+    memset(tempStr, 0, 50);
+    memset(value, 0, 20);
+
+    ClearParamString(bufIn);
+
+    strncpy(tempStr, bufIn, 110);
+
+    strcpy(bufOut, HTTP_200_OK);
+
+    if (GetParamValue(tempStr, "username=", login, &valueLen) &&
+        GetParamValue(tempStr, "oldpass=", password, &valueLen))
+    {
+          for (user_id = 0; user_id < MAX_WEB_USERS; user_id++)
+          {
+        	  memset(value, 0, 20);
+			  memset(WebLogin, 0, MAX_WEB_LOGIN_LEN);
+			 GetUserLogin(user_id, WebLogin, &valueLen);
+			 GetUserPassword(user_id, value, &valueLen2);
+			 /* Check login and password */
+			 if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
+				 (memcmp(password, value, 11) == 0))
+			 {
+				 memset(password, 0, 20);
+				 if (GetParamValue(tempStr, "newpass=", password, &valueLen))
+				 {
+
+					 memcpy(sSettings.sAuth[user_id].password, password, 11);
+
+					 HTTP_SaveSettings();
+					 log_event_data(LOG_PSW_CHANGE, name_login);
+					 strcat(bufOut, "Пароль успешно изменён");
+					 *lenBufOut = strlen(bufOut);
+					 return SEND_REQUIRED_YES;
+				 }
+				 else {
+					  strcat(bufOut, "Введены некорректные данные!");
+					  *lenBufOut = strlen(bufOut);
+					  return SEND_REQUIRED_YES;
+				 }
+			 }
+          }
+          strcat(bufOut, "Введён неверный пароль!");
+          *lenBufOut = strlen(bufOut);
+          return SEND_REQUIRED_YES;
+  }
+  else {
+      strcat(bufOut, "Введены некорректные данные!");
+      *lenBufOut = strlen(bufOut);
+      return SEND_REQUIRED_YES;
+  }
+}
+
+
+
+// -----------------------------------------------------------------------------
+
+#include "mbedtls/platform.h"
+
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/certs.h"
+#include "mbedtls/x509.h"
+#include "mbedtls/net_sockets.h"
+#include "mbedtls/error.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/memory_buffer_alloc.h"
+#include "mbedtls_time.h"
+#include "mbedtls_debug.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "cert_req.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+extern unsigned char req_cert[];
+
+static mbedtls_net_context listen_fd, client_fd;
+static const uint8_t *pers = (uint8_t *)("ssl_server");
+mbedtls_entropy_context entropy;
+mbedtls_ctr_drbg_context ctr_drbg;
+mbedtls_ssl_context ssl;
+mbedtls_ssl_config conf;
+mbedtls_x509_crt srvcert;
+mbedtls_pk_context pkey;
+
+char CookieBuf[51];
+char *CookiePtr = NULL;
+char name[MAX_WEB_COOKIE_LEN];
+char id[MAX_WEB_COOKIE_LEN];
+uint8_t nameLen = 0, idLen = 0;
+uint8_t user_id; // Id of currently logged-in user
+struct fs_file file = {0, 0};
+
+//
+void Cockie(void)
+{
+  char* endPtr;
+  uint32_t len;
+  receiveBuf[receivedBufLen] = '\0';
+  //printf("receive %s \r\n", receiveBuf);
+  // Get cookie "uname" value
+  memset(CookieBuf, 0, sizeof(CookieBuf));
+  CookiePtr = strstr(receiveBuf, "uname=");
+  endPtr = strstr(CookiePtr, "\r");
+  len =  (endPtr - CookiePtr)+2;
+  if(len < 50)
+	strncpy(CookieBuf, CookiePtr,len);
+  else
+	strncpy(CookieBuf, CookiePtr, 50);
+
+  //printf("********CookieBuf1= %s\r\n", CookieBuf);
+  memset(name, 0, MAX_WEB_COOKIE_LEN);
+  GetCookieValue(CookieBuf, "uname=", name, &nameLen);
+  //printf("********CookieBuf2= %s\r\n", CookieBuf);
+  //printf("********uname= %s\r\n", name);
+
+  memset(CookieBuf, 0, sizeof(CookieBuf));
+  // Get cookie "id" value
+  CookiePtr = strstr(receiveBuf, " id=");
+  if(len < 50)
+ 	strncpy(CookieBuf, CookiePtr,len);
+  else
+    strncpy(CookieBuf, CookiePtr, 50);
+
+  //printf("********CookieBuf1= %s\r\n", CookieBuf);
+  memset(id, 0, MAX_WEB_COOKIE_LEN);
+  GetCookieValue(CookieBuf, "id=", id, &idLen);
+  // printf("********ID= %s\r\n", id);
+}
+
+//
+void getAuthenticatedState(void)
+{
+  seclevel = 0xFF;
+  for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
+	HTTP_GetUserCookie(user_id, CookieBuf, &idLen);
+	if (strncmp(id, CookieBuf, idLen) == 0 ) {
+	  GetUserLevelInt(user_id, &seclevel);
+	  Authenticated = true;
+	  break;
+	}
+	Authenticated = false;
+	seclevel = 0xFF;
+  }
+}
+
+//
+void ssl_server(void *pvParameters)
+{
+  SSL_SERVER_STATE ssl_state = SSL_ACCEPT;
+  char* sendPtr;
+  int ret;
+
+  mbedtls_net_init( &listen_fd );
+  mbedtls_net_init( &client_fd );
+  mbedtls_ssl_init( &ssl );
+  mbedtls_ssl_config_init( &conf );
+  mbedtls_x509_crt_init( &srvcert );
+  mbedtls_pk_init( &pkey );
+  mbedtls_entropy_init( &entropy );
+  mbedtls_ctr_drbg_init( &ctr_drbg );
+  mbedtls_platform_set_time(&MBEDTLS_GetTime);
+#if defined(MBEDTLS_DEBUG_C)
+  mbedtls_debug_set_threshold(DEBUG_LEVEL);
+  mbedtls_ssl_conf_dbg(&conf, MBEDTLS_Debug, NULL);
+#endif
+
+  // 1. Load the certificates and private RSA key
+  mbedtls_printf( "\r\n  . Loading the server cert. and key..." );
+  ret = mbedtls_x509_crt_parse( &srvcert, (const unsigned char *) sSettings.our_srv_crt, (strlen(sSettings.our_srv_crt) + 1) );//mbedtls_test_srv_crtmbedtls_test_srv_crt_len
+  if( ret != 0 )
+  {
+    mbedtls_printf( " failed\r\n  !  mbedtls_x509_crt_parse returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+
+  ret =  mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_srv_key, mbedtls_test_srv_key_len, NULL, 0 );
+  if( ret != 0 )
+  {
+    mbedtls_printf( " failed\r\n  !  mbedtls_pk_parse_key returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+
+  mbedtls_printf( " ok\r\n" );
+
+  // 2. Setup the listening TCP socket
+  mbedtls_printf( "  . Bind on https://localhost:443/ ..." );
+
+  if((ret = mbedtls_net_bind(&listen_fd, NULL, "443", MBEDTLS_NET_PROTO_TCP )) != 0)
+  {
+    mbedtls_printf( " failed\n  ! mbedtls_net_bind returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+
+  mbedtls_printf( " ok\r\n" );
+
+  // 3. Seed the RNG
+  mbedtls_printf( "  . Seeding the random number generator..." );
+  if((ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( (char *)pers))) != 0)
+  {
+    mbedtls_printf( " failed\r\n  ! mbedtls_ctr_drbg_seed returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+  mbedtls_printf( " ok\r\n" );
+
+  // 4. Setup stuff
+  mbedtls_printf( "  . Setting up the SSL data...." );
+  if( ( ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
+  {
+    mbedtls_printf( " failed\r\n  ! mbedtls_ssl_config_defaults returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+
+  mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
+
+  mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL);
+  if( ( ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey ) ) != 0)
+  {
+    mbedtls_printf( " failed\r\n  ! mbedtls_ssl_conf_own_cert returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+
+  if( ( ret = mbedtls_ssl_setup( &ssl, &conf ) ) != 0 )
+  {
+    mbedtls_printf( " failed\r\n  ! mbedtls_ssl_setup returned %d\r\n", ret );
+    ssl_state = SSL_CRITICAL_ERROR;
+  }
+  mbedtls_printf( " ok\r\n" );
+
+
+  for (;;) {
+  switch (ssl_state)
+  {
+    case SSL_ACCEPT :
+
+      mbedtls_ssl_session_reset( &ssl );
+      mbedtls_printf( "  . Waiting for a remote connection ...\r\n" );
+
+      if((ret = mbedtls_net_accept(&listen_fd, &client_fd, NULL, 0, NULL)) != 0) {
+        mbedtls_printf( " failed\r\n  ! mbedtls_net_accept returned %d\r\n", ret );
+        ssl_state = SSL_ERROR;
+      }
+      else {
+        mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );//mbedtls_net_recv
+        mbedtls_printf( " ok\r\n" );
+
+        ssl_state = SSL_HANDSHAKE;
+      }
+
+    break;
+
+    case SSL_HANDSHAKE :
+
+      mbedtls_printf( "  . Performing the SSL/TLS handshake..." );
+      while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
+      {
+        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+        {
+          mbedtls_printf( " failed\r\n  ! mbedtls_ssl_handshake returned %d\r\n", ret );
+          ssl_state = SSL_ERROR;
+          break;
+        }
+      }
+
+      if (ret != 0)
+        ssl_state = SSL_ERROR;
+      else {
+        mbedtls_printf( " ok\r\n" );
+        ssl_state = SSL_READ;
+      }
+
+    break;
+
+    case SSL_READ :
+      //printf("SSL_READ\r\n");
+      if (SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf) <= 0)
+        ssl_state = SSL_ERROR;
+      else
+        ssl_state = SSL_PROCESSING;
+    break;
+
+    case SSL_PROCESSING :
+      //printf("SSL_PROCESSING\r\n");
+      sendPtr = SSL_ProcessingRoutine(&sendBufLoadLen);
+      if (sendPtr)
+        ssl_state = SSL_WRITE;
+      else
+        ssl_state = SSL_ACCEPT;
+    break;
+
+    case SSL_WRITE :
+      //printf("SSL_WRITE\r\n");
+      SSL_WriteRoutine(&ssl, sendPtr, sendBufLoadLen);
+      ssl_state = SSL_CLOSE;
+    break;
+
+    case SSL_CLOSE :
+      //printf("SSL_CLOSE\r\n");
+      mbedtls_ssl_close_notify(&ssl);
+      mbedtls_net_free(&client_fd);
+      //mbedtls_ssl_free( &ssl );
+      ssl_state = SSL_ACCEPT;
+    break;
+
+    case SSL_ERROR :
+      //printf("SSL_ERROR\r\n");
+      //mbedtls_net_free(&client_fd);
+      //mbedtls_ssl_free( &ssl );
+      mbedtls_ssl_close_notify(&ssl);
+      mbedtls_net_free(&client_fd);
+      ssl_state = SSL_ACCEPT;
+    break;
+
+    case SSL_CRITICAL_ERROR:
+      //printf("SSL_CRITICAL_ERROR\r\n");
+      mbedtls_x509_crt_free( &srvcert );
+      mbedtls_pk_free( &pkey );
+      mbedtls_ssl_free( &ssl );
+      mbedtls_ssl_config_free( &conf );
+      mbedtls_ctr_drbg_free( &ctr_drbg );
+      mbedtls_entropy_free( &entropy );
+      vTaskDelete(NULL);
+    break;
+  }
+  }
+}
+
+
+/**
+  * @brief  Initialize the HTTPS server (start its thread)
+  */
+void HTTPS_Init()
+{
+  char buf[MAX_WEB_COOKIE_LEN];
+  uint8_t user_id;
+
+  for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
+    // Flush user cookie by random value
+    sprintf(buf, "%X", (unsigned int)GetRandomNumber());
+    HTTP_SetUserCookie(buf, user_id);
+    // Create user logout timers
+    users[user_id].LogoutTimer = xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback);
+  }
+  RepeatLoginTimer = xTimerCreate("LoginTmr", REPEAT_LOGIN_TIME, pdFALSE, ( void * ) 0, LoginTimerCallback);
+}
+
+//
+int SSL_ReadRoutine(mbedtls_ssl_context *ssl, unsigned char* recvBuf)
+{
+  int ret;
+
+  mbedtls_printf( "  < Read from client:" );
+  do
+  {
+    receivedBufLen = RECIVE_BUF_MAX_LEN - 1;
+    memset(recvBuf, 0, RECIVE_BUF_MAX_LEN);
+    ret = mbedtls_ssl_read(ssl, receiveBuf, receivedBufLen);
+
+    if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE )
+      continue;
+
+    if( ret <= 0 )
+    {
+      switch( ret )
+      {
+        case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
+          mbedtls_printf( " connection was closed gracefully\r\n" );
+          break;
+
+        case MBEDTLS_ERR_NET_CONN_RESET:
+          mbedtls_printf( " connection was reset by peer\r\n" );
+          break;
+
+        default:
+          mbedtls_printf( "mbedtls_ssl_read returned -0x%x\r\n", -ret );
+        break;
+      }
+      return ret;
+    }
+
+    receivedBufLen = ret;
+  } while(0);
+}
+
+//
+SSL_SERVER_STATE SSL_WriteRoutine(mbedtls_ssl_context *ssl, char *data, int datalen)
+{
+    return SSL_SendFrames(ssl, data, datalen);
+}
+
+//
+char* SSL_ProcessingRoutine(uint16_t* sendLen)
+{
+    Cockie();
+    getAuthenticatedState();
+
+    if ( Authenticated == false && sSettings.sRADIUS.Auth_enable == false)
+    {
+        HTTP_LOGIN(sendBuf, sendLen);
+        return sendBuf;
+    }
+    else if (!Authenticated)
+    {
+        return AuthenticatedFalseRoutine(sendLen);
+    }
+    else
+    {
+        return AuthenticatedTrueRoutine(sendLen);
+    }
+}
+
+//
+char* AuthenticatedFalseRoutine(uint16_t* sendLen)
+{
+    if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // +
+    {
+        fs_open("/main.css", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // +
+    {
+        fs_open("/rotek.png", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ?
+    {
+        fs_open("/favicon.ico", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /role.js", 12) == 0)
+    {
+        fs_open("/role.js", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "POST /login.cgi", 15) == 0)
+    {
+        uint32_t req_data_received = 0;
+        char *offset = 0;
+
+        post_data_count = Parse_Content_Length(receiveBuf, receivedBufLen);
+
+        if (post_data_count < MAX_POST_REQ_LEN)
+        {
+            memset(post_req_data, 0, MAX_POST_REQ_LEN);
+            offset = (strstr(receiveBuf, "\r\n\r\n")) + 4;
+            req_data_received = receivedBufLen - (offset - &receiveBuf[0]);
+
+            if (offset != 0)
+            {
+                if (req_data_received < post_data_count)
+                {
+                    snprintf(post_req_data, req_data_received, "%s", receiveBuf);
+                    post_data_count -= req_data_received;
+                    SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+                    offset = receiveBuf;
+                }
+                if(strlen(receiveBuf) != 0)
+                {
+                    strncat(post_req_data, offset, post_data_count);
+                    if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), sendLen) == SEND_REQUIRED_YES)
+                    {
+                    	post_data_count = 0;
+                        return sendBuf;
+                    }
+                    else
+                    {
+                    	post_data_count = 0;
+                        return sendBuf;
+                    }
+
+                }
+                else
+                {
+                    // Redirect to login page
+                    if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+                    fs_open("/rslogin.html", &file);
+                    else
+                    fs_open("/login.html", &file);
+
+                    post_data_count = 0;
+                    *sendLen = file.len;
+                    return file.data;
+                }
+            }
+            // request was fragmented before "\r\n\r\n"
+            else
+            {
+                // Redirect to login page
+                if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+                    fs_open("/rslogin.html", &file);
+                else
+                    fs_open("/login.html", &file);
+
+                post_data_count = 0;
+                *sendLen = file.len;
+                return file.data;
+            }
+        }
+        else
+        {
+            //printf("Too long POST request!\r\n");
+            // Ignore request
+            post_data_count = 0;
+            // Redirect to login page
+            if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+                fs_open("/rslogin.html", &file);
+            else
+                fs_open("/login.html", &file);
+
+            *sendLen = file.len;
+            return file.data;
+        }
+    }
+    else if (post_data_count > 0)
+    {
+        strncat(post_req_data, receiveBuf, post_data_count);
+        post_data_count = 0;
+        log_post_reqn = 0;
+
+        if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), sendLen) == SEND_REQUIRED_YES)
+        {
+            return sendBuf;
+        }
+        else
+        {
+            return sendBuf;
+        }
+    }
+    else
+    {
+        if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+            fs_open("/rslogin.html", &file);
+        else
+            fs_open("/login.html", &file);
+
+        *sendLen = file.len;
+        return file.data;
+    }
+}
+
+//
+char* AuthenticatedTrueRoutine(uint16_t* sendLen)
+{
+    char *DataOffset;
+    char *ptr;
+
+  /*  if (strncmp(receiveBuf, "GET /main.css", 13) == 0) // +
+    {
+        fs_open("/main.css", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /rotek.png", 14) == 0) // +
+    {
+        fs_open("/rotek.png", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /favicon.ico", 16) == 0) // ?
+    {
+        fs_open("/favicon.ico", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /main.js", 12) == 0) // +
+    {
+        fs_open("/main.js", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /role.js", 12) == 0)
+    {
+        fs_open("/role.js", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /settings.html", 18) == 0) // +
+    {
+        HTTP_UpdateUserLoginTime(user_id);
+        if (seclevel == 0)
+            fs_open("/settings.html", &file);
+        else
+            fs_open("/index.html", &file);
+
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /info.html", 14) == 0) // +
+    {
+        HTTP_UpdateUserLoginTime(user_id);
+        fs_open("/info.html", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /history.html", 17) == 0)
+    {
+        HTTP_UpdateUserLoginTime(user_id);
+        fs_open("/history.html", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else if (strncmp(receiveBuf, "GET /ups_history.html", 21) == 0)
+    {
+        HTTP_UpdateUserLoginTime(user_id);
+        fs_open("/ups_history.html", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    else*/ if (strncmp(receiveBuf, "GET /getJson.cgi", 16) == 0) // +
+    {
+        HTTP_GetParamsPage1(sendBuf);
+        *sendLen = strlen(sendBuf);
+        return sendBuf;
+    }
+    else if (strncmp(receiveBuf, "GET /settings.cgi", 17) == 0) // +
+    {
+        if (seclevel == 0) {
+            SET_PAGE = SET_PAGE_PAGE2;
+            if (HTTP_SettingsPage(receiveBuf, sendBuf, receivedBufLen, sendLen) == SEND_REQUIRED_YES)
+            {
+                *sendLen = strlen(sendBuf);
+                return sendBuf;
+            }
+        }
+        return 0;
+    }
+    else if (strncmp(receiveBuf, "POST /settings.cgi", 18) == 0)
+    {
+        if (seclevel == 0)
+        {
+            DataOffset = 0;
+            // POST Packet received
+            TotalReceived = 0;
+            TotalData = 0;
+            memset(sendBuf, 0, strlen(sendBuf));
+
+            // parse packet for Content-length field
+            size = Parse_Content_Length(receiveBuf, receivedBufLen);
+            DataOffset = strstr(receiveBuf, "managerIP");
+
+            /* case of MSIE8 : we do not receive data in the POST packet*/
+            if (DataOffset == 0)
+            {
+                //ssl_server_read();
+                SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+                DataOffset = strstr(receiveBuf, "managerIP");
+            }
+
+            TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]);
+            TotalData += TotalReceived;
+            strncat(sendBuf,  DataOffset, TotalReceived);
+
+            for (int i = TotalData; i < size; i ++)
+            {
+                //ssl_server_read();
+                SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+                strncat(sendBuf,  receiveBuf, receivedBufLen);
+                TotalData += receivedBufLen;
+            }
+            // check if last data packet
+            if (TotalData == size)
+            {
+                DBG printf("State: Received %d bytes\r\n", (int)TotalData);
+                //  printf("receive %s \r\n", sendBuf);
+                strncat(sendBuf,  " ", 1);
+                HTTP_SetSettings(sendBuf, strlen(sendBuf));
+                memset(sendBuf, 0, size);
+                strcpy(sendBuf, "HTTP/1.1 200 OK\r\n");
+                strcat(sendBuf, "\r\n\r\n");
+                strcat(sendBuf,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/settings.html\"/></head></html>\r\n\r\n");
+                sendBufLoadLen = strlen(sendBuf);
+                *sendLen = sendBufLoadLen;
+                return sendBuf;
+            }
+        }
+        return 0;
+    }
+    else if (strncmp(receiveBuf, "GET /getcert.cgi", 16) == 0)
+    {
+    	// Send HTTP header first (Safari needs it)
+    	memset(sendBuf, 0, sizeof(sendBuf));
+	    strcpy(sendBuf, HTTP_200_OK);
+        SSL_CreateReqCert();
+  	    strncpy(sendBuf, req_cert, strlen(req_cert));
+		*sendLen = strlen(sendBuf);
+		return sendBuf;
+    }
+    else if (strncmp(receiveBuf, "POST /srv_crt_upload.cgi", 24) == 0)
+    {
+        static char boundary[70];
+        static char *pbound = NULL;
+        char* ContentOffset = 0;
+        DataOffset = 0;
+        TotalData = 0;
+
+        memset(sendBuf, 0, sizeof(sendBuf));
+        //printf("receive %s \r\n", receiveBuf);
+        // parse packet for Content-length field
+        size = Parse_Content_Length(receiveBuf, receivedBufLen);
+        pbound = Parce_Boundary(receiveBuf, receivedBufLen, boundary, sizeof(boundary));
+        if (pbound != NULL)
+        {
+            ContentOffset = strstr(receiveBuf, boundary);
+            //ContentOffset += 4;
+            DataOffset = strstr(ContentOffset, "\r\n\r\n");
+            if( DataOffset != NULL )
+                DataOffset += 4;
+        }
+        // case of MSIE8 : we do not receive data in the POST packet
+        if (DataOffset == NULL)
+        {
+            SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+            receiveBuf[receivedBufLen] = '\0';
+            printf("receive2 %s \r\n", receiveBuf);
+            if (pbound != NULL)
+            {
+                ContentOffset = strstr(receiveBuf, boundary);
+                // ContentOffset += 4;
+                DataOffset = strstr(ContentOffset, "\r\n\r\n");
+                if( DataOffset != NULL )
+                    DataOffset += 4;
+            }
+        }
+
+        TotalReceived = receivedBufLen - (uint32_t)(ContentOffset - receiveBuf);
+        TotalData += TotalReceived;
+        strncat(sendBuf,  DataOffset, TotalReceived);
+
+        while(TotalData < size)
+        {
+            SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+            receiveBuf[receivedBufLen] = '\0';
+            //printf("receive3 %s \r\n", receiveBuf);
+            strncat(sendBuf,  receiveBuf, receivedBufLen);
+            TotalData += receivedBufLen;
+            //printf("TotalData %d \r\n", TotalData);
+            /*printf("receivedBufLen %d \r\n", receivedBufLen);
+            printf("TotalData %d \r\n", TotalData);
+            printf("size %d \r\n", size);
+            printf("receive3 %s \r\n", (receiveBuf+receivedBufLen - 30));*/
+        }
+        printf("TotalData %d \r\n", TotalData);
+        // check if last data packet
+        if (TotalData == size)
+        {
+            printf("receive %s \r\n", sendBuf);
+            if(strstr(sendBuf, "BEGIN CERTIFICATE") != NULL)
+            {
+                DataOffset = strstr(sendBuf, "-----END CERTIFICATE");
+                uint32_t len_crt = (uint32_t)(DataOffset - sendBuf) + 25;
+                memset(sSettings.our_srv_crt, 0, sizeof(sSettings.our_srv_crt));
+                memcpy(sSettings.our_srv_crt, sendBuf, len_crt);
+                strcat(sendBuf,  "\r\n");
+                HTTP_SaveSettings();
+                memset(sendBuf, 0, sizeof(sendBuf));
+                strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n");
+                strcat(sendBuf,"1");
+            }
+            else
+            {
+                memset(sendBuf, 0, sizeof(sendBuf));
+                strcpy(sendBuf, "HTTP/1.1 200 OK\r\n\r\n");
+                strcat(sendBuf,"Некорректный сертефикат");
+            }
+            *sendLen = strlen(sendBuf);
+            return sendBuf;
+        }
+    }
+    else if (strncmp(receiveBuf, "GET /info.cgi", 13) == 0) // +
+    {
+        if (HTTP_InfoPage(receiveBuf, sendBuf, receivedBufLen, sendLen) == SEND_REQUIRED_YES)
+        {
+            return sendBuf;
+        }
+    }
+    else if (strncmp(receiveBuf, "POST /info.cgi", 14) == 0)
+    {
+        if (seclevel == 0)
+        {
+            DataOffset = 0;
+            // POST Packet received
+            TotalReceived = 0;
+            TotalData = 0;
+            memset(sendBuf, 0, strlen(sendBuf));
+            // parse packet for Content-length field
+            size = Parse_Content_Length(receiveBuf, receivedBufLen);
+            DataOffset = strstr(receiveBuf, "owner");
+
+            // case of MSIE8 : we do not receive data in the POST packet
+            if (DataOffset == 0)
+            {
+                SSL_ReadRoutine(&ssl, (unsigned char*)receiveBuf);
+                DataOffset = strstr(receiveBuf, "owner");
+            }
+
+            TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]);
+            TotalData += TotalReceived;
+            strncat(sendBuf,  DataOffset, TotalReceived);
+
+            // check if last data packet
+            if (TotalReceived == size)
+            {
+                strncat(sendBuf,  " ", 1);
+                HTTP_SetInfo(sendBuf, strlen(sendBuf));
+                DataFlag = 0;
+                BrowserFlag = 0;
+                memset(sendBuf, 0, size);
+
+                strcpy(sendBuf, "HTTP/1.1 200 OK\r\n");
+                strcat(sendBuf, "\r\n\r\n");
+                strcat(sendBuf,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/info.html\"/></head></html>\r\n\r\n");
+
+                *sendLen = strlen(sendBuf);
+                return sendBuf;
+            }
+            // not last data packet
+            else
+            {
+                // write data in flash
+                if(receivedBufLen)
+                {
+                    strncat(sendBuf,  ptr, receivedBufLen);
+                    //memcpy(receiveBufTemp, ptr, receivedBufLen);
+                }
+            }
+        }
+    }
+    else if (strncmp(receiveBuf, "GET /history.cgi", 16) == 0)
+    {
+        int res;
+        res = HTTP_HistoryPage(receiveBuf, sendBuf, receivedBufLen, sendLen);
+
+        if (res == SEND_REQUIRED_FILE)
+        {
+            if (SSL_SendFrames(&ssl, sendBuf, sendBufLoadLen) == SSL_ERROR)
+                return 0;
+
+            HTTP_SendHistory();
+            return 0;
+        }
+        else if (res == SEND_REQUIRED_YES)
+        {
+            return sendBuf;
+        }
+    }
+    else if (strncmp(receiveBuf, "GET /ups_history.cgi", 19) == 0)
+    {
+        int res;
+
+        res = HTTP_UpsHistoryPage(receiveBuf, sendBuf, receivedBufLen, sendLen);
+
+        if (res == SEND_REQUIRED_FILE)
+        {
+            if (SSL_SendFrames(&ssl, sendBuf, sendBufLoadLen) == SSL_ERROR)
+                return 0;
+
+            HTTP_SendLog();
+            return 0;
+        }
+        else if (res == SEND_REQUIRED_YES)
+        {
+            return sendBuf;
+        }
+    }
+    /* Тест  АКБ ИБП */
+    else if (strncmp(receiveBuf, "GET /bat_test.cgi", 17) == 0)
+    {
+        HTTP_UPSTest(receiveBuf, sendBuf, receivedBufLen, sendLen);
+        return sendBuf;
+    }
+    /* Выключение ИБП */
+    else if (strncmp(receiveBuf, "GET /ups_power.cgi", 18) == 0)
+    {
+        HTTP_UPSshutdown(receiveBuf, sendBuf, receivedBufLen, sendLen);
+        return sendBuf;
+    }
+    /* Сброс настроек и сохранине */
+    else if (strncmp(receiveBuf, "GET /reset.cgi", 14) == 0)
+    {
+        HTTP_ResetSettings();
+        HTTP_SaveSettings();
+
+        fs_open("/settings.html", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    /* Перезагрузка контроллера */
+    else if (strncmp(receiveBuf, "GET /reboot.cgi", 15) == 0)
+    {
+        HTTP_Reboot();
+    }
+    /* Подтверждение новых сетевых настроек */
+    else if (strncmp(receiveBuf, "GET /confirm.cgi", 16) == 0)
+    {
+        SetWebReinitFlag(false);
+        SetConfirmWebParamsFlag();
+
+        fs_open("/index.html", &file);
+        *sendLen = file.len;
+        return file.data;
+    }
+    /* Проверка пароля, переход в bootloader */
+    else if (strncmp(receiveBuf, "GET /fw_update.cgi", 18) == 0)
+    {
+        HTTP_ConfirmBootPwd(receiveBuf, sendBuf, receivedBufLen, sendLen);
+        return sendBuf;
+    }
+    /* Смена пароля пользователя */
+    else if (strncmp(receiveBuf, "GET /changepwd.cgi", 18) == 0)
+    {
+        HTTP_ChangeUserPwd(receiveBuf, sendBuf, receivedBufLen, sendLen);
+        return sendBuf;
+    }
+    // На производстве
+    else if (strncmp(receiveBuf, "GET /setProdate.cgi", 19) == 0)
+    {
+        HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, sendLen);
+        return sendBuf;
+    }
+    /* Check common GET request */
+	  else if (strncmp(receiveBuf, "GET", 3) == 0) {
+		  char filename[MAX_FILENAME_LEN];
+		  char nonmatch[MAX_ETAG_LEN];
+		  char *pnonmatch = NULL;
+		  uint8_t len;
+
+		  if (GetFileName(receiveBuf, filename, &len)) {
+			  HTTP_UpdateUserLoginTime(user_id);
+
+			  /* Parce If-Non_Match value */
+			  uint8_t nonmatch_len = Parse_Header(receiveBuf, receivedBufLen, If_None_Match, 15, nonmatch);
+			  if (nonmatch_len < MAX_ETAG_LEN && nonmatch_len > 0) {
+				  DBG printf("If_None_Match: %s\r\n", nonmatch);
+				  pnonmatch = nonmatch;
+			  }
+			  return send_file(filename, pnonmatch, &file, sendLen);
+		  }
+	  }
+    else
+    {
+        HTTP_UpdateUserLoginTime(user_id);
+        fs_open("/index.html", &file); // +
+        *sendLen = file.len;
+        return file.data;
+    }
+
+    return 0;
+}
+
+
+#define FRAME_SIZE   (1000)
+SSL_SERVER_STATE SSL_SendFrames(mbedtls_ssl_context *ssl, char *data, int datalen)
+{
+  SSL_SERVER_STATE ret;
+  int retClose;
+  int index = 0;
+  int k = 0;
+  int lastframe, nbrframes;
+
+  nbrframes = datalen / FRAME_SIZE;
+
+  while(nbrframes > 0)
+  {
+    index = k * FRAME_SIZE;
+
+    if (SSL_Write(ssl, (data + index), FRAME_SIZE ) == SSL_WRITE_ERROR)
+      return SSL_WRITE_ERROR;
+
+    nbrframes--;
+    k++;
+  }
+
+  index = k * FRAME_SIZE;
+  lastframe = datalen % FRAME_SIZE ;
+  if (SSL_Write(ssl, (data + index), lastframe ) == SSL_WRITE_ERROR)
+      return SSL_WRITE_ERROR;
+
+  return SSL_WRITE_OK;
+}
+
+SSL_SERVER_STATE SSL_Write(mbedtls_ssl_context *ssl, char *data, int datalen)
+{
+  int ret;
+
+  mbedtls_printf( "  > Write to client:" );
+
+  while( ( ret = mbedtls_ssl_write(ssl, data, datalen) ) <= 0 )
+  {
+    if( ret == MBEDTLS_ERR_NET_CONN_RESET )
+    {
+      mbedtls_printf( " failed\r\n  ! peer closed the connection\r\n" );
+      return SSL_WRITE_ERROR;
+    }
+
+    if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
+    {
+      mbedtls_printf( " failed\r\n  ! mbedtls_ssl_write returned %d\r\n", ret );
+      return SSL_WRITE_ERROR;
+    }
+  }
+
+  mbedtls_printf( " %d bytes written\r\n", ret);
+  return SSL_WRITE_OK;
+}
+
+/**
+  * @brief Send callback for log file transfer (messages as is, not ordered)
+  */
+void HTTP_SendHistory(void)
+{
+    uint32_t nbytes = 0;
+    static bool start = true;
+
+    memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
+
+    if (log_ptr + FILE_BUF_MAX_LEN <= log_size) {
+        nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start);
+    }
+    else if (log_ptr < log_size) {
+        nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
+    }
+    else {
+        nbytes = 0;
+    }
+    log_ptr += nbytes;
+
+    start = false;
+
+    if (nbytes == 0) {
+        // File transfer finished.
+        start = true;
+        // Clear file transfer in progress flag
+        fLogTransInprog = false;
+        return;
+    }
+
+    SSL_SendFrames(&ssl, logFileBuf, nbytes);
+    HTTP_SendHistory();
+}
+
+/**
+  * @brief Sent callback for log file transfer (messages as is, not ordered)
+  */
+void HTTP_SendLog(void)
+{
+    uint32_t nbytes = 0;
+    static bool start = true;
+
+	memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
+    if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) {
+        nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start);
+    }
+    else if (log_ptr < log_size) {
+        nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
+    }
+    else {
+        nbytes = 0;
+    }
+    log_ptr += nbytes;
+
+    start = false;
+    if (nbytes == 0) {
+        // File transfer finished.
+        start = true;
+        // Clear file transfer in progress flag
+        fLogTransInprog = false;
+        return;
+    }
+
+    SSL_SendFrames(&ssl, logFileBuf, nbytes);
+    HTTP_SendLog();
+
+    return;
+}
+
+/**
+  * @brief  sends file from flash FS
+  * @param  filename: pointer to the file name to send
+  * @param  pnonmatch: pointer to the If-Non_Match value
+  * @param  pcb: pointer to a tcp_pcb struct
+  * @param  hs: pointer to a http_state struct
+  * @param  file: pointer to a fs_file struct
+  * @retval
+  */
+char* send_file(char *filename, char *pnonmatch,  struct fs_file *file, uint16_t *Len)
+{
+    int res = 0;
+    char etag[MAX_ETAG_LEN];
+    char *petag = NULL;
+
+    res = fs_open(filename, file);
+
+    if (res == 0) {
+        printf("Not found: %s\r\n", filename);
+        sprintf(filename, "/index.html");
+        fs_open(filename, file);
+    }
+
+    /* Find Etag value */
+    uint8_t etag_len = Parse_Header(file->data, file->len, Etag, 6, etag);
+    if (etag_len < MAX_ETAG_LEN && etag_len > 0) {
+        DBG printf("Etag: %s\r\n", etag);
+        petag = etag;
+    }
+
+    /* Compare Etag and If-Non-Match fields */
+    if (pnonmatch && petag && (strcmp(pnonmatch, petag) == 0)) {
+        /* Send 304 code */
+        sprintf(sendBuf, HTTP_304_NOT_MODIFIED);
+        DBG printf(sendBuf);
+        *Len = strlen(sendBuf);
+        return sendBuf;
+        //hs->file = sendBuf;
+        //hs->left = strlen(sendBuf);
+    }
+    else {
+        /* Send file */
+        //DBG printf("%s\r\n\r\n", filename);
+        //hs->file = file->data;
+        //hs->left = file->len;
+    	*Len = file->len;
+    	return file->data;
+    }
+
+    //send_data(pcb, hs);
+    //tcp_sent(pcb, http_sent);
+}
+
+/**
+  * @brief  Extract the custom field data from HTML data
+  * @param  data : pointer on receive packet buffer
+  * @param  len  : buffer length
+  * @param  field : field name
+  * @param  flen : field name length
+  * @retval value : pointer for field data
+  */
+static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value)
+{
+    uint32_t i = 0, size = 0;
+    char *ptr;
+    uint32_t Offset = 0;
+
+    /* Find field name in data buffer */
+    for (i = 0; i < len; i++) {
+        if (strncmp ((char*)(data + i), field, flen) == 0) {
+            Offset = i + flen;
+            break;
+        }
+    }
+    /* Copy Field value */
+    if (Offset) {
+        i = 0;
+        ptr = (char*)(data + Offset);
+        while (*(ptr + i) != 0x0d) {
+            value[i] = *(ptr + i);
+            i++;
+        }
+        value[i] = '\0';
+        size = i;
+    }
+    return size;
+}
+/**
+  * @brief
+  * @retval None
+  */
+bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen)
+{
+  char *beginValue = NULL;
+  char *endValue = NULL;
+  int  len = 0;
+  char *strPtr = NULL;
+
+  strPtr = strstr(inStr, "GET");
+  if (strPtr == NULL) {
+      strPtr = strstr(inStr, "POST");
+  }
+
+  if (strPtr == NULL) {
+      *fileNameLen = 0;
+      return false;
+  }
+  else {
+    beginValue = strpbrk(strPtr, "/");
+
+    endValue = strpbrk(beginValue, " ");
+    if (endValue == NULL) {
+        *fileNameLen = 0;
+        return false;
+    }
+    len = endValue - beginValue;
+    if (len < MAX_FILENAME_LEN) {
+        strncpy(fileName, beginValue, len);
+        *fileNameLen = len;
+        fileName[len] = '\0';
+        return true;
+    }
+    else {
+        return false;
+    }
+  }
+}
+
+
+#endif
+
+
+

+ 199 - 0
modules/HTTP_Server/my_ssl_server.h

@@ -0,0 +1,199 @@
+/*
+ * ssl_server.h
+ *
+ *  Created on: 08.11.2017
+ *      Author: balbekova
+ */
+#ifdef HARDWARE_BT6702
+
+#ifndef MY_SSL_SERVER_H_
+#define MY_SSL_SERVER_H_
+
+
+#include "lwip/opt.h"
+#include "lwip/arch.h"
+#include "lwip/api.h"
+
+#include "mbedtls/ssl.h"
+
+#define SSL_TASK_PRIO   ( configMAX_PRIORITIES - 3 )
+#define FRAME_SIZE      (1000)
+
+typedef enum
+{
+  SSL_ACCEPT = 0,
+  SSL_ERROR,
+  SSL_CRITICAL_ERROR,
+  SSL_HANDSHAKE,
+  SSL_READ,
+  SSL_PROCESSING,
+  SSL_CLOSE,
+  SSL_WRITE,
+  SSL_WRITE_OK,
+  SSL_WRITE_ERROR,
+
+} SSL_SERVER_STATE;
+
+typedef enum
+{
+  SET_PAGE_IDLE = 0,
+  SET_PAGE_PAGE1,
+  SET_PAGE_PAGE2,
+  SET_PAGE_PAGE3,
+  SET_PAGE_PAGE4,
+} SET_PAGE_t;
+
+typedef enum
+{
+  SEND_REQUIRED_YES = 0,
+  SEND_REQUIRED_NO,
+  SEND_REQUIRED_FILE
+} REQ_TYPE_t;
+
+struct http_state
+{
+  char *file;
+  u32_t left;
+};
+
+struct fs_file {
+  char *data;
+  int len;
+};
+
+void HTTP_Init();
+
+static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err);
+static err_t http_recv(void *arg, struct tcp_pcb *pcb,  struct pbuf *p, err_t err);
+
+
+
+
+void http_server_netconn_init();
+
+/**
+  * @brief  Выводим запросы в консоль
+  */
+void vTaskPrintHttp(void *pvParameters);
+
+/**
+  * @brief  Установка даты производства
+  */
+void HTTP_Prodate(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief  Парсинг строки настроек
+  */
+void HTTP_SetSettings(char *buf, uint16_t lenBuf);
+
+/**
+  * @brief
+  */
+void HTTP_SetInfo(char *buf, uint16_t lenBuf);
+
+/**
+  * @brief
+  */
+int HTTP_SettingsPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief
+  */
+int HTTP_InfoPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+
+int HTTP_UpsHistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+int HTTP_HistoryPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief  Запуск/останов теста UPS
+  */
+void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief  Выклюение UPS
+  */
+void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief  Проверка пароля для перехода в режим bootloader
+  */
+void HTTP_ConfirmBootPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+/**
+  * @brief  Проверка пароля для входа в Web
+  */
+int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
+
+void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut);
+
+/**
+  * @brief
+  */
+uint8_t GetParamValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen);
+
+uint8_t GetCookieValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen);
+
+/**
+  * @brief
+  * @retval None
+  */
+uint8_t GetParamValueInEnd(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen);
+
+void ClearParamString(char *inBuf);
+
+/**
+  * @brief  Замена символа в строке
+  * @param  *str - входная строка
+  * @param  sim1 - символ который надо заменить
+  * @param  sim2 - символ на который надо заменить
+  */
+void HTTP_ReplaceSimbol(char *str, char sim1, char sim2);
+
+
+// -----------------------------------------------------------------------------
+//
+//
+//  SSL тесты
+//
+//
+// -----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* Exported types ------------------------------------------------------------*/
+typedef struct
+{
+  uint32_t State;
+}rng_state;
+
+void Cockie(void);
+void getAuthenticatedState(void);
+void ssl_server(void *pvParameters);
+
+
+int RandVal(void* arg);
+void HTTP_SendHistory(void);
+void HTTP_SendLog(void);
+void HTTPS_Init();
+int SSL_ReadRoutine(mbedtls_ssl_context *ssl, unsigned char* recvBuf);
+char* SSL_ProcessingRoutine(uint16_t* sendLen);
+SSL_SERVER_STATE SSL_WriteRoutine(mbedtls_ssl_context *ssl, char *data, int datalen);
+char* AuthenticatedFalseRoutine(uint16_t* sendLen);
+char* AuthenticatedTrueRoutine(uint16_t* sendLen);
+SSL_SERVER_STATE SSL_SendFrames(mbedtls_ssl_context *ssl, char *data, int datalen);
+SSL_SERVER_STATE SSL_Write(mbedtls_ssl_context *ssl, char *data, int datalen);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+#endif /* SSL_SERVER_H_ */
+#endif

+ 13 - 1
modules/HTTP_Server/web_params_api.c

@@ -95,7 +95,13 @@ void HTTP_GetParamsPage1(char *buf)
   GetDOUTStatusStr(str, &len, 1);
   strcat(buf, "\",\"ro2\":\"");
   strncat(buf, str, len);
-  
+
+#ifdef HARDWARE_BT6706
+  GetDOUTStatusStr(str, &len, 2);
+  strcat(buf, "\",\"ro3\":\"");
+  strncat(buf, str, len);
+#endif
+
   // Дополнительные параметры
 
     // Мониторинг
@@ -174,6 +180,12 @@ void HTTP_GetSettings(char *buf)
   GetROTypeActStr(str, &len, 1);
   strcat(buf, "\",\"ro2\":\"");
   strncat(buf, str, len);
+
+#ifdef HARDWARE_BT6706
+  GetROTypeActStr(str, &len, 2);
+  strcat(buf, "\",\"ro3\":\"");
+  strncat(buf, str, len);
+#endif
 	
   /* WEB */
   GetIpStr(str, &len);  

+ 12 - 3
modules/Makefile

@@ -19,6 +19,8 @@ endif
 
 CFLAGS += -DPRINTF_$(shell echo $(PRINTF) | tr a-z A-Z)
 
+CFLAGS += -DHARDWARE_$(shell echo $(HARDWARE) | tr a-z A-Z)
+
 INCLUDES = -I../config
 INCLUDES += -I../stm32/stm32f4xx_spl/inc 
 INCLUDES += -I../stm32/system
@@ -60,7 +62,6 @@ CSRC += $(wildcard radius/*.c)
 CSRC += $(wildcard mbedtls_api/*.c)
 
 CFLAGS += -DOS_FREERTOS
-CFLAGS += -DHARDWARE_$(shell echo $(HARDWARE) | tr a-z A-Z)
 
 #FreeRTOS
 LDSCRIPT := startup/stm32_flash.ld
@@ -88,7 +89,8 @@ CSRC += $(wildcard ../thirdparty/FreeRTOS/portable/MemMang/heap_4.c)
     INCLUDES += -IEthernet
  # INCLUDES += -I../stm32/stm32f4x7_ethernet 
  	INCLUDES += -ISTM32F4x7_ETH_Driver
-    CSRC += $(wildcard HTTP_Server/http_server.c)
+   CSRC += $(wildcard HTTP_Server/http_server.c)
+    CSRC += $(wildcard HTTP_Server/my_ssl_server.c)
     CSRC += $(wildcard HTTP_Server/trap_params.c)
     CSRC += $(wildcard HTTP_Server/web_params_api.c)
     CSRC += $(wildcard ../thirdparty/lwip/src/*.c)
@@ -136,7 +138,14 @@ FW_NAME = BT_6702xx
 -include ../Makefile.inc.stm32
 
 #Building Web UI FS
-WUI_DIR = ../web_interface/dist/wui
+ifeq ($(HARDWARE), bt6706)
+	WUI_DIR = ../web_interface/dist/wui-6
+endif
+
+ifeq ($(HARDWARE), bt6702)
+	WUI_DIR = ../web_interface/dist/wui
+endif
+
 FSDATA_DIR = ./HTTP_Server
 
 $(FSDATA_DIR)/fsdata.c: $(WUI_DIR)/*

+ 15 - 13
modules/MegaTec/megatec.c

@@ -320,20 +320,22 @@ void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
 
 int ups_metac_service_pdu(cmdMegaTecEnums_t command)
 {
-	while(!megatec_send)
-	{
-		vTaskDelay(50);
-	}
-	megatec_send = false;
-	send_MegaTec_cmd(command);
-	if (ups_megatec_rx_pdu())
-	{
-		megatec_send = true;
-		if(strncmp(ups_pdu.data, "ACK", 3) == 0)
-			return 1;
-		else if(strncmp(ups_pdu.data, "NCK", 3) == 0)
-			return 0;
+	if(UPS.Present){
+		while(!megatec_send)
+		{
+			vTaskDelay(50);
+		}
+		megatec_send = false;
+		send_MegaTec_cmd(command);
+		if (ups_megatec_rx_pdu())
+		{
+			megatec_send = true;
+			if(strncmp(ups_pdu.data, "ACK", 3) == 0)
+				return 1;
+			else if(strncmp(ups_pdu.data, "NCK", 3) == 0)
+				return 0;
 
+		}
 	}
 	return -1;
 }

+ 4 - 0
modules/log/log.c

@@ -27,6 +27,10 @@ const char* logsStrShortRu[] =
     "Авария дискр. входа 1",
     "Состояние выхода 1",
     "Состояние выхода 2",
+#ifdef HARDWARE_BT6706
+    "Состояние выхода 3",
+    "Авария вых. напряжения",
+#endif
     "Авария температуры",
     "Авария вх. напряжения",
     "Низкий заряд АКБ",

+ 4 - 0
modules/log/log.h

@@ -25,6 +25,10 @@ typedef __packed enum {
 	LOG_ALARM_DIO,
 	LOG_DO0_STATE,
 	LOG_DO1_STATE,
+#ifdef HARDWARE_BT6706
+	LOG_DO2_STATE,
+	LOG_ALARM_VAC_OUTPUT,
+#endif
 	LOG_ALARM_TEMP,
 	LOG_ALARM_LINE,
 	LOG_ALARM_LOW_BAT,

+ 287 - 159
modules/monitor/ups_monitor.c

@@ -32,6 +32,9 @@
 #define UPS_TEMPERATURE         40.0    // Температура (граница)
 #define UPS_TEMPERATURE_HIST    1.0     // Гистерезис температуры 
 
+#define UPS_VAC_OUTPUT          150.0    // Выходного напряжения (граница)
+#define UPS_VAC_OUTPUT_HIST     20.0     // Гистерезис Выходного напряжения
+
 
 bool flCriticalAlarm = false;
 bool flNonCriticalAlarm = false;
@@ -58,6 +61,9 @@ void UPS_Monitor(void *params)
    if (UPS.Present)
     {
       UPS_LineFailMonitor();
+#ifdef HARDWARE_BT6706
+      UPS_VACoutputMonitor();
+#endif
       UPS_LowBatMonitor();  
       UPS_PowerMonitor();
       UPS_TemperatureMonitor();
@@ -65,9 +71,10 @@ void UPS_Monitor(void *params)
     }
     UPS_ConnectMonitor();
     UPS_DI0Monitor();
-
+#ifdef HARDWARE_BT6702
     UPS_CriticalAlarmMonitor();
     UPS_NonCriticalAlarmMonitor();
+#endif
       
     vTaskDelay(1000);
   }
@@ -120,6 +127,65 @@ void UPS_DI0Monitor(void)
 	DI0OldState = DI0StateCurrent;
 }
 
+void relay_setup_log(uint8_t *curr_source, ro_type_source_t src_act_ro, uint8_t state_relay)
+{
+	uint8_t i = 0;
+
+	flUpdateLog = true;
+	for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+		if(curr_source[i] == src_act_ro){
+			  SetROInt(state_relay, i);
+			  SNMP_SendUserTrap((DO0_TOGGLED+i));
+			  if(state_relay){
+#ifdef HARDWARE_BT6706
+				  log_event_data((LOG_DO0_STATE + i), "Разомкнуто");
+#elif HARDWARE_BT6702
+				  log_event_data((LOG_DO0_STATE + i), "Замкнуто");
+#endif
+
+			  }
+			  else{
+#ifdef HARDWARE_BT6706
+				  log_event_data((LOG_DO0_STATE + i), "Замкнуто");
+#elif HARDWARE_BT6702
+				  log_event_data((LOG_DO0_STATE + i), "Разомкнуто");
+#endif
+			  }
+		}
+	}
+}
+
+void relay_setup_log_change(uint8_t *curr_source, uint8_t *prev_source, ro_type_source_t src_act_ro, uint8_t state_relay)
+{
+	uint8_t i = 0;
+
+	flUpdateLog = true;
+	for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+		if(get_state_din_outs(DOUT1 + i)){
+			if(curr_source[i] != prev_source[i] && (prev_source[i] == src_act_ro || curr_source[i] == src_act_ro)){
+				  SetROInt(state_relay, i);
+				  SNMP_SendUserTrap((DO0_TOGGLED+i));
+				  if(state_relay){
+#ifdef HARDWARE_BT6706
+					  log_event_data((LOG_DO0_STATE + i), "Разомкнуто");
+#elif HARDWARE_BT6702
+					  log_event_data((LOG_DO0_STATE + i), "Замкнуто");
+#endif
+
+				  }
+				  else{
+#ifdef HARDWARE_BT6706
+					  log_event_data((LOG_DO0_STATE + i), "Замкнуто");
+#elif HARDWARE_BT6702
+					  log_event_data((LOG_DO0_STATE + i), "Разомкнуто");
+#endif
+				  }
+			}
+		}
+	}
+}
+
+#ifdef HARDWARE_BT6702
 /**
   * @brief  Мониторинг бита CriticalAlarm
   */
@@ -128,37 +194,23 @@ void UPS_CriticalAlarmMonitor(void)
   static bool isValueRecv = false;
   static uint8_t CriticalAlarmOldState = 0;
   uint8_t CriticalAlarmCurrent;
-  static uint8_t OldRO0type_Sourse = 0;
-  static uint8_t OldRO2type_Sourse = 0;
-  uint8_t CurrRO2type_Sourse = 0;
-  uint8_t CurrRO1type_Sourse = 0;
-  char str[30];
+  uint8_t i = 0;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
 
-  memset(str, 0, 30);
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
 
-  CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
-  CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
   CriticalAlarmCurrent = flCriticalAlarm;
 
   if (!isValueRecv) {
 	isValueRecv = true;
 	CriticalAlarmOldState = CriticalAlarmCurrent;
-	OldRO0type_Sourse = CurrRO1type_Sourse;
-	OldRO2type_Sourse = CurrRO2type_Sourse;
-	if(OldRO0type_Sourse == CRITICAL){
-	  if(CriticalAlarmCurrent){
-		  SetROInt(1, 0);
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, "Замкнуто");
-	  }
-    }
-	  if(OldRO2type_Sourse == CRITICAL){
-		  if(CriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  SNMP_SendUserTrap(DO1_TOGGLED);
-			  log_event_data(LOG_DO1_STATE, "Замкнуто");
-		  }
-	  }
+	for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+		OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+	if(CriticalAlarmCurrent){
+	  relay_setup_log(CurrROtype_Sourse, CRITICAL, 1);
+	}
 	return;
   }
 
@@ -175,65 +227,25 @@ void UPS_CriticalAlarmMonitor(void)
   // Значение параметра изменилось
   if (CriticalAlarmCurrent != CriticalAlarmOldState)
   {
-	  if(CurrRO1type_Sourse == CRITICAL){
-		  memset(str, 0, 30);
-		  if(CriticalAlarmCurrent){
-			  SetROInt(1, 0);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 0);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, str);
+	  if(CriticalAlarmCurrent){
+		  relay_setup_log(CurrROtype_Sourse, CRITICAL, 1);
 	  }
-	  if(CurrRO2type_Sourse == CRITICAL){
-		  memset(str, 0, 30);
-		  if(CriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 1);
-			  strcat(str, "Разомкнуто");
-		  }
-	  	  SNMP_SendUserTrap(DO1_TOGGLED);
-	  	log_event_data(LOG_DO1_STATE, str);
+	  else{
+		  relay_setup_log(CurrROtype_Sourse, CRITICAL, 0);
 	  }
   }
   else
   {
-	  if(CurrRO1type_Sourse == CRITICAL && CurrRO1type_Sourse != OldRO0type_Sourse){
-		  memset(str, 0, 30);
-		  if(CriticalAlarmCurrent){
-			  SetROInt(1, 0);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 0);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, str);
-	  }
-	  if(CurrRO2type_Sourse == CRITICAL && CurrRO2type_Sourse != OldRO2type_Sourse){
-		  memset(str, 0, 30);
-		  if(CriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 1);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO1_TOGGLED);
-		  log_event_data(LOG_DO1_STATE, str);
-	  }
+	  if(CriticalAlarmCurrent)
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CRITICAL, 1);
+	  else
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CRITICAL, 0);
+
   }
 
-  OldRO0type_Sourse = CurrRO1type_Sourse;
-  OldRO2type_Sourse = CurrRO2type_Sourse;
+	for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+	}
   CriticalAlarmOldState = CriticalAlarmCurrent;
 }
 
@@ -245,126 +257,89 @@ void UPS_NonCriticalAlarmMonitor(void)
   static bool isValueRecv = false;
   static uint8_t NonCriticalAlarmOldState = 0;
   uint8_t NonCriticalAlarmCurrent;
-  static uint8_t OldRO0type_Sourse = 0;
-  static uint8_t OldRO2type_Sourse = 0;
-  uint8_t CurrRO2type_Sourse = 0;
-  uint8_t CurrRO1type_Sourse = 0;
-  char str[30];
-  memset(str, 0, 30);
-
-  CurrRO1type_Sourse = sSettings.sInOuts.ro_type_source[0];
-  CurrRO2type_Sourse = sSettings.sInOuts.ro_type_source[1];
+  uint8_t i = 0;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
+
   NonCriticalAlarmCurrent = flNonCriticalAlarm;
 
   if (!isValueRecv) {
 	isValueRecv = true;
 	NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
-	OldRO0type_Sourse = CurrRO1type_Sourse;
-	OldRO2type_Sourse = CurrRO2type_Sourse;
-	if(OldRO0type_Sourse == NON_CRITICAL){
-	  if(NonCriticalAlarmCurrent){
-		  SetROInt(1, 0);
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, "Замкнуто");
-	  }
-	}
-	  if(OldRO2type_Sourse == NON_CRITICAL){
-		  if(NonCriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  SNMP_SendUserTrap(DO1_TOGGLED);
-			 log_event_data(LOG_DO1_STATE, "Замкнуто");
-		  }
-	  }
+	 for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+		 OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+	  if(NonCriticalAlarmCurrent)
+		  relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 1);
+
 	return;
   }
 
   // Значение параметра изменилось
   if (NonCriticalAlarmCurrent != NonCriticalAlarmOldState)
   {
-	  if(CurrRO1type_Sourse == NON_CRITICAL){
-		  memset(str, 0, 30);
-		  if(NonCriticalAlarmCurrent){
-			  SetROInt(1, 0);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 0);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, str);
+	  if(NonCriticalAlarmCurrent){
+		  relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 1);
 	  }
-	  if(CurrRO2type_Sourse == NON_CRITICAL){
-		  memset(str, 0, 30);
-		  if(NonCriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 1);
-			  strcat(str, "Разомкнуто");
-		  }
-	  	  SNMP_SendUserTrap(DO1_TOGGLED);
-	  	log_event_data(LOG_DO1_STATE, str);
+	  else{
+		  relay_setup_log(CurrROtype_Sourse, NON_CRITICAL, 0);
 	  }
   }
   else
   {
-	  if(CurrRO1type_Sourse == NON_CRITICAL && CurrRO1type_Sourse != OldRO0type_Sourse){
-		  memset(str, 0, 30);
-		  if(NonCriticalAlarmCurrent){
-			  SetROInt(1, 0);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 0);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO0_TOGGLED);
-		  log_event_data(LOG_DO0_STATE, str);
-	  }
-	  if(CurrRO2type_Sourse == NON_CRITICAL && CurrRO2type_Sourse != OldRO2type_Sourse){
-		  memset(str, 0, 30);
-		  if(NonCriticalAlarmCurrent){
-			  SetROInt(1, 1);
-			  strcat(str, "Замкнуто");
-		  }
-		  else{
-			  SetROInt(0, 1);
-			  strcat(str, "Разомкнуто");
-		  }
-		  SNMP_SendUserTrap(DO1_TOGGLED);
-		  log_event_data(LOG_DO1_STATE, str);
-	  }
+	  if(NonCriticalAlarmCurrent)
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CRITICAL, 1);
+	  else
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CRITICAL, 0);
   }
 
-  OldRO0type_Sourse = CurrRO1type_Sourse;
-  OldRO2type_Sourse = CurrRO2type_Sourse;
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+  	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+  }
   NonCriticalAlarmOldState = NonCriticalAlarmCurrent;
 }
+#endif
 
 /**
   * @brief  Мониторинг бита LainFail
   */
 void UPS_LineFailMonitor(void)
 {
+
   static bool isValueRecv = false;
   static uint8_t lineFailOldState = 0;
   uint8_t lineFailCurrent;
-  
+
+#ifdef HARDWARE_BT6706
+  uint8_t i = 0;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
+#endif
+
   lineFailCurrent = (UPS.Status >> 7) & 0x01;
   
   if (!isValueRecv) {
     isValueRecv = true;
     lineFailOldState = lineFailCurrent;
+
     if (lineFailCurrent){
     	log_event_data(LOG_ALARM_LINE, "Авария");
           SNMP_SendUserTrap(LINE_ALARM);
           flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+    	relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 1);
+#endif
     }
+
     return;
   }
 
+
   if (lineFailCurrent)
 	  flCriticalAlarm = true;
     
@@ -372,20 +347,112 @@ void UPS_LineFailMonitor(void)
   if (lineFailCurrent != lineFailOldState)
   {
     if (lineFailCurrent){
-      log_event_data(LOG_ALARM_LINE, "Авария");
-      SNMP_SendUserTrap(LINE_ALARM);
-      flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+    	relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 1);
+#endif
+
+    	log_event_data(LOG_ALARM_LINE, "Авария");
+    	SNMP_SendUserTrap(LINE_ALARM);
+    	flUpdateLog = true;
     }
     else{
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, AC_PRESENT, 0);
+#endif
       log_event_data(LOG_ALARM_LINE, "Норма");
       SNMP_SendUserTrap(LINE_NORM);
       flUpdateLog = true;
     }
   }
-  
+
+#ifdef HARDWARE_BT6706
+  else{
+	  if (lineFailCurrent)
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, AC_PRESENT, 1);
+	  else
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, AC_PRESENT, 0);
+  }
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+  }
+#endif
+
   lineFailOldState = lineFailCurrent;
 }
 
+#ifdef HARDWARE_BT6706
+/**
+  * @brief  Мониторинг аварии выходного напряжения
+  */
+void UPS_VACoutputMonitor(void)
+{
+
+  static uint8_t stateCurrentVACoutput = HYST_IDLE;
+  uint8_t VACoutputCurrent;
+
+  uint8_t i = 0;
+  static bool isValueRecv = false;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
+	  if(!isValueRecv)
+		  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+  }
+
+
+  VACoutputCurrent = UPS.VAC_out;
+
+  /* Отслеживается переход через нижнию границу */
+  if (VACoutputCurrent < UPS_VAC_OUTPUT)
+  {
+    if (stateCurrentVACoutput == HYST_IDLE)
+	{
+      LED_On(LED_MINOR_R);
+      LED_On(LED_MINOR_G);
+      stateCurrentVACoutput = HYST_UP;
+
+      relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 1);
+
+	  log_event_data(LOG_ALARM_VAC_OUTPUT, "Авария");
+	  // Отправка трапа о завышении
+	//  SNMP_SendUserTrap(POWER_ALARM);
+	  flUpdateLog = true;
+	}
+    else{
+    	relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, DC_PRESENT, 1);
+    }
+  }
+  /* Отслеживается нормализация */
+  else if (VACoutputCurrent > (UPS_VAC_OUTPUT + UPS_VAC_OUTPUT_HIST))
+  {
+    if (stateCurrentVACoutput == HYST_UP)
+	{
+    	LED_Off(LED_MINOR_R);
+    	LED_Off(LED_MINOR_G);
+    	stateCurrentVACoutput = HYST_IDLE;
+
+	  relay_setup_log(CurrROtype_Sourse, DC_PRESENT, 0);
+
+	  log_event_data(LOG_ALARM_VAC_OUTPUT, "Норма");
+	  // Отправка трапа о нормализации
+	 // SNMP_SendUserTrap(POWER_NORM);
+	  flUpdateLog = true;
+	}
+    else{
+    	relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, DC_PRESENT, 0);
+    }
+  }
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+  	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+    }
+}
+
+#endif
+
 /**
   * @brief  Мониторинг бита LowBat  
   */
@@ -394,6 +461,16 @@ void UPS_LowBatMonitor(void)
   static bool isValueRecv = false;
   static uint8_t lowBatOldState = 0;
   uint8_t lowBatCurrent;
+
+#ifdef HARDWARE_BT6706
+  uint8_t i = 0;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
+#endif
+
   if((UPS.Status >> 7) & 0x01)
 	  lowBatCurrent = (UPS.Status >> 6) & 0x01;
   else
@@ -406,6 +483,9 @@ void UPS_LowBatMonitor(void)
     	log_event_data(LOG_ALARM_LOW_BAT, "Авария");
           SNMP_SendUserTrap(LOW_BAT_ALARM);
           flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 1);
+#endif
     }
     return;
   }
@@ -418,13 +498,31 @@ void UPS_LowBatMonitor(void)
       SNMP_SendUserTrap(LOW_BAT_ALARM);
       log_event_data(LOG_ALARM_LOW_BAT, "Авария");
       flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 1);
+#endif
     }
     else{
       SNMP_SendUserTrap(LOW_BAT_NORM);
       log_event_data(LOG_ALARM_LOW_BAT, "Норма");
       flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, CHARGE_AKB, 0);
+#endif
     }
   }
+#ifdef HARDWARE_BT6706
+  else{
+	  if (lowBatCurrent)
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CHARGE_AKB, 1);
+	  else
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, CHARGE_AKB, 0);
+  }
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+  }
+#endif
   
   lowBatOldState = lowBatCurrent;
 }
@@ -568,6 +666,15 @@ void UPS_BatteryConnectMonitor(void)
   static uint8_t AKBconnectOldState = 0;
   uint8_t AKBconnectCurrent;
 
+#ifdef HARDWARE_BT6706
+  uint8_t i = 0;
+  static uint8_t OldROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+  uint8_t CurrROtype_Sourse[OUTPUTS_TOTAL_COUNT] = {0};
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++)
+	  CurrROtype_Sourse[i] = sSettings.sInOuts.ro_type_source[i];
+#endif
+
   if(((UPS.Status >> 7) & 0x01) == 0)
 	  AKBconnectCurrent = (UPS.Status >> 6) & 0x01;
   else{
@@ -583,6 +690,9 @@ void UPS_BatteryConnectMonitor(void)
       log_event_data(LOG_ALARM_AKB, "Авария");
 	  SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
 	  flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, OFF_AKB, 1);
+#endif
     }
     return;
   }
@@ -595,13 +705,31 @@ void UPS_BatteryConnectMonitor(void)
       log_event_data(LOG_ALARM_AKB, "Норма");
       SNMP_SendUserTrap(BATTERY_CONNECT_NORM);
       flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, OFF_AKB, 0);
+#endif
     }
     else{
       log_event_data(LOG_ALARM_AKB, "Авария");
       SNMP_SendUserTrap(BATTERY_CONNECT_ALARM);
       flUpdateLog = true;
+#ifdef HARDWARE_BT6706
+      relay_setup_log(CurrROtype_Sourse, OFF_AKB, 1);
+#endif
     }
   }
+#ifdef HARDWARE_BT6706
+  else{
+	  if (AKBconnectCurrent)
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, OFF_AKB, 1);
+	  else
+		  relay_setup_log_change(CurrROtype_Sourse, OldROtype_Sourse, OFF_AKB, 0);
+  }
+
+  for(i = 0; i < OUTPUTS_TOTAL_COUNT; i ++){
+	  OldROtype_Sourse[i] = CurrROtype_Sourse[i];
+  }
+#endif
 
   AKBconnectOldState = AKBconnectCurrent;
 }

+ 7 - 0
modules/monitor/ups_monitor.h

@@ -42,6 +42,13 @@ void UPS_NonCriticalAlarmMonitor(void);
   */
 void UPS_LineFailMonitor(void);
 
+#ifdef HARDWARE_BT6706
+/**
+  * @brief  Мониторинг аварии выходного напряжения
+  */
+void UPS_VACoutputMonitor(void);
+#endif
+
 /**
   * @brief  Мониторинг бита LowBat 
   */

+ 26 - 2
modules/parameters.c

@@ -27,7 +27,7 @@
 #include "settings_api.h"
 //#include "d_inouts.h"
 #include "gpio.h"
-#if defined HARDWARE_BT6702
+//#if defined HARDWARE_BT6702
 #ifdef PRINTF_STDLIB
 #include <stdio.h>
 #endif
@@ -37,7 +37,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <math.h>   
-#endif
+//#endif
 /**
   * @brief  Структура для хранения состояний дискретных входов
   */
@@ -303,7 +303,12 @@ void GetROTypeActStr(char *str, uint8_t *len, uint8_t num)
   */
 void GetDOUTStatusStr(char *str, uint8_t *len, uint8_t num)
 {
+#ifdef HARDWARE_BT6706
+	sprintf(str, "%d", (get_state_din_outs(DOUT1+num)^1));
+#elif HARDWARE_BT6702
 	sprintf(str, "%d", get_state_din_outs(DOUT1+num));
+#endif
+
 	*len = strlen(str);
 }
 
@@ -312,7 +317,11 @@ void GetDOUTStatusStr(char *str, uint8_t *len, uint8_t num)
   */
 void GetDOUT0StatusStr(char *str, uint8_t *len)
 {
+#ifdef HARDWARE_BT6706
+	sprintf(str, "%d", (get_state_din_outs(DOUT1)^1));
+#elif HARDWARE_BT6702
 	sprintf(str, "%d", get_state_din_outs(DOUT1));
+#endif
 	*len = strlen(str);
 }
 
@@ -321,10 +330,25 @@ void GetDOUT0StatusStr(char *str, uint8_t *len)
   */
 void GetDOUT1StatusStr(char *str, uint8_t *len)
 {
+#ifdef HARDWARE_BT6706
+	sprintf(str, "%d", (get_state_din_outs(DOUT2)^1));
+#elif HARDWARE_BT6702
 	sprintf(str, "%d", get_state_din_outs(DOUT2));
+#endif
 	*len = strlen(str);
 }
 
+#ifdef HARDWARE_BT6706
+/**
+  * @brief  Состояние релейного выхода
+  */
+void GetDOUT2StatusStr(char *str, uint8_t *len)
+{
+	sprintf(str, "%d", (get_state_din_outs(DOUT3)^3));
+	*len = strlen(str);
+}
+#endif
+
 // ************************************************************************** //
 //                             Информация
 

+ 7 - 0
modules/parameters.h

@@ -288,6 +288,13 @@ void GetDOUT0StatusStr(char *str, uint8_t *len);
   */
 void GetDOUT1StatusStr(char *str, uint8_t *len);
 
+#ifdef HARDWARE_BT6706
+/**
+  * @brief  Состояние релейного выхода
+  */
+void GetDOUT2StatusStr(char *str, uint8_t *len);
+#endif
+
 // ************************************************************************** //
 //                                Флаги
 

+ 6 - 0
modules/settings_api.c

@@ -180,8 +180,14 @@ void SETTINGS_SetSntpDef(void)
   */
 void SETTINGS_SetINOUTSDef(void)
 {
+#ifdef HARDWARE_BT6706
+	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_BT6702
 	sSettings.sInOuts.ro_type_source[0] = CRITICAL;
 	sSettings.sInOuts.ro_type_source[1] = SNMP_SET;
+#endif
 
 	sSettings.sInOuts.din_type_act[0] = DI_CONN;
 }

+ 10 - 3
modules/settings_api.h

@@ -131,9 +131,16 @@ typedef struct
   */
 typedef enum
 {
-    CRITICAL = 1,
-    NON_CRITICAL,
-    SNMP_SET,
+#ifdef HARDWARE_BT6706
+	AC_PRESENT = 1,
+	DC_PRESENT,
+	CHARGE_AKB,
+	OFF_AKB,
+#elif HARDWARE_BT6702
+	CRITICAL = 1,
+	NON_CRITICAL,
+#endif
+	SNMP_SET,
     RO_MAX_SOURCE
 } ro_type_source_t;
 

BIN
tracefile.bin


+ 8 - 3
user/init_task.c

@@ -24,7 +24,11 @@
 #include "netconf.h"
 #include "udp_netsetting.h"
 #include "snmp_api.h"
+#ifdef HARDWARE_BT6706
 #include "http_server.h"
+#elif HARDWARE_BT6702
+#include "my_ssl_server.h"
+#endif
 #include "sntp_api.h"
 #include "settings_api.h"
 #include "main.h"
@@ -137,10 +141,11 @@ void InitTask(void *params)
 #ifdef WEB_SERVER_ENABLE
 
 	  HTTP_Init();
-
+#ifdef HARDWARE_BT6702
 	   HTTPS_Init();
 //#define SSL_TASK_PRIO   ( configMAX_PRIORITIES - 3 )
 	   xTaskCreate(ssl_server, "SSL", 24*configMINIMAL_STACK_SIZE, NULL, SSL_TASK_PRIO, NULL);
+#endif
 #endif
 	   // UDP for net settings 
 	   if(strncmp(sSettings.sFlags.testState, "T2OK", 4)){
@@ -205,9 +210,9 @@ static void vTaskDebug(void *pvParameters)
   char msg[700];
   for(;;)
   {
-	vTaskList(msg);
+	/*vTaskList(msg);
 	DBG printf(msg);
-	DBG printf("\n\r\r\n");
+	DBG printf("\n\r\r\n");*/
 #if LWIP_STATS
 	stats_display();
 	DBG printf("\r\n\r\n");

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov