Explorar o código

Портирование проекта

TelenkovDmitry %!s(int64=7) %!d(string=hai) anos
pai
achega
69e4fe69f3

+ 2 - 2
config/common_config.h

@@ -66,7 +66,7 @@
 /**
   * @brief  Отладочный порт USART и консоль
   */
-//#define USART_DEBUG_ENABLE
+#define USART_DEBUG_ENABLE
 
 #define SYSTEMTICK_PERIOD_MS  1
 
@@ -100,7 +100,7 @@
   * @brief  SNMP протокол
   */
 #if defined HARDWARE_BT6702
-#define SNMP_ENABLE
+//#define SNMP_ENABLE
 #endif
 
 /**

+ 325 - 325
modules/Ethernet/udp_netsetting.c

@@ -1,325 +1,325 @@
-/*
- * udp_netsetting.c
- *
- *  Created on: 22.07.2016
- *      Author: balbekova
- */
-
-#include "FreeRTOS.h"
-#include "task.h"
-
-#include "lwip/api.h"
-#include "udp_netsetting.h"
-#include "stm32_uid.h"
-#include "parameters.h"
-#include "netconf.h"
-#include "web_params_api.h"
-#include "main.h"
-
-
-#include <string.h>
-#ifdef PRINTF_STDLIB
-#include <stdio.h>
-#endif
-#ifdef PRINTF_CUSTOM
-#include "tinystdio.h"
-#endif
-
-#undef DBG
-#define DBG if(0)
-
-#define RCV_TIMEOUT		1000
-#define SEND_TIMEOUT    2000
-
-#define DATA_BUF_LEN1   255
-
-#define UDP_PORT 49049
-
-char dataBuf1[DATA_BUF_LEN1];
-
-static uint8_t udp_type_message = 0;  //0 - идентификационное сообщение; 1 - сообщение с настройками сети
-
-void udp_message(char *buf)
-{
-	uint8_t len2 = 0;
-	char str[97];
-
-	memset(str, 0, 97);
-
-	GetModelStr(str, &len2);
-	strncat(buf, str, len2);
-	strcat(buf, ";");
-
-	GetSerialNumberStr(str, &len2);
-	strncat(buf, str, len2);
-	strcat(buf, ";");
-
-	GetMacStr(str, &len2);
-	strncat(buf, str, len2);
-	strcat(buf, ";");
-
-	GetVersionStr(str, &len2);
-	strncat(buf, str, len2);
-	strcat(buf, ";;;");
-
-	memset(str, 0, 97);
-	GetSTM32IDStr(str, &len2);
-	strncat(buf, str, len2);
-	strcat(buf, ";;;T2OK;;");
-}
-
-void udp_message_netSettings(char *buf)
-{
-  char str[100];
-  uint8_t len;
-
-  /* S/N */
-  GetSerialNumberStr(str, &len);
-  strcat(buf, "{\"serno\":\"");
-  strncat(buf, str, len);
-
-  /* WEB */
-  GetDhcpStateUDP(str, &len);
-  strcat(buf, "\",\"dhcp\":\"");
-  strncat(buf, str, len);
-
-  GetIpStr(str, &len);
-  strcat(buf, "\",\"ipaddress\":\"");
-  strncat(buf, str, len);
-
-  GetGatewayStr(str, &len);
-  strcat(buf, "\",\"gateway\":\"");
-  strncat(buf, str, len);
-
-  GetMaskStr(str, &len);
-  strcat(buf, "\",\"mask\":\"");
-  strncat(buf, str, len);
-
-  strncat(buf, "\"}", 2);
-}
-
-
-uint8_t GetUDPParamValue(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,"}");
-      if (endValue == 0)
-            endValue = strpbrk(strPtr," ");
-    }
-    len = endValue - beginValue - 3;
-    strncpy(paramValue, beginValue + 2, len);
-    *endValue = '0';
-    *beginValue = '0';
-	*paramLen = len;
-	return 1;
-  }
-  else
-  {
-	*paramLen = 0;
-	return 0;
-  }
-}
-
-void udp_recieve_parser(char *buf, u16_t rcvlen)
-{
-  uint8_t valueLen = 0;
-  uint8_t len2 = 0;
-  const uint8_t len = 100;
-  char value[100];
-  char str[100];
-
-  memset(str, 0, 100);
-
- // ClearParamString(buf);
-
-  memset(value, 0, len);
-  memset(str, 0, len);
-
-  DBG buf[rcvlen]='\0';
-  DBG printf("Rcvd (%d bytes): \t%s\r\n", rcvlen, buf);
-  GetUDPParamValue(buf, "\"serno\"", value, &valueLen);
-  if(valueLen != 0)
-	  GetSerialNumberStr(str, &len2);
-  else
-	  return;
-
-  if(strncmp(value, str, len2) == 0)
-  {
-	  memset(str, 0, len);
-
-	  GetUDPParamValue(buf, "\"dhcp\"", str, &valueLen);
-
-	 // memset(str, 0, len);
-	  memset(value, 0, len);
-	  GetUDPParamValue(buf, "\"ipaddress\"", value, &valueLen);
-	  if(valueLen != 0)
-	  {
-		  SetUDPDhcpStateStr(str);
-		  SetIPStr(value);
-	  }
-	  else{
-		  udp_type_message = 1;
-		  return;
-	  }
-
-	  if (strncmp(str, "True", 4) != 0)  // Если dhcp off устанавливаем параметры
-	  {
-		  memset(value, 0, len);
-
-		  GetUDPParamValue(buf, "\"gateway\"", value, &valueLen);
-		  if(valueLen != 0)
-			  SetGatewayStr(value);
-		  memset(value, 0, len);
-
-		  GetUDPParamValue(buf, "\"mask\"", value, &valueLen);
-		  if(valueLen != 0)
-			  SetMaskStr(value);
-		  memset(value, 0, len);
-	  }
-	  else
-		  SetUDPDhcpStateStr(str);
-	  // Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся
-	 if (GetStateWebReinit() == true)
-	  {
-	//	_message_add_to_log("Изменение сетевых настр", "Инфо", "ND");
-		 SetWebReinitFlag(false);
-		SetConfirmWebParamsFlag();
-		SaveWEBparam();
-		HTTP_SaveSettings();
-
-		NVIC_SystemReset();
-	  }
-  }
-}
-
-
-
-bool http_server_serve(struct netconn *conn)
-{
-    struct netbuf *inbuf;
-    err_t res;
-    char* buf;
-    u16_t buflen;
-    bool flag = false;
-
-    netconn_set_recvtimeout(conn, RCV_TIMEOUT);
-    res = netconn_recv(conn, &inbuf);
-
-  //  DBG printf("recv failed %d\n", res);
-
-    if (res == ERR_OK)
-    {
-        netbuf_data(inbuf, (void**)&buf, &buflen);
-        udp_recieve_parser(buf, buflen);
-        flag = true;
-        netbuf_delete(inbuf);
-    }
-
-    /* TODO remove if tested */
-    /* Close the connection (server closes in HTTP) */
-    //netconn_close(conn);
-
-    /* TODO remove if tested */
-    /* Delete the buffer (netconn_recv gives us ownership,
-    so we have to make sure to deallocate the buffer) */
-    //netbuf_delete(inbuf);
-    return flag;
-}
-
-
-void udp_netsettings_task(void *arg)
-{
-  struct netconn *udp_conn;
-  struct netbuf *buf_snd;
-  char *data_snd;
-  err_t err;
-  TickType_t timestamp = 0;
-  uint32_t len;
-
-
-  vTaskDelay(5000);
-
-  udp_conn = netconn_new( NETCONN_UDP );
-
-  if (udp_conn != NULL)
-  {
-    err = netconn_bind(udp_conn, IP_ADDR_ANY, UDP_PORT);
-
-    if (err == ERR_OK)
-    {
-
-      for( ;; )
-      {
-    	netconn_connect(udp_conn, IP_ADDR_BROADCAST, UDP_PORT);
-		memset(dataBuf1, 0, DATA_BUF_LEN1);
-
-		switch(udp_type_message)
-		{
-		case 0:
-		    if (timestamp + SEND_TIMEOUT < xTaskGetTickCount()) {
-		        udp_message(dataBuf1);
-		        timestamp = xTaskGetTickCount();
-		    }
-			break;
-		case 1:
-			udp_message_netSettings(dataBuf1);
-			udp_type_message = 0;
-			break;
-		default:
-			break;
-		}
-
-		len = strlen(dataBuf1);
-
-        if (len > 0) {
-            buf_snd = netbuf_new();
-            data_snd = netbuf_alloc(buf_snd,len);
-            memcpy(data_snd, dataBuf1, len);
-            netconn_send(udp_conn, buf_snd);
-            netbuf_delete(buf_snd);
-            DBG printf("\r\nSent (%u bytes): \t%s\r\n", (unsigned int)len, dataBuf1);
-        }
-
-		netconn_disconnect(udp_conn);
-
-		/* TODO remove if tested */
-		//if(http_server_serve(udp_conn))
-			 //vTaskDelay(1000);
-
-		http_server_serve(udp_conn);
-      }
-    }
-    else
-    {
-      netconn_delete(udp_conn);
-      DBG printf("udp_netsettings_task: can't bind netconn\r\n");
-    }
-  }
-  else
-	  DBG printf("udp_netsettings_task: can't create new UDP netconn\r\n");
-
-  for( ;; )
-  {
-	  vTaskDelay(10000);
-  }
-
-}
-
-void UDP_netsetting_init() {
-	xTaskCreate(udp_netsettings_task, ( char * ) "udp_netsettings_task", 4*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY, NULL);
-}
-
-
-
+/*
+ * udp_netsetting.c
+ *
+ *  Created on: 22.07.2016
+ *      Author: balbekova
+ */
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "lwip/api.h"
+#include "udp_netsetting.h"
+#include "stm32_uid.h"
+#include "parameters.h"
+#include "netconf.h"
+#include "web_params_api.h"
+#include "main.h"
+
+
+#include <string.h>
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+
+#undef DBG
+#define DBG if(0)
+
+#define RCV_TIMEOUT		1000
+#define SEND_TIMEOUT    2000
+
+#define DATA_BUF_LEN1   255
+
+#define UDP_PORT 49049
+
+char dataBuf1[DATA_BUF_LEN1];
+
+static uint8_t udp_type_message = 0;  //0 - идентификационное сообщение; 1 - сообщение с настройками сети
+
+void udp_message(char *buf)
+{
+	uint8_t len2 = 0;
+	char str[97];
+
+	memset(str, 0, 97);
+
+	GetModelStr(str, &len2);
+	strncat(buf, str, len2);
+	strcat(buf, ";");
+
+	GetSerialNumberStr(str, &len2);
+	strncat(buf, str, len2);
+	strcat(buf, ";");
+
+	GetMacStr(str, &len2);
+	strncat(buf, str, len2);
+	strcat(buf, ";");
+
+	GetVersionStr(str, &len2);
+	strncat(buf, str, len2);
+	strcat(buf, ";;;");
+
+	memset(str, 0, 97);
+	GetSTM32IDStr(str, &len2);
+	strncat(buf, str, len2);
+	strcat(buf, ";;;T2OK;;");
+}
+
+void udp_message_netSettings(char *buf)
+{
+  char str[100];
+  uint8_t len;
+
+  /* S/N */
+  GetSerialNumberStr(str, &len);
+  strcat(buf, "{\"serno\":\"");
+  strncat(buf, str, len);
+
+  /* WEB */
+  //GetDhcpStateUDP(str, &len);
+  strcat(buf, "\",\"dhcp\":\"");
+  strncat(buf, str, len);
+
+  GetIpStr(str, &len);
+  strcat(buf, "\",\"ipaddress\":\"");
+  strncat(buf, str, len);
+
+  GetGatewayStr(str, &len);
+  strcat(buf, "\",\"gateway\":\"");
+  strncat(buf, str, len);
+
+  GetMaskStr(str, &len);
+  strcat(buf, "\",\"mask\":\"");
+  strncat(buf, str, len);
+
+  strncat(buf, "\"}", 2);
+}
+
+
+uint8_t GetUDPParamValue(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,"}");
+      if (endValue == 0)
+            endValue = strpbrk(strPtr," ");
+    }
+    len = endValue - beginValue - 3;
+    strncpy(paramValue, beginValue + 2, len);
+    *endValue = '0';
+    *beginValue = '0';
+	*paramLen = len;
+	return 1;
+  }
+  else
+  {
+	*paramLen = 0;
+	return 0;
+  }
+}
+
+void udp_recieve_parser(char *buf, u16_t rcvlen)
+{
+  uint8_t valueLen = 0;
+  uint8_t len2 = 0;
+  const uint8_t len = 100;
+  char value[100];
+  char str[100];
+
+  memset(str, 0, 100);
+
+ // ClearParamString(buf);
+
+  memset(value, 0, len);
+  memset(str, 0, len);
+
+  DBG buf[rcvlen]='\0';
+  DBG printf("Rcvd (%d bytes): \t%s\r\n", rcvlen, buf);
+  GetUDPParamValue(buf, "\"serno\"", value, &valueLen);
+  if(valueLen != 0)
+	  GetSerialNumberStr(str, &len2);
+  else
+	  return;
+
+  if(strncmp(value, str, len2) == 0)
+  {
+	  memset(str, 0, len);
+
+	  GetUDPParamValue(buf, "\"dhcp\"", str, &valueLen);
+
+	 // memset(str, 0, len);
+	  memset(value, 0, len);
+	  GetUDPParamValue(buf, "\"ipaddress\"", value, &valueLen);
+	  if(valueLen != 0)
+	  {
+		  //SetUDPDhcpStateStr(str);
+		  SetIPStr(value);
+	  }
+	  else{
+		  udp_type_message = 1;
+		  return;
+	  }
+
+	  if (strncmp(str, "True", 4) != 0)  // Если dhcp off устанавливаем параметры
+	  {
+		  memset(value, 0, len);
+
+		  GetUDPParamValue(buf, "\"gateway\"", value, &valueLen);
+		  if(valueLen != 0)
+			  SetGatewayStr(value);
+		  memset(value, 0, len);
+
+		  GetUDPParamValue(buf, "\"mask\"", value, &valueLen);
+		  if(valueLen != 0)
+			  SetMaskStr(value);
+		  memset(value, 0, len);
+	  }
+	  //else
+		  //SetUDPDhcpStateStr(str);
+	  // Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся
+	 if (GetStateWebReinit() == true)
+	  {
+	//	_message_add_to_log("Изменение сетевых настр", "Инфо", "ND");
+		 SetWebReinitFlag(false);
+		SetConfirmWebParamsFlag();
+		SaveWEBparam();
+		HTTP_SaveSettings();
+
+		NVIC_SystemReset();
+	  }
+  }
+}
+
+
+
+bool http_server_serve(struct netconn *conn)
+{
+    struct netbuf *inbuf;
+    err_t res;
+    char* buf;
+    u16_t buflen;
+    bool flag = false;
+
+    netconn_set_recvtimeout(conn, RCV_TIMEOUT);
+    res = netconn_recv(conn, &inbuf);
+
+  //  DBG printf("recv failed %d\n", res);
+
+    if (res == ERR_OK)
+    {
+        netbuf_data(inbuf, (void**)&buf, &buflen);
+        udp_recieve_parser(buf, buflen);
+        flag = true;
+        netbuf_delete(inbuf);
+    }
+
+    /* TODO remove if tested */
+    /* Close the connection (server closes in HTTP) */
+    //netconn_close(conn);
+
+    /* TODO remove if tested */
+    /* Delete the buffer (netconn_recv gives us ownership,
+    so we have to make sure to deallocate the buffer) */
+    //netbuf_delete(inbuf);
+    return flag;
+}
+
+
+void udp_netsettings_task(void *arg)
+{
+  struct netconn *udp_conn;
+  struct netbuf *buf_snd;
+  char *data_snd;
+  err_t err;
+  TickType_t timestamp = 0;
+  uint32_t len;
+
+
+  vTaskDelay(5000);
+
+  udp_conn = netconn_new( NETCONN_UDP );
+
+  if (udp_conn != NULL)
+  {
+    err = netconn_bind(udp_conn, IP_ADDR_ANY, UDP_PORT);
+
+    if (err == ERR_OK)
+    {
+
+      for( ;; )
+      {
+    	netconn_connect(udp_conn, IP_ADDR_BROADCAST, UDP_PORT);
+		memset(dataBuf1, 0, DATA_BUF_LEN1);
+
+		switch(udp_type_message)
+		{
+		case 0:
+		    if (timestamp + SEND_TIMEOUT < xTaskGetTickCount()) {
+		        udp_message(dataBuf1);
+		        timestamp = xTaskGetTickCount();
+		    }
+			break;
+		case 1:
+			udp_message_netSettings(dataBuf1);
+			udp_type_message = 0;
+			break;
+		default:
+			break;
+		}
+
+		len = strlen(dataBuf1);
+
+        if (len > 0) {
+            buf_snd = netbuf_new();
+            data_snd = netbuf_alloc(buf_snd,len);
+            memcpy(data_snd, dataBuf1, len);
+            netconn_send(udp_conn, buf_snd);
+            netbuf_delete(buf_snd);
+            DBG printf("\r\nSent (%u bytes): \t%s\r\n", (unsigned int)len, dataBuf1);
+        }
+
+		netconn_disconnect(udp_conn);
+
+		/* TODO remove if tested */
+		//if(http_server_serve(udp_conn))
+			 //vTaskDelay(1000);
+
+		http_server_serve(udp_conn);
+      }
+    }
+    else
+    {
+      netconn_delete(udp_conn);
+      DBG printf("udp_netsettings_task: can't bind netconn\r\n");
+    }
+  }
+  else
+	  DBG printf("udp_netsettings_task: can't create new UDP netconn\r\n");
+
+  for( ;; )
+  {
+	  vTaskDelay(10000);
+  }
+
+}
+
+void UDP_netsetting_init() {
+	xTaskCreate(udp_netsettings_task, ( char * ) "udp_netsettings_task", 4*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY, NULL);
+}
+
+
+

+ 8 - 6
modules/HTTP_Server/http_server.c

@@ -92,7 +92,7 @@ const char HTTP_200_OK[] = "HTTP/1.1 200 OK\r\n\r\n";
 /**
   * @brief  Общая структура настроек
   */
-SETTINGS_t sSettings;
+extern SETTINGS_t sSettings;
 
 /**
   * @brief  closes tcp connection
@@ -471,7 +471,8 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb,  struct pbuf *p, err_t er
 	  }
 	  else if (strncmp(data, "POST /settings.cgi", 18) == 0)
 	  {
-		  strncat(&receiveBuf,  " ", 1);
+		  //strncat(&receiveBuf,  " ", 1);
+          strncat(receiveBuf,  " ", 1);
 		  HTTP_SetSettings(receiveBuf, receivedBufLen);
 		  memset(sendBuf, 0, SEND_BUF_MAX_LEN);
 
@@ -505,7 +506,8 @@ static err_t http_recv(void *arg, struct tcp_pcb *pcb,  struct pbuf *p, err_t er
 	  }
 	  else if (strncmp(data, "POST /info.cgi", 14) == 0)
 	  {
-		  strncat(&receiveBuf,  " ", 1);
+		  //strncat(&receiveBuf,  " ", 1);
+          strncat(receiveBuf,  " ", 1);
 		  HTTP_SetInfo(receiveBuf, receivedBufLen);
 		  memset(sendBuf, 0, SEND_BUF_MAX_LEN);
 
@@ -789,8 +791,8 @@ void HTTP_Init()
      HTTP_SetUserCookie(buf, user_id);
 
      /* Create user logout timers */
-     users[user_id].LogoutTimer =
-             xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback);
+     //users[user_id].LogoutTimer =
+     //        xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback);
    }
 }
 
@@ -1475,7 +1477,7 @@ static void HTTP_SetUserCookie(char *str, uint8_t user_id)
   */
 static void HTTP_UpdateUserLoginTime(uint8_t user_id)
 {
-    xTimerStart(users[user_id].LogoutTimer, 0);
+    //xTimerStart(users[user_id].LogoutTimer, 0);
 }
 
 /**

+ 337 - 332
modules/MegaTec/megatec.c

@@ -1,332 +1,337 @@
-/*
- * megatec.c
- *
- *  Created on: 22.05.2017
- *      Author: balbekova
- */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "usart.h"
-#include "megatec.h"
-#ifdef PRINTF_STDLIB
-#include <stdio.h>
-#endif
-#ifdef PRINTF_CUSTOM
-#include "tinystdio.h"
-#endif
-
-#include <string.h>
-#include <math.h>
-
-#define UPS_PDU_MAX_LEN 50
-
-uint16_t TimeParam = 0;
-uint16_t TimeParam2 = 0;
-bool megatec_send = true;
-
-enum {
-	NORMAL = 0x00,
-	VER_ERROR = 0x01,
-	CHKSUM_ERROR = 0x02,
-	LCHKSUM_ERROR = 0x03,
-	CID2_INVALID = 0x04,
-	CMD_FMT_ERROR = 0x05,
-	INVALID_DATA = 0x06,
-};
-
-static struct {
-	uint8_t data[UPS_PDU_MAX_LEN];
-	uint16_t len;
-} ups_pdu;
-
-
-const char* MegaTecCMD[] =
-{
-		"Q1\r",
-		"T\r",
-		"TL\r",
-		"T",
-		"Q\r",
-		"S",
-		"R",
-		"C\r",
-		"CT\r",
-		"I\r",
-		"F\r"
-};
-
-
-void init_UPS_value(void)
-{
-	UPS.Freq_in = 0;
-	UPS.VAC_in = 0;
-	UPS.VAC_out = 0;
-	UPS.Temp = 0;
-	UPS.Load = 0;
-	UPS.SOC = 0;
-	UPS.work_time = 0;
-	UPS.Status = 0;
-	UPS.Alarm = 0;
-	UPS.cnt_err_ups = 0;
-	UPS.Flag_Present = false;
-	UPS.Present = false;
-
-	memset(UPS.model, 0, 11);
-	memset(UPS.vertion, 0, 11);
-}
-
-void send_MegaTec_cmd(cmdMegaTecEnums_t command)
-{
-	if(command == ups_test_time){
-		uint8_t req[10];
-
-		memset(req, 0, 10);
-		sprintf(req, "%s%d\r", MegaTecCMD[command], TimeParam);
-		ups_send_block(req, strlen(req));
-	}
-	else if(command == ups_shutdown){
-
-	}
-	else if(command == ups_shutdown_restore){
-		uint8_t req[10];
-
-		memset(req, 0, 10);
-		sprintf(req, "%s.%d%s%d\r", MegaTecCMD[command-1], TimeParam, MegaTecCMD[command], TimeParam2);
-		ups_send_block(req, strlen(req));
-	}
-	else{
-		ups_send_block(MegaTecCMD[command], strlen(MegaTecCMD[command]));
-	}
-}
-
-bool ups_megatec_rx_pdu(void)
-{
-	int c = 0;
-
-	ups_pdu.len = 0;
-
-	while ((ups_pdu.len < UPS_PDU_MAX_LEN) && (c != 0x0d)) {
-		c = ups_getchar(500);//portMAX_DELAY
-		if(c < 0)
-		{
-			ups_pdu.len = 0;
-			break;
-		}
-		ups_pdu.data[ups_pdu.len++] = c;
-	}
-
-	if (ups_pdu.len == 0)
-		return false;
-
-	return true;
-}
-
-void ups_status_response(char *data)
-{
-	uint8_t i;
-	char *endValue;
-	char value[10];
-	uint8_t len = 0;
-	if(data[0] != '(')
-		return;
-
-	UPS.Present = true;
-	UPS.Flag_Present = true;
-	UPS.cnt_err_ups = true;
-
-	data++;
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.VAC_in = atof(value);
-
-	//TODO
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.VAC_out = atof(value);
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.Load = atoi(value);
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.Freq_in = atof(value);
-
-	//TODO
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.SOC = 100*(atof(value));
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data," ");
-	len = endValue - data;
-	strncpy(value, data, len);
-	data += (len + 1);
-	UPS.Temp = atof(value);
-
-	memset(value, 0, 10);
-	endValue = strpbrk(data,"\r");
-	len = endValue - data;
-	strncpy(value, data, len);
-	uint8_t stat = 0;
-	for(i = 0; i < len; i ++)
-	{
-		stat |= (value[i] - 0x30) << (7-i);
-	}
-	UPS.Status = stat;
-}
-
-void ups_info_response(char *data)
-{
-	uint8_t i = 0;
-	char *endValue;
-	uint8_t len = 0;
-	if(data[0] != '#')
-		return;
-
-	UPS.Present = true;
-	UPS.Flag_Present = true;
-	UPS.cnt_err_ups = true;
-
-	data++;
-
-	data += 16;
-
-	while(data[0] == ' '){
-		data ++;
-		i ++;
-	}
-	if(i < 11){
-		endValue = strpbrk(data," ");
-		len = endValue - data;
-		strncpy(UPS.model, data, len);
-		data += (len + 1);
-	}
-	else
-	{
-		strcpy(UPS.model, "RTMP II");
-	}
-
-	endValue = strpbrk(data,"\r");
-	len = endValue - data;
-	strncpy(UPS.vertion, data, len);
-
-}
-
-void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
-{
-	switch(command)
-	{
-	case ups_status_req:
-		ups_status_response(ups_pdu.data);
-		break;
-	case ups_info:
-		ups_info_response(ups_pdu.data);
-		break;
-	case ups_rating_info:
-
-		break;
-	default:
-		break;
-	}
-}
-
-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;
-
-	}
-	return -1;
-}
-
-void request_task(void)
-{
-
-		for(;;)
-		{
-			if(UPS.Present == true){
-				if(UPS.Flag_Present == false)
-				{
-					if(UPS.cnt_err_ups != 2)
-						UPS.cnt_err_ups++;
-					else{
-						UPS.Freq_in = 0;
-						UPS.VAC_in = 0;
-						UPS.VAC_out = 0;
-						UPS.Temp = 0;
-						UPS.Load = 0;
-						UPS.SOC = 0;
-						UPS.work_time = 0;
-						UPS.Status = 0;
-						UPS.Alarm = 0;
-						UPS.Present = false;
-
-						memset(UPS.model, 0, 11);
-						memset(UPS.vertion, 0, 11);
-					}
-				}
-			}
-			if(megatec_send){
-				megatec_send= false;
-				UPS.Flag_Present = false;
-				send_MegaTec_cmd(ups_status_req);
-				if (ups_megatec_rx_pdu())
-					ups_megatec_process_pdu(ups_status_req);
-
-				megatec_send=true;
-			}
-			//vTaskDelay(100);
-			if(megatec_send){
-				megatec_send = false;
-				UPS.Flag_Present = false;
-				 send_MegaTec_cmd(ups_info);
-				if (ups_megatec_rx_pdu())
-					ups_megatec_process_pdu(ups_info);
-				megatec_send = true;
-			}
-
-	        vTaskDelay(1000);
-
-		}
-}
-
-void ups_megatec_init(void) {
-	init_UPS_value();
-
-	xTaskCreate(request_task, ( char * ) "request_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
-
-}
+/*
+ * megatec.c
+ *
+ *  Created on: 22.05.2017
+ *      Author: balbekova
+ */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "usart.h"
+#include "megatec.h"
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#define UPS_PDU_MAX_LEN 50
+
+uint16_t TimeParam = 0;
+uint16_t TimeParam2 = 0;
+bool megatec_send = true;
+UPS_value_t UPS;
+
+enum {
+	NORMAL = 0x00,
+	VER_ERROR = 0x01,
+	CHKSUM_ERROR = 0x02,
+	LCHKSUM_ERROR = 0x03,
+	CID2_INVALID = 0x04,
+	CMD_FMT_ERROR = 0x05,
+	INVALID_DATA = 0x06,
+};
+
+static struct {
+	uint8_t data[UPS_PDU_MAX_LEN];
+	uint16_t len;
+} ups_pdu;
+
+
+const char* MegaTecCMD[] =
+{
+		"Q1\r",
+		"T\r",
+		"TL\r",
+		"T",
+		"Q\r",
+		"S",
+		"R",
+		"C\r",
+		"CT\r",
+		"I\r",
+		"F\r"
+};
+
+
+void init_UPS_value(void)
+{
+	UPS.Freq_in = 0;
+	UPS.VAC_in = 0;
+	UPS.VAC_out = 0;
+	UPS.Temp = 0;
+	UPS.Load = 0;
+	UPS.SOC = 0;
+	UPS.work_time = 0;
+	UPS.Status = 0;
+	UPS.Alarm = 0;
+	UPS.cnt_err_ups = 0;
+	UPS.Flag_Present = false;
+	UPS.Present = false;
+
+	memset(UPS.model, 0, 11);
+	memset(UPS.vertion, 0, 11);
+}
+
+void send_MegaTec_cmd(cmdMegaTecEnums_t command)
+{
+	if(command == ups_test_time){
+		uint8_t req[10];
+
+		memset(req, 0, 10);
+		sprintf(req, "%s%d\r", MegaTecCMD[command], TimeParam);
+		ups_send_block(req, strlen(req));
+	}
+	else if(command == ups_shutdown){
+
+	}
+	else if(command == ups_shutdown_restore){
+		uint8_t req[10];
+
+		memset(req, 0, 10);
+		sprintf(req, "%s.%d%s%d\r", MegaTecCMD[command-1], TimeParam, MegaTecCMD[command], TimeParam2);
+		ups_send_block(req, strlen(req));
+	}
+	else{
+        // TODO Согласовать изменения
+		//ups_send_block(MegaTecCMD[command], strlen(MegaTecCMD[command]));
+        ups_send_block((void*)MegaTecCMD[command], strlen(MegaTecCMD[command]));
+	}
+}
+
+bool ups_megatec_rx_pdu(void)
+{
+	int c = 0;
+
+	ups_pdu.len = 0;
+
+	while ((ups_pdu.len < UPS_PDU_MAX_LEN) && (c != 0x0d)) {
+		c = ups_getchar(500);//portMAX_DELAY
+		if(c < 0)
+		{
+			ups_pdu.len = 0;
+			break;
+		}
+		ups_pdu.data[ups_pdu.len++] = c;
+	}
+
+	if (ups_pdu.len == 0)
+		return false;
+
+	return true;
+}
+
+void ups_status_response(char *data)
+{
+	uint8_t i;
+	char *endValue;
+	char value[10];
+	uint8_t len = 0;
+	if(data[0] != '(')
+		return;
+
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = true;
+
+	data++;
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.VAC_in = atof(value);
+
+	//TODO
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.VAC_out = atof(value);
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.Load = atoi(value);
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.Freq_in = atof(value);
+
+	//TODO
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.SOC = 100*(atof(value));
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data," ");
+	len = endValue - data;
+	strncpy(value, data, len);
+	data += (len + 1);
+	UPS.Temp = atof(value);
+
+	memset(value, 0, 10);
+	endValue = strpbrk(data,"\r");
+	len = endValue - data;
+	strncpy(value, data, len);
+	uint8_t stat = 0;
+	for(i = 0; i < len; i ++)
+	{
+		stat |= (value[i] - 0x30) << (7-i);
+	}
+	UPS.Status = stat;
+}
+
+void ups_info_response(char *data)
+{
+	uint8_t i = 0;
+	char *endValue;
+	uint8_t len = 0;
+	if(data[0] != '#')
+		return;
+
+	UPS.Present = true;
+	UPS.Flag_Present = true;
+	UPS.cnt_err_ups = true;
+
+	data++;
+
+	data += 16;
+
+	while(data[0] == ' '){
+		data ++;
+		i ++;
+	}
+	if(i < 11){
+		endValue = strpbrk(data," ");
+		len = endValue - data;
+		strncpy(UPS.model, data, len);
+		data += (len + 1);
+	}
+	else
+	{
+		strcpy(UPS.model, "RTMP II");
+	}
+
+	endValue = strpbrk(data,"\r");
+	len = endValue - data;
+	strncpy(UPS.vertion, data, len);
+
+}
+
+void ups_megatec_process_pdu(cmdMegaTecEnums_t command)
+{
+	switch(command)
+	{
+	case ups_status_req:
+		ups_status_response(ups_pdu.data);
+		break;
+	case ups_info:
+		ups_info_response(ups_pdu.data);
+		break;
+	case ups_rating_info:
+
+		break;
+	default:
+		break;
+	}
+}
+
+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;
+
+	}
+	return -1;
+}
+
+// TODO Согласовать изменения
+//void request_task(void)
+void request_task(void* params)
+{
+
+		for(;;)
+		{
+			if(UPS.Present == true){
+				if(UPS.Flag_Present == false)
+				{
+					if(UPS.cnt_err_ups != 2)
+						UPS.cnt_err_ups++;
+					else{
+						UPS.Freq_in = 0;
+						UPS.VAC_in = 0;
+						UPS.VAC_out = 0;
+						UPS.Temp = 0;
+						UPS.Load = 0;
+						UPS.SOC = 0;
+						UPS.work_time = 0;
+						UPS.Status = 0;
+						UPS.Alarm = 0;
+						UPS.Present = false;
+
+						memset(UPS.model, 0, 11);
+						memset(UPS.vertion, 0, 11);
+					}
+				}
+			}
+			if(megatec_send){
+				megatec_send= false;
+				UPS.Flag_Present = false;
+				send_MegaTec_cmd(ups_status_req);
+				if (ups_megatec_rx_pdu())
+					ups_megatec_process_pdu(ups_status_req);
+
+				megatec_send=true;
+			}
+			//vTaskDelay(100);
+			if(megatec_send){
+				megatec_send = false;
+				UPS.Flag_Present = false;
+				 send_MegaTec_cmd(ups_info);
+				if (ups_megatec_rx_pdu())
+					ups_megatec_process_pdu(ups_info);
+				megatec_send = true;
+			}
+
+	        vTaskDelay(1000);
+
+		}
+}
+
+void ups_megatec_init(void) {
+	init_UPS_value();
+    
+    xTaskCreate(request_task, ( char * ) "request_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
+
+}

+ 58 - 58
modules/MegaTec/megatec.h

@@ -1,58 +1,58 @@
-/*
- * megatec.h
- *
- *  Created on: 22.05.2017
- *      Author: balbekova
- */
-
-#ifndef MEGATEC_H_
-#define MEGATEC_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-typedef enum{
-	ups_status_req,
-	ups_test_10sec,
-	ups_test_low_bat,
-	ups_test_time,
-	ups_beep,
-	ups_shutdown,
-	ups_shutdown_restore,
-	ups_cancel_shut_down,
-	ups_cancel_test,
-	ups_info,
-	ups_rating_info,
-
-	MegaTec_cmd_max
-} cmdMegaTecEnums_t;
-
-typedef struct{
-	float Freq_in;
-	float VAC_in;
-	float VAC_out;
-	float Temp;
-	uint8_t Load;
-	uint8_t SOC;
-	uint8_t work_time;
-	uint8_t Status;
-	uint8_t Alarm;
-	char model[11];
-	char vertion[11];
-	uint8_t cnt_err_ups;
-	bool Present;
-	bool Flag_Present;
-}UPS_value_t;
-
-UPS_value_t UPS;
-
-extern uint16_t TimeParam;
-extern uint16_t TimeParam2;
-
-int ups_metac_service_pdu(cmdMegaTecEnums_t command);
-
-void ups_megatec_init(void);
-
-
-#endif /* MEGATEC_H_ */
+/*
+ * megatec.h
+ *
+ *  Created on: 22.05.2017
+ *      Author: balbekova
+ */
+
+#ifndef MEGATEC_H_
+#define MEGATEC_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef enum{
+	ups_status_req,
+	ups_test_10sec,
+	ups_test_low_bat,
+	ups_test_time,
+	ups_beep,
+	ups_shutdown,
+	ups_shutdown_restore,
+	ups_cancel_shut_down,
+	ups_cancel_test,
+	ups_info,
+	ups_rating_info,
+
+	MegaTec_cmd_max
+} cmdMegaTecEnums_t;
+
+typedef struct{
+	float Freq_in;
+	float VAC_in;
+	float VAC_out;
+	float Temp;
+	uint8_t Load;
+	uint8_t SOC;
+	uint8_t work_time;
+	uint8_t Status;
+	uint8_t Alarm;
+	char model[11];
+	char vertion[11];
+	uint8_t cnt_err_ups;
+	bool Present;
+	bool Flag_Present;
+}UPS_value_t;
+
+extern UPS_value_t UPS;
+
+extern uint16_t TimeParam;
+extern uint16_t TimeParam2;
+
+int ups_metac_service_pdu(cmdMegaTecEnums_t command);
+
+void ups_megatec_init(void);
+
+
+#endif /* MEGATEC_H_ */

+ 31 - 31
modules/d_inouts/d_inouts.h

@@ -1,31 +1,31 @@
-#ifndef D_INOUTS_H
-#include "board.h"
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#define INOUTS_EXPAND_AS_ENUM(name, ...) name ## _,
-
-
-
-enum inputs_e {
-	DI_TABLE(INOUTS_EXPAND_AS_ENUM)
-	INPUTS_TOTAL_COUNT
-};
-
-enum outputs_e {
-	RELAYS(INOUTS_EXPAND_AS_ENUM)
-	OUTPUTS_TOTAL_COUNT
-};
-
-uint8_t  inputs[INPUTS_TOTAL_COUNT], outputs[OUTPUTS_TOTAL_COUNT];
-void  d_inouts_task(void *arg);
-void  d_inouts_test(void *arg);
-
-bool get_inputs(uint8_t *inputs_p); 
-bool set_outputs(uint8_t *outputs_p);
-
-uint8_t get_state_din_outs(gpio_t pin);
-void set_state_douts(gpio_t pin, uint8_t value);
-
-#endif /* D_INOUTS_H */
+#ifndef D_INOUTS_H
+#include "board.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define INOUTS_EXPAND_AS_ENUM(name, ...) name ## _,
+
+
+
+enum inputs_e {
+	DI_TABLE(INOUTS_EXPAND_AS_ENUM)
+	INPUTS_TOTAL_COUNT
+};
+
+enum outputs_e {
+	RELAYS(INOUTS_EXPAND_AS_ENUM)
+	OUTPUTS_TOTAL_COUNT
+};
+
+extern uint8_t  inputs[INPUTS_TOTAL_COUNT], outputs[OUTPUTS_TOTAL_COUNT];
+void  d_inouts_task(void *arg);
+void  d_inouts_test(void *arg);
+
+bool get_inputs(uint8_t *inputs_p); 
+bool set_outputs(uint8_t *outputs_p);
+
+uint8_t get_state_din_outs(gpio_t pin);
+void set_state_douts(gpio_t pin, uint8_t value);
+
+#endif /* D_INOUTS_H */

+ 4 - 2
modules/parameters.c

@@ -930,7 +930,8 @@ void SetDateStr(char *str)
 	len = strlen(str_time);
 	strncat(str_data, str_time, len);
 
-	TM_RTC_SetDateTimeString(&str_data);
+	//TM_RTC_SetDateTimeString(&str_data);
+    TM_RTC_SetDateTimeString(str_data);
 }
 
 /**
@@ -952,7 +953,8 @@ void SetTimeStr(char *str)
 	strncat(str_data, str_date, len);
 	strncat(str_data, str, 5);
 
-	TM_RTC_SetDateTimeString(&str_data);
+	//TM_RTC_SetDateTimeString(&str_data);
+    TM_RTC_SetDateTimeString(str_data);
 }
 
 // ************************************************************************** //

+ 9 - 1
modules/settings_api.c

@@ -30,6 +30,10 @@
 
 #define DBG if(0)
 
+#if defined ( __ICCARM__ )
+#define DEVICE_MAC "00-00-00-00-00-02"
+#endif
+
 /**
   * @brief  Флаг подтверждения новых сетевых параметров пользователем
   */  
@@ -54,7 +58,7 @@ void SETTINGS_SetBootParamsDef(void)
   */
 void SETTINGS_SetWebParamsDef(void)
 {
-	  strcpy(sSettings.sWebParams.ip, "192.168.1.2");
+	  strcpy(sSettings.sWebParams.ip, "192.168.1.8");
 	  strcpy(sSettings.sWebParams.gate, "192.168.1.1");
 	  strcpy(sSettings.sWebParams.mask, "255.255.255.0");
 	  sSettings.sWebParams.dhcpEnable = 1;
@@ -413,11 +417,15 @@ void SETTINGS_GetMac(uint8_t *mac)
   char dummy[2];
   char *macPtr = sSettings.sInfo.mac;	
   
+#if defined ( __ICCARM__ ) 
+  macPtr = DEVICE_MAC;
+#endif
   for (uint8_t i = 0; i < 6; i++)
   {
     strncpy(dummy, macPtr+i*3, 2);
 	mac[i] = (uint8_t)strtol(dummy, NULL, 16);
   }
+
 }
 
 /**

+ 125 - 125
peripheral_modules/inc/gpio.h

@@ -1,125 +1,125 @@
-#ifndef GPIO_H
-#define GPIO_H
-
-#include "stm32f4xx_conf.h"
-#include "stm32f4xx.h"
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-
-#define GLITCH_TIMEOUT 200
-
-
-/* 
- * Alternative function numbers definitions
- */
-enum af_n {AF0 = 0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
-	   AF8, AF9, AF10, AF11, AF12, AF13, AF14, AF15};
-
-
-#define _GPIO_AF_SHIFT   10
-/* Flags for gpio init */
-#define GPIO_IN		0x01
-#define GPIO_IN_PU	0x02
-#define GPIO_OUT	0x04
-#define GPIO_SET	0x08
-#define GPIO_INV	0x10
-#define GPIO_OD		0x20
-#define GPIO_BKP	0x40
-#define GPIO_NOINIT	0x80
-#define GPIO_DIR_CHANGE	0x100
-#define GPIO_AF		0x200
-#define AF_TIM1		((AF1 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM2  	((AF1 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM3  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM4  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM5  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM8  	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM9  	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM10 	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM11 	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_I2C1 	((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_I2C2		((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_I2C3 	((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_SPI1 	((AF5 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_SPI2 	((AF5 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_SPI3 	((AF6 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART1 	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART2 	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART3	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART4	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART5 	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_USART6 	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_CAN1 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_CAN2 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM12 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM13 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_TIM14 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_OTG_FS 	((AF10 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_OTG_HS 	((AF10 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_ETH		((AF11 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_FSMC 	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_SDIO 	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_OTG_HS_FS	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_DCMI 	((AF13 << _GPIO_AF_SHIFT) | GPIO_AF)
-#define AF_EVENTOUT	((AF14 << _GPIO_AF_SHIFT) | GPIO_AF)
-
-typedef struct {
-	GPIO_TypeDef *port;
-	uint8_t pin;
-	uint16_t flags;
-} gpio_pindef_t;
-
-#include "board.h"
-
-gpio_pindef_t gpio_pins[GPIO_TOTAL_COUNT];
-
-/*
- * GPIO register bitmasks
- */
-#define GPIO_MODER_MASK		0x03
-#define GPIO_TYPER_MASK		0x01
-#define GPIO_SPEEDR_MASK	0x03
-#define GPIO_PUPDR_MASK		0x03
-#define GPIO_AFR_MASK		0x0f
-
-/* 
- * Port configuration values.
- * A configuration is passing to gpio_hw_config_pin() bitwise in
- * a 16-bit 'conf' parameter where low byte representing a port
- * configuration and high using only for representing a number of an
- * alternative function (if GPIO_MODE_AF is chosen).
- * Shifts is using to encode/decode the config bits to/from 'conf'.
- */
-#define GPIO_MODE_CFG_SHIFT	0
-#define GPIO_TYPE_CFG_SHIFT 	2
-#define GPIO_SPEED_CFG_SHIFT 	4
-#define GPIO_PUPD_CFG_SHIFT	6
-
-#define GPIO_MODE_IN_CFG	(0x00 << GPIO_MODE_CFG_SHIFT)
-#define GPIO_MODE_OUT_CFG	(0x01 << GPIO_MODE_CFG_SHIFT)
-#define GPIO_MODE_AF_CFG	(0x02 << GPIO_MODE_CFG_SHIFT)
-#define GPIO_MODE_ANALOG_CFG	(0x03 << GPIO_MODE_CFG_SHIFT)
-#define GPIO_TYPE_PP_CFG	(0x00 << GPIO_TYPE_CFG_SHIFT)
-#define GPIO_TYPE_OD_CFG	(0x01 << GPIO_TYPE_CFG_SHIFT)
-#define GPIO_SPEED_LOW_CFG	(0x00 << GPIO_SPEED_CFG_SHIFT)
-#define GPIO_SPEED_MED_CFG	(0x01 << GPIO_SPEED_CFG_SHIFT)
-#define GPIO_SPEED_FAST_CFG	(0x02 << GPIO_SPEED_CFG_SHIFT)
-#define GPIO_SPEED_HIGH_CFG	(0x03 << GPIO_SPEED_CFG_SHIFT)
-#define GPIO_PU_CFG		(0x01 << GPIO_PUPD_CFG_SHIFT)
-#define GPIO_PD_CFG		(0x02 << GPIO_PUPD_CFG_SHIFT)
-
-void gpio_init(void);
-void gpio_set(gpio_t pin, bool value);
-void gpio_invert_output(gpio_t pin);
-bool gpio_get(gpio_t pin);
-bool gpio_is_output(gpio_t pin);
-void gpio_set_direction(gpio_t pin, bool out);
-void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf);
-//void gpio_connect_af(GPIO_TypeDef *port, uint8_t pin, uint8_t af);
-void gpio_connect_af(gpio_t id, uint8_t af_n);
-void exti_handler(void);
-void gpio_test(void);
-
-#endif /* GPIO_H */
+#ifndef GPIO_H
+#define GPIO_H
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#define GLITCH_TIMEOUT 200
+
+
+/* 
+ * Alternative function numbers definitions
+ */
+enum af_n {AF0 = 0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
+	   AF8, AF9, AF10, AF11, AF12, AF13, AF14, AF15};
+
+
+#define _GPIO_AF_SHIFT   10
+/* Flags for gpio init */
+#define GPIO_IN		0x01
+#define GPIO_IN_PU	0x02
+#define GPIO_OUT	0x04
+#define GPIO_SET	0x08
+#define GPIO_INV	0x10
+#define GPIO_OD		0x20
+#define GPIO_BKP	0x40
+#define GPIO_NOINIT	0x80
+#define GPIO_DIR_CHANGE	0x100
+#define GPIO_AF		0x200
+#define AF_TIM1		((AF1 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM2  	((AF1 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM3  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM4  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM5  	((AF2 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM8  	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM9  	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM10 	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM11 	((AF3 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_I2C1 	((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_I2C2		((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_I2C3 	((AF4 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_SPI1 	((AF5 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_SPI2 	((AF5 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_SPI3 	((AF6 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART1 	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART2 	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART3	((AF7 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART4	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART5 	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_USART6 	((AF8 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_CAN1 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_CAN2 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM12 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM13 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_TIM14 	((AF9 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_OTG_FS 	((AF10 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_OTG_HS 	((AF10 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_ETH		((AF11 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_FSMC 	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_SDIO 	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_OTG_HS_FS	((AF12 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_DCMI 	((AF13 << _GPIO_AF_SHIFT) | GPIO_AF)
+#define AF_EVENTOUT	((AF14 << _GPIO_AF_SHIFT) | GPIO_AF)
+
+typedef struct {
+	GPIO_TypeDef *port;
+	uint8_t pin;
+	uint16_t flags;
+} gpio_pindef_t;
+
+#include "board.h"
+
+extern gpio_pindef_t gpio_pins[GPIO_TOTAL_COUNT];
+
+/*
+ * GPIO register bitmasks
+ */
+#define GPIO_MODER_MASK		0x03
+#define GPIO_TYPER_MASK		0x01
+#define GPIO_SPEEDR_MASK	0x03
+#define GPIO_PUPDR_MASK		0x03
+#define GPIO_AFR_MASK		0x0f
+
+/* 
+ * Port configuration values.
+ * A configuration is passing to gpio_hw_config_pin() bitwise in
+ * a 16-bit 'conf' parameter where low byte representing a port
+ * configuration and high using only for representing a number of an
+ * alternative function (if GPIO_MODE_AF is chosen).
+ * Shifts is using to encode/decode the config bits to/from 'conf'.
+ */
+#define GPIO_MODE_CFG_SHIFT	0
+#define GPIO_TYPE_CFG_SHIFT 	2
+#define GPIO_SPEED_CFG_SHIFT 	4
+#define GPIO_PUPD_CFG_SHIFT	6
+
+#define GPIO_MODE_IN_CFG	(0x00 << GPIO_MODE_CFG_SHIFT)
+#define GPIO_MODE_OUT_CFG	(0x01 << GPIO_MODE_CFG_SHIFT)
+#define GPIO_MODE_AF_CFG	(0x02 << GPIO_MODE_CFG_SHIFT)
+#define GPIO_MODE_ANALOG_CFG	(0x03 << GPIO_MODE_CFG_SHIFT)
+#define GPIO_TYPE_PP_CFG	(0x00 << GPIO_TYPE_CFG_SHIFT)
+#define GPIO_TYPE_OD_CFG	(0x01 << GPIO_TYPE_CFG_SHIFT)
+#define GPIO_SPEED_LOW_CFG	(0x00 << GPIO_SPEED_CFG_SHIFT)
+#define GPIO_SPEED_MED_CFG	(0x01 << GPIO_SPEED_CFG_SHIFT)
+#define GPIO_SPEED_FAST_CFG	(0x02 << GPIO_SPEED_CFG_SHIFT)
+#define GPIO_SPEED_HIGH_CFG	(0x03 << GPIO_SPEED_CFG_SHIFT)
+#define GPIO_PU_CFG		(0x01 << GPIO_PUPD_CFG_SHIFT)
+#define GPIO_PD_CFG		(0x02 << GPIO_PUPD_CFG_SHIFT)
+
+void gpio_init(void);
+void gpio_set(gpio_t pin, bool value);
+void gpio_invert_output(gpio_t pin);
+bool gpio_get(gpio_t pin);
+bool gpio_is_output(gpio_t pin);
+void gpio_set_direction(gpio_t pin, bool out);
+void gpio_hw_config_pin(GPIO_TypeDef *port, uint8_t pin, uint16_t conf);
+//void gpio_connect_af(GPIO_TypeDef *port, uint8_t pin, uint8_t af);
+void gpio_connect_af(gpio_t id, uint8_t af_n);
+void exti_handler(void);
+void gpio_test(void);
+
+#endif /* GPIO_H */

+ 38 - 36
peripheral_modules/inc/spi_flash.h

@@ -1,36 +1,38 @@
-#ifndef SPI_FLASH_H
-#define SPI_FLASH_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef PRINTF_STDLIB
-#include <stdio.h>
-#endif
-#ifdef PRINTF_CUSTOM
-#include "tinystdio.h"
-#endif
-
-#define SPI_FLASH_SECTOR_SIZE		        4096
-#define SPI_FLASH_SECTORS_IN_BLOCK_NUMBER   16
-#define SPI_FLASH_BLOCK_SIZE                4
-#define SPI_FLASH_BLOCK_NUMBER		        32
-
-typedef struct {
-	bool present;
-//	uint16_t sector_size;
-	uint32_t sector_size;
-	uint8_t sector_erase_op;
-	uint16_t sector_count;
-} spi_flash_desc_t;
-
-extern spi_flash_desc_t spi_flash_desc;
-
-extern bool spi_flash_init(void);
-extern ssize_t spi_flash_read(int addr, void *buf, size_t len, uint32_t timeout);
-extern ssize_t spi_flash_write(int addr, const void *buf, size_t len, uint32_t timeout);
-extern int spi_flash_erase_sector(int addr, uint32_t timeout);
-extern int spi_flash_chip_erase(uint32_t timeout);
-extern void spi_flash_test(void);
-#endif /* SPI_FLASH_H */
+#ifndef SPI_FLASH_H
+#define SPI_FLASH_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+
+#define SPI_FLASH_SECTOR_SIZE		        4096
+#define SPI_FLASH_SECTORS_IN_BLOCK_NUMBER   16
+#define SPI_FLASH_BLOCK_SIZE                4
+#define SPI_FLASH_BLOCK_NUMBER		        32
+
+typedef uint32_t ssize_t;
+
+typedef struct {
+	bool present;
+//	uint16_t sector_size;
+	uint32_t sector_size;
+	uint8_t sector_erase_op;
+	uint16_t sector_count;
+} spi_flash_desc_t;
+
+extern spi_flash_desc_t spi_flash_desc;
+
+extern bool spi_flash_init(void);
+extern ssize_t spi_flash_read(int addr, void *buf, size_t len, uint32_t timeout);
+extern ssize_t spi_flash_write(int addr, const void *buf, size_t len, uint32_t timeout);
+extern int spi_flash_erase_sector(int addr, uint32_t timeout);
+extern int spi_flash_chip_erase(uint32_t timeout);
+extern void spi_flash_test(void);
+#endif /* SPI_FLASH_H */

+ 385 - 0
peripheral_modules/inc/unistd.h

@@ -0,0 +1,385 @@
+/* Checking macros for unistd functions.
+   Copyright (C) 2005-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _UNISTD_H
+# error "Never include <bits/unistd.h> directly; use <unistd.h> instead."
+#endif
+
+extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
+			   size_t __buflen) __wur;
+extern ssize_t __REDIRECT (__read_alias, (int __fd, void *__buf,
+					  size_t __nbytes), read) __wur;
+extern ssize_t __REDIRECT (__read_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    size_t __buflen), __read_chk)
+     __wur __warnattr ("read called with bigger length than size of "
+		       "the destination buffer");
+
+__fortify_function __wur ssize_t
+read (int __fd, void *__buf, size_t __nbytes)
+{
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
+
+      if (__nbytes > __bos0 (__buf))
+	return __read_chk_warn (__fd, __buf, __nbytes, __bos0 (__buf));
+    }
+  return __read_alias (__fd, __buf, __nbytes);
+}
+
+#ifdef __USE_UNIX98
+extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
+			    __off_t __offset, size_t __bufsize) __wur;
+extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes,
+			      __off64_t __offset, size_t __bufsize) __wur;
+extern ssize_t __REDIRECT (__pread_alias,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off_t __offset), pread) __wur;
+extern ssize_t __REDIRECT (__pread64_alias,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off64_t __offset), pread64) __wur;
+extern ssize_t __REDIRECT (__pread_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off_t __offset, size_t __bufsize), __pread_chk)
+     __wur __warnattr ("pread called with bigger length than size of "
+		       "the destination buffer");
+extern ssize_t __REDIRECT (__pread64_chk_warn,
+			   (int __fd, void *__buf, size_t __nbytes,
+			    __off64_t __offset, size_t __bufsize),
+			    __pread64_chk)
+     __wur __warnattr ("pread64 called with bigger length than size of "
+		       "the destination buffer");
+
+# ifndef __USE_FILE_OFFSET64
+__fortify_function __wur ssize_t
+pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
+{
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread_chk_warn (__fd, __buf, __nbytes, __offset,
+				 __bos0 (__buf));
+    }
+  return __pread_alias (__fd, __buf, __nbytes, __offset);
+}
+# else
+__fortify_function __wur ssize_t
+pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
+{
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+				   __bos0 (__buf));
+    }
+
+  return __pread64_alias (__fd, __buf, __nbytes, __offset);
+}
+# endif
+
+# ifdef __USE_LARGEFILE64
+__fortify_function __wur ssize_t
+pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
+{
+  if (__bos0 (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__nbytes))
+	return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+      if ( __nbytes > __bos0 (__buf))
+	return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+				   __bos0 (__buf));
+    }
+
+  return __pread64_alias (__fd, __buf, __nbytes, __offset);
+}
+# endif
+#endif
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K
+extern ssize_t __readlink_chk (const char *__restrict __path,
+			       char *__restrict __buf, size_t __len,
+			       size_t __buflen)
+     __THROW __nonnull ((1, 2)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlink_alias,
+			       (const char *__restrict __path,
+				char *__restrict __buf, size_t __len), readlink)
+     __nonnull ((1, 2)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlink_chk_warn,
+			       (const char *__restrict __path,
+				char *__restrict __buf, size_t __len,
+				size_t __buflen), __readlink_chk)
+     __nonnull ((1, 2)) __wur __warnattr ("readlink called with bigger length "
+					  "than size of destination buffer");
+
+__fortify_function __nonnull ((1, 2)) __wur ssize_t
+__NTH (readlink (const char *__restrict __path, char *__restrict __buf,
+		 size_t __len))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __readlink_chk (__path, __buf, __len, __bos (__buf));
+
+      if ( __len > __bos (__buf))
+	return __readlink_chk_warn (__path, __buf, __len, __bos (__buf));
+    }
+  return __readlink_alias (__path, __buf, __len);
+}
+#endif
+
+#ifdef __USE_ATFILE
+extern ssize_t __readlinkat_chk (int __fd, const char *__restrict __path,
+				 char *__restrict __buf, size_t __len,
+				 size_t __buflen)
+     __THROW __nonnull ((2, 3)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlinkat_alias,
+			       (int __fd, const char *__restrict __path,
+				char *__restrict __buf, size_t __len),
+			       readlinkat)
+     __nonnull ((2, 3)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlinkat_chk_warn,
+			       (int __fd, const char *__restrict __path,
+				char *__restrict __buf, size_t __len,
+				size_t __buflen), __readlinkat_chk)
+     __nonnull ((2, 3)) __wur __warnattr ("readlinkat called with bigger "
+					  "length than size of destination "
+					  "buffer");
+
+__fortify_function __nonnull ((2, 3)) __wur ssize_t
+__NTH (readlinkat (int __fd, const char *__restrict __path,
+		   char *__restrict __buf, size_t __len))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
+
+      if (__len > __bos (__buf))
+	return __readlinkat_chk_warn (__fd, __path, __buf, __len,
+				      __bos (__buf));
+    }
+  return __readlinkat_alias (__fd, __path, __buf, __len);
+}
+#endif
+
+extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
+     __THROW __wur;
+extern char *__REDIRECT_NTH (__getcwd_alias,
+			     (char *__buf, size_t __size), getcwd) __wur;
+extern char *__REDIRECT_NTH (__getcwd_chk_warn,
+			     (char *__buf, size_t __size, size_t __buflen),
+			     __getcwd_chk)
+     __wur __warnattr ("getcwd caller with bigger length than size of "
+		       "destination buffer");
+
+__fortify_function __wur char *
+__NTH (getcwd (char *__buf, size_t __size))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size))
+	return __getcwd_chk (__buf, __size, __bos (__buf));
+
+      if (__size > __bos (__buf))
+	return __getcwd_chk_warn (__buf, __size, __bos (__buf));
+    }
+  return __getcwd_alias (__buf, __size);
+}
+
+#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
+extern char *__getwd_chk (char *__buf, size_t buflen)
+     __THROW __nonnull ((1)) __wur;
+extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd)
+     __nonnull ((1)) __wur __warnattr ("please use getcwd instead, as getwd "
+				       "doesn't specify buffer size");
+
+__fortify_function __nonnull ((1)) __attribute_deprecated__ __wur char *
+__NTH (getwd (char *__buf))
+{
+  if (__bos (__buf) != (size_t) -1)
+    return __getwd_chk (__buf, __bos (__buf));
+  return __getwd_warn (__buf);
+}
+#endif
+
+extern size_t __confstr_chk (int __name, char *__buf, size_t __len,
+			     size_t __buflen) __THROW;
+extern size_t __REDIRECT_NTH (__confstr_alias, (int __name, char *__buf,
+						size_t __len), confstr);
+extern size_t __REDIRECT_NTH (__confstr_chk_warn,
+			      (int __name, char *__buf, size_t __len,
+			       size_t __buflen), __confstr_chk)
+     __warnattr ("confstr called with bigger length than size of destination "
+		 "buffer");
+
+__fortify_function size_t
+__NTH (confstr (int __name, char *__buf, size_t __len))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+	return __confstr_chk (__name, __buf, __len, __bos (__buf));
+
+      if (__bos (__buf) < __len)
+	return __confstr_chk_warn (__name, __buf, __len, __bos (__buf));
+    }
+  return __confstr_alias (__name, __buf, __len);
+}
+
+
+extern int __getgroups_chk (int __size, __gid_t __list[], size_t __listlen)
+     __THROW __wur;
+extern int __REDIRECT_NTH (__getgroups_alias, (int __size, __gid_t __list[]),
+			   getgroups) __wur;
+extern int __REDIRECT_NTH (__getgroups_chk_warn,
+			   (int __size, __gid_t __list[], size_t __listlen),
+			   __getgroups_chk)
+     __wur __warnattr ("getgroups called with bigger group count than what "
+		       "can fit into destination buffer");
+
+__fortify_function int
+__NTH (getgroups (int __size, __gid_t __list[]))
+{
+  if (__bos (__list) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__size) || __size < 0)
+	return __getgroups_chk (__size, __list, __bos (__list));
+
+      if (__size * sizeof (__gid_t) > __bos (__list))
+	return __getgroups_chk_warn (__size, __list, __bos (__list));
+    }
+  return __getgroups_alias (__size, __list);
+}
+
+
+extern int __ttyname_r_chk (int __fd, char *__buf, size_t __buflen,
+			    size_t __nreal) __THROW __nonnull ((2));
+extern int __REDIRECT_NTH (__ttyname_r_alias, (int __fd, char *__buf,
+					       size_t __buflen), ttyname_r)
+     __nonnull ((2));
+extern int __REDIRECT_NTH (__ttyname_r_chk_warn,
+			   (int __fd, char *__buf, size_t __buflen,
+			    size_t __nreal), __ttyname_r_chk)
+     __nonnull ((2)) __warnattr ("ttyname_r called with bigger buflen than "
+				 "size of destination buffer");
+
+__fortify_function int
+__NTH (ttyname_r (int __fd, char *__buf, size_t __buflen))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __ttyname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
+    }
+  return __ttyname_r_alias (__fd, __buf, __buflen);
+}
+
+
+#if defined __USE_REENTRANT || defined __USE_POSIX199506
+extern int __getlogin_r_chk (char *__buf, size_t __buflen, size_t __nreal)
+     __nonnull ((1));
+extern int __REDIRECT (__getlogin_r_alias, (char *__buf, size_t __buflen),
+		       getlogin_r) __nonnull ((1));
+extern int __REDIRECT (__getlogin_r_chk_warn,
+		       (char *__buf, size_t __buflen, size_t __nreal),
+		       __getlogin_r_chk)
+     __nonnull ((1)) __warnattr ("getlogin_r called with bigger buflen than "
+				 "size of destination buffer");
+
+__fortify_function int
+getlogin_r (char *__buf, size_t __buflen)
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __getlogin_r_chk_warn (__buf, __buflen, __bos (__buf));
+    }
+  return __getlogin_r_alias (__buf, __buflen);
+}
+#endif
+
+
+#if defined __USE_BSD || defined __USE_UNIX98
+extern int __gethostname_chk (char *__buf, size_t __buflen, size_t __nreal)
+     __THROW __nonnull ((1));
+extern int __REDIRECT_NTH (__gethostname_alias, (char *__buf, size_t __buflen),
+			   gethostname) __nonnull ((1));
+extern int __REDIRECT_NTH (__gethostname_chk_warn,
+			   (char *__buf, size_t __buflen, size_t __nreal),
+			   __gethostname_chk)
+     __nonnull ((1)) __warnattr ("gethostname called with bigger buflen than "
+				 "size of destination buffer");
+
+__fortify_function int
+__NTH (gethostname (char *__buf, size_t __buflen))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __gethostname_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __gethostname_chk_warn (__buf, __buflen, __bos (__buf));
+    }
+  return __gethostname_alias (__buf, __buflen);
+}
+#endif
+
+
+#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98)
+extern int __getdomainname_chk (char *__buf, size_t __buflen, size_t __nreal)
+     __THROW __nonnull ((1)) __wur;
+extern int __REDIRECT_NTH (__getdomainname_alias, (char *__buf,
+						   size_t __buflen),
+			   getdomainname) __nonnull ((1)) __wur;
+extern int __REDIRECT_NTH (__getdomainname_chk_warn,
+			   (char *__buf, size_t __buflen, size_t __nreal),
+			   __getdomainname_chk)
+     __nonnull ((1)) __wur __warnattr ("getdomainname called with bigger "
+				       "buflen than size of destination "
+				       "buffer");
+
+__fortify_function int
+__NTH (getdomainname (char *__buf, size_t __buflen))
+{
+  if (__bos (__buf) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__buflen))
+	return __getdomainname_chk (__buf, __buflen, __bos (__buf));
+
+      if (__buflen > __bos (__buf))
+	return __getdomainname_chk_warn (__buf, __buflen, __bos (__buf));
+    }
+  return __getdomainname_alias (__buf, __buflen);
+}
+#endif

+ 395 - 387
peripheral_modules/src/spi_flash.c

@@ -1,387 +1,395 @@
-#include "stm32f4xx_conf.h"
-#include "stm32f4xx.h"
-
-#include "spi_flash.h"
-#include "gpio.h"
-
-/*
-struct {
-	uint8_t *tx;
-	uint8_t *rx;
-	uint16_t tx_len;
-	uint16_t rx_len;
-	uint8_t rx_skip;
-	TN_SEM ready;
-	TN_MUTEX busy;
-} xact;
-
-void SPI2_IRQHandler(void) {
-	uint32_t status = SPI2->SR;
-	uint8_t b;
-
-	if (!xact.tx_len && !xact.rx_len) {
-		SPI2->CR1 &= ~SPI_CR1_SPE;
-		SPI2->CR2 &= ~(SPI_CR2_TXEIE | SPI_CR2_RXNEIE);
-		tn_sem_isignal(&xact.ready);
-		return;
-	}
-
-	if (status & SPI_SR_RXNE) {
-		b = SPI2->DR;
-		if (!xact.tx_len) {
-			if (xact.rx_skip) {
-				xact.rx_skip--;
-			}
-			else if (xact.rx_len) {
-				*(xact.rx++) = b;
-				xact.rx_len--;
-			}
-		}
-	}
-
-	if (status & SPI_SR_TXE) {
-		if (xact.tx_len) {		// have smth for tx
-			SPI2->DR = *(xact.tx++);
-			xact.tx_len--;
-		}
-		else if (xact.rx_len) {
-			SPI2->DR = 0;
-		}
-	}
-}
-*/
-
-#define SPI_FLASH_CS_L() gpio_set(SPI2_NSS, 0)
-#define SPI_FLASH_CS_H() gpio_set(SPI2_NSS, 1)
-
-
-//static TN_MUTEX spi_mutex;
-
-static uint8_t spi_tx_rx(uint8_t byte) {
-	while (!(SPI2->SR & SPI_SR_TXE)) {}
-	SPI2->DR = byte;
-		
-	while (!(SPI2->SR & SPI_SR_RXNE)) {}
-	return SPI2->DR;
-}
-
-static void spi_cs_up(void) {
-	SPI2->CR1 &= ~SPI_CR1_SPE;
-//	GPIOB->BSRR = 1 << 12;
-}
-
-static void spi_cs_down(void) {
-//	GPIOB->BRR = 1 << 12;
-	SPI2->CR1 |= SPI_CR1_SPE;
-}
-
-static void spi_init_(void) {
-//	tn_mutex_create(&spi_mutex, TN_MUTEX_ATTR_INHERIT, 0);
-	//tn_sem_create(&xact.ready, 0, 1);
-
-	RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
-	RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST;
-	RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;
-
-	SPI2->CR1 &= ~SPI_CR1_SPE;
-	//SPI2->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI;
-	SPI2->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;
-	SPI2->CR2 = 0;//SPI_CR2_SSOE;
-	SPI2->CR1 |= SPI_CR1_SPE;
-}
-
-#define CMD_WREN	0x06
-#define CMD_WRDI	0x04
-#define CMD_WRSR	0x01
-#define CMD_RDSR	0x05
-#define CMD_READ	0x03
-#define CMD_SE		0x20
-#define CMD_BE		0x52
-#define CMD_CE		0x60
-#define CMD_PP		0x02
-#define CMD_RDSFDP	0x5A
-
-#define SR_WIP	(1 << 0)
-#define SR_WEL	(1 << 1)
-#define SR_SRWD	(1 << 7)
-
-spi_flash_desc_t spi_flash_desc;
-
-static inline void wait_write_enable(void) {
-	uint8_t status;
-//	spi_cs_down();
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_RDSR);
-	do {
-		status = spi_tx_rx(0);
-	} while (!(status & SR_WEL));
-//	spi_cs_up();
-	SPI_FLASH_CS_H();
-}
-
-static inline void wait_write_end(void) {
-	uint8_t status;
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_RDSR);
-	do {
-		status = spi_tx_rx(0);
-	} while (status & SR_WIP);
-	SPI_FLASH_CS_H();
-}
-
-static inline void send_addr(int addr) {
-	spi_tx_rx((addr >> 16) & 0xFF);
-	spi_tx_rx((addr >> 8) & 0xFF);
-	spi_tx_rx(addr & 0xFF);
-}
-
-static int spi_flash_read_sfdp(int addr, void *buf, size_t len) {
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_RDSFDP);
-	send_addr(addr);
-	spi_tx_rx(0);
-	while (len--)
-		*((uint8_t *)buf++) = spi_tx_rx(0);
-	SPI_FLASH_CS_H();
-	return 0;
-}
-
-ssize_t spi_flash_read(int addr, void *buf, size_t len, uint32_t timeout) {
-	ssize_t ret = 0;
-//	ret = tn_mutex_lock(&spi_mutex, timeout);
-//	if (ret != TERR_NO_ERR)
-//		return ret;
-
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_READ);
-	send_addr(addr);
-	while (len--)
-		*((uint8_t *)buf++) = spi_tx_rx(0);
-	SPI_FLASH_CS_H();
-//	tn_mutex_unlock(&spi_mutex);
-	return len;
-}
-
-#define TIMEOUT 10000
-
-uint16_t spi_flash_pp(int addr, const void *buf, size_t len, uint32_t timeout) {
-//	ret = tn_mutex_lock(&spi_mutex, timeout);
-//	if (ret != TERR_NO_ERR)
-//		return ret;
-	// don't allow page wrapping
-	ssize_t ret = 0;
-	if ((addr & 0xFF) + len > 0xFF)
-	    len = 0x100 - (addr & 0xFF);
-	ret = len;
-
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_WREN);
-	SPI_FLASH_CS_H();
-
-	wait_write_enable();
-
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_PP);
-	send_addr(addr);
-	while (len--)
-	    spi_tx_rx(*((uint8_t *)buf++));
-	SPI_FLASH_CS_H();
-
-	wait_write_end();
-
-//	tn_mutex_unlock(&spi_mutex);
-	return ret;
-}
-
-ssize_t spi_flash_write(int addr, const void *buf, size_t len, uint32_t timeout) {
-	int ret = 0, offset = 0;
-	do {
-	    ret = spi_flash_pp(addr + offset, buf + offset, len - offset, 0);
-	    offset += ret;
-	} while (len - offset);
-	return 0;
-}
-
-int spi_flash_chip_erase(uint32_t timeout) {
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_WREN);
-	SPI_FLASH_CS_H();
-	wait_write_enable();
-
-    	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_CE);
-	SPI_FLASH_CS_H();
-
-	wait_write_end();
-	return 0;
-}
-
-int spi_flash_erase_sector(int addr, uint32_t timeout) {
-	int ret = 0;
-//	ret = tn_mutex_lock(&spi_mutex, timeout);
-//	if (ret != TERR_NO_ERR)
-//		return ret;
-
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_WREN);
-	SPI_FLASH_CS_H();
-
-	wait_write_enable();
-
-	SPI_FLASH_CS_L();
-	spi_tx_rx(CMD_SE);
-	send_addr(addr);
-	SPI_FLASH_CS_H();
-
-	wait_write_end();
-
-//	tn_mutex_unlock(&spi_mutex);
-	return 0;
-}
-
-bool spi_flash_init(void) {
-	uint32_t i, ptable, bitsize = 0;
-	uint8_t tmp[4];
-
-	spi_flash_desc.present = false;
-
-	spi_init_();
-
-	// check SFDP magic
-	spi_flash_read_sfdp(0, tmp, 4);
-	if (!(tmp[0] == 0x53 && tmp[1] == 0x46 && 
-		tmp[2] == 0x44 && tmp[3] == 0x50))
-		return 0;
-
-	return 1;
-
-/*
-	// get parameter headers count
-	spi_flash_read_sfdp(0x06, tmp, 1);
-
-	// find first jedec pheader (with ID == 0)
-	for (ptable = 0x08, i = 0; i <= tmp[0]; i++, ptable += 8) {
-		spi_flash_read_sfdp(ptable, tmp, 1);
-		if (tmp[0] == 0)
-			break;
-	}
-
-	// read ptable pointer from pheader
-	spi_flash_read_sfdp(ptable + 4, &ptable, 3);
-
-	// get flash density (size in bits)
-	if (spi_flash_read_sfdp(ptable + 4, &bitsize, 4) < 0 || !bitsize)
-		return;
-
-	// find smallest available sector
-	for (i = 0; i < 4; i++) {
-		tmp[0] = 0;
-		if (spi_flash_read_sfdp(ptable + 0x1C + i*2, &tmp, 2) >= 0 &&
-				tmp[0]) {
-			spi_flash_desc.sector_size = 1 << tmp[0];
-			spi_flash_desc.sector_erase_op = tmp[1];
-			spi_flash_desc.sector_count = (bitsize + 1) >> (3 + tmp[0]);
-			break;
-		}
-	}
-	if (!spi_flash_desc.sector_size)
-		return;
-
-	spi_flash_desc.present = true;
-*/
-}
-
-uint8_t txbuf1[] = "This film came out on DVD yesterday and I rushed to buy it. \
-		    This version is the first to render all the detail and perfection \
-		    of Jack Cardiff's amazing compositions and brilliant, varied photography. \
-		    As a collection of memorable images, this film is better than any comparable \
-		    historical epic of the period and even gives GWTW a run for its money. \
-		    King Vidor's direction is a series of 'tableaux vivants' where the \
-		    characters are not posing but acting in a very natural, period-specific way. \
-		    I have never had a problem with this adaptation of Tolstoy's novel. \
-		    I think it is a wonderful introduction to the period and the novel and that \
-		    it is a very poetic, very original work in its own right. Henry Fonda's \
-		    characterization is especially moving, including great memorable interactions \
-		    with/reations to Mel Ferrer, Audrey Hepburn, Helmut Dantine and John Mills, but \
-		    all members of the cast are actually perfect. The harrowing last 45 minutes of \
-		    the film manage to convey a sense of history, a sense of grandeur as well as to \
-		    communicate very clearly Tolstoy's ideas about the meaning of life, by relying \
-		    mostly on the power of memorable images. The most conspicuous handicap of this movie, \
-		    in my opinion, is its soundtrack (in glorious mono). The barely hi-fi recording of \
-		    dialogues and music sounds pinched, hollow and tinny and it always has in very version \
-		    I have ever seen: in the theatres, on TV and on video. Even the soundtrack album is \
-		    an atrocity. In some scenes, before the necessary adjustments of bass and treble, \
-		    Audrey Hepburn's and Mel Ferrer's voices actually hurt your ear. Nino Rota's very \
-		    Russian-sounding score is serviceable and melodic, although rather sparse in its \
-		    orchestration and in the number of players. One can only wonder what 'War and Peace' \
-		    could have sounded like with a cohort of Hollywood arrangers, decent recording facilities \
-		    and lavish, varied orchestrations in true high fidelity and stereophonic sound. \
-		    According to Lukas Kendall of 'Film Score Monthly', the original recording elements \
-		    of the soundtrack have long ago disappeared, which is the common lot of international, \
-		    independent co-productions of the era. Someone somewhere is certainly guilty of \
-		    skimping on quality or embezzlement for this 1956 movie to sound so much worse \
-		    than a 1939, pre-hi-fi epic like GWTW. Like all VistaVision films, this one was \
-		    meant to be shown in Perspecta Stereophonic Sound where the mono dialog track was \
-		    meant to be channelled to three different directions, making it directional, while \
-		    the separate mono music + sound effects track was generally directed to all three \
-		    speakers at the same time. The results fooled the viewers into thinking everything \
-		    was in true stereo and the reproduction of the music was usually in very high fidelity. \
-		    Maybe the soundtrack used on the DVD is a mono reduction of those two separate tracks \
-		    that has squandered that fidelity and maybe the DVD can be issued again with better \
-		    results in some kind of 4.0 presentation. When they do, very little electronic \
-		    restoration work will be needed to make the image absolutely perfect. \
-		    But let's concentrate on the positive: This film is a summit of visual \
-		    splendour and its sets, costumes, colour photography, composition and lighting \
-		    achieve, in every single scene, wonders of artistry, creativity and delicacy \
-		    that will probably never be equalled. Suffice it to say that it has, \
-		    among many other treasures, a sunrise duel scene in the snow that still has viewers \
-		    wondering whether it was shot outdoors or in a studio and that will have them wondering forever.\r\n";
-
-uint8_t txbuf2[] = "STM32F4xx SPI Firmware Library Example: communication with an M25P SPI FLASH\r\n";
-
-#define countof(a) (sizeof(a) / sizeof(*(a)))
-#define  bufsize1 (countof(txbuf1)-1)
-#define  bufsize2 (countof(txbuf2)-1)
-
-uint8_t  rxbuf1[bufsize1] = {0};
-uint8_t  rxbuf2[bufsize2] = {0};
-
-void spi_flash_test(void) {
-    if (!spi_flash_init())
-	return;
-    int ret = 0, addr = 0, offset = 0;
-
-    spi_flash_read(0, rxbuf1, bufsize1, 0);
-    spi_flash_erase_sector(0,0);
-    spi_flash_read(0, rxbuf1, bufsize1, 0);
-    
-    spi_flash_write(addr, txbuf1, bufsize1, 0);
-
-    memset(rxbuf1, 0, bufsize1);
-    spi_flash_read(0, rxbuf1, bufsize1, 0);
-
-    if (memcmp(txbuf1, rxbuf1, bufsize1) != 0)
-	return;
-
-    spi_flash_erase_sector(0,0);
-    spi_flash_read(0, rxbuf1, bufsize1, 0);
-
-    spi_flash_write(0, txbuf2, bufsize2, 0);
-
-    memset(rxbuf2, 0, bufsize2);
-    spi_flash_read(0, rxbuf2, bufsize2, 0);
-
-
-/*
- * TODO restore spi_flash_init();
-	spi_flash_init();
-	if (!spi_flash_desc.present)
-		return -1;
-	printf("\tPresent: %d sectors, %d bytes per sector (%d bytes total)\n",
-		spi_flash_desc.sector_count,
-		spi_flash_desc.sector_size,
-		spi_flash_desc.sector_size * spi_flash_desc.sector_count);
-	return 0;
-*/
-    
-}
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+
+#include "spi_flash.h"
+#include "gpio.h"
+
+/*
+struct {
+	uint8_t *tx;
+	uint8_t *rx;
+	uint16_t tx_len;
+	uint16_t rx_len;
+	uint8_t rx_skip;
+	TN_SEM ready;
+	TN_MUTEX busy;
+} xact;
+
+void SPI2_IRQHandler(void) {
+	uint32_t status = SPI2->SR;
+	uint8_t b;
+
+	if (!xact.tx_len && !xact.rx_len) {
+		SPI2->CR1 &= ~SPI_CR1_SPE;
+		SPI2->CR2 &= ~(SPI_CR2_TXEIE | SPI_CR2_RXNEIE);
+		tn_sem_isignal(&xact.ready);
+		return;
+	}
+
+	if (status & SPI_SR_RXNE) {
+		b = SPI2->DR;
+		if (!xact.tx_len) {
+			if (xact.rx_skip) {
+				xact.rx_skip--;
+			}
+			else if (xact.rx_len) {
+				*(xact.rx++) = b;
+				xact.rx_len--;
+			}
+		}
+	}
+
+	if (status & SPI_SR_TXE) {
+		if (xact.tx_len) {		// have smth for tx
+			SPI2->DR = *(xact.tx++);
+			xact.tx_len--;
+		}
+		else if (xact.rx_len) {
+			SPI2->DR = 0;
+		}
+	}
+}
+*/
+
+#define SPI_FLASH_CS_L() gpio_set(SPI2_NSS, 0)
+#define SPI_FLASH_CS_H() gpio_set(SPI2_NSS, 1)
+
+
+//static TN_MUTEX spi_mutex;
+
+static uint8_t spi_tx_rx(uint8_t byte) {
+	while (!(SPI2->SR & SPI_SR_TXE)) {}
+	SPI2->DR = byte;
+		
+	while (!(SPI2->SR & SPI_SR_RXNE)) {}
+	return SPI2->DR;
+}
+
+static void spi_cs_up(void) {
+	SPI2->CR1 &= ~SPI_CR1_SPE;
+//	GPIOB->BSRR = 1 << 12;
+}
+
+static void spi_cs_down(void) {
+//	GPIOB->BRR = 1 << 12;
+	SPI2->CR1 |= SPI_CR1_SPE;
+}
+
+static void spi_init_(void) {
+//	tn_mutex_create(&spi_mutex, TN_MUTEX_ATTR_INHERIT, 0);
+	//tn_sem_create(&xact.ready, 0, 1);
+
+	RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
+	RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST;
+	RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;
+
+	SPI2->CR1 &= ~SPI_CR1_SPE;
+	//SPI2->CR1 = SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_SSM | SPI_CR1_SSI;
+	SPI2->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;
+	SPI2->CR2 = 0;//SPI_CR2_SSOE;
+	SPI2->CR1 |= SPI_CR1_SPE;
+}
+
+#define CMD_WREN	0x06
+#define CMD_WRDI	0x04
+#define CMD_WRSR	0x01
+#define CMD_RDSR	0x05
+#define CMD_READ	0x03
+#define CMD_SE		0x20
+#define CMD_BE		0x52
+#define CMD_CE		0x60
+#define CMD_PP		0x02
+#define CMD_RDSFDP	0x5A
+
+#define SR_WIP	(1 << 0)
+#define SR_WEL	(1 << 1)
+#define SR_SRWD	(1 << 7)
+
+spi_flash_desc_t spi_flash_desc;
+
+static inline void wait_write_enable(void) {
+	uint8_t status;
+//	spi_cs_down();
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_RDSR);
+	do {
+		status = spi_tx_rx(0);
+	} while (!(status & SR_WEL));
+//	spi_cs_up();
+	SPI_FLASH_CS_H();
+}
+
+static inline void wait_write_end(void) {
+	uint8_t status;
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_RDSR);
+	do {
+		status = spi_tx_rx(0);
+	} while (status & SR_WIP);
+	SPI_FLASH_CS_H();
+}
+
+static inline void send_addr(int addr) {
+	spi_tx_rx((addr >> 16) & 0xFF);
+	spi_tx_rx((addr >> 8) & 0xFF);
+	spi_tx_rx(addr & 0xFF);
+}
+
+static int spi_flash_read_sfdp(int addr, void *buf, size_t len) {
+    uint8_t* foo = (uint8_t *)buf;
+    SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_RDSFDP);
+	send_addr(addr);
+	spi_tx_rx(0);
+	while (len--)
+		//*((uint8_t *)buf++) = spi_tx_rx(0);
+      *(foo++) = spi_tx_rx(0);
+    SPI_FLASH_CS_H();
+	return 0;
+}
+
+ssize_t spi_flash_read(int addr, void *buf, size_t len, uint32_t timeout) {
+    uint8_t* foo = (uint8_t *)buf;
+	ssize_t ret = 0;
+//	ret = tn_mutex_lock(&spi_mutex, timeout);
+//	if (ret != TERR_NO_ERR)
+//		return ret;
+
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_READ);
+	send_addr(addr);
+	while (len--)
+		//*((uint8_t *)buf++) = spi_tx_rx(0);
+        *(foo++) = spi_tx_rx(0);
+	SPI_FLASH_CS_H();
+//	tn_mutex_unlock(&spi_mutex);
+	return len;
+}
+
+#define TIMEOUT 10000
+
+uint16_t spi_flash_pp(int addr, const void *buf, size_t len, uint32_t timeout) {
+//	ret = tn_mutex_lock(&spi_mutex, timeout);
+//	if (ret != TERR_NO_ERR)
+//		return ret;
+	// don't allow page wrapping
+    uint8_t* foo = (uint8_t *)buf;
+	ssize_t ret = 0;
+	if ((addr & 0xFF) + len > 0xFF)
+	    len = 0x100 - (addr & 0xFF);
+	ret = len;
+
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_WREN);
+	SPI_FLASH_CS_H();
+
+	wait_write_enable();
+
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_PP);
+	send_addr(addr);
+	while (len--)
+	    //spi_tx_rx(*((uint8_t *)buf++));
+        spi_tx_rx(*(foo++));
+	SPI_FLASH_CS_H();
+
+	wait_write_end();
+
+//	tn_mutex_unlock(&spi_mutex);
+	return ret;
+}
+
+ssize_t spi_flash_write(int addr, const void *buf, size_t len, uint32_t timeout) {
+    uint8_t* foo = (uint8_t *)buf;
+	int ret = 0, offset = 0;
+	do {
+	    //ret = spi_flash_pp(addr + offset, buf + offset, len - offset, 0);
+        ret = spi_flash_pp(addr + offset, foo + offset, len - offset, 0);
+	    offset += ret;
+	} while (len - offset);
+	return 0;
+}
+
+int spi_flash_chip_erase(uint32_t timeout) {
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_WREN);
+	SPI_FLASH_CS_H();
+	wait_write_enable();
+
+    	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_CE);
+	SPI_FLASH_CS_H();
+
+	wait_write_end();
+	return 0;
+}
+
+int spi_flash_erase_sector(int addr, uint32_t timeout) {
+	int ret = 0;
+//	ret = tn_mutex_lock(&spi_mutex, timeout);
+//	if (ret != TERR_NO_ERR)
+//		return ret;
+
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_WREN);
+	SPI_FLASH_CS_H();
+
+	wait_write_enable();
+
+	SPI_FLASH_CS_L();
+	spi_tx_rx(CMD_SE);
+	send_addr(addr);
+	SPI_FLASH_CS_H();
+
+	wait_write_end();
+
+//	tn_mutex_unlock(&spi_mutex);
+	return 0;
+}
+
+bool spi_flash_init(void) {
+	uint32_t i, ptable, bitsize = 0;
+	uint8_t tmp[4];
+
+	spi_flash_desc.present = false;
+
+	spi_init_();
+
+	// check SFDP magic
+	spi_flash_read_sfdp(0, tmp, 4);
+	if (!(tmp[0] == 0x53 && tmp[1] == 0x46 && 
+		tmp[2] == 0x44 && tmp[3] == 0x50))
+		return 0;
+
+	return 1;
+
+/*
+	// get parameter headers count
+	spi_flash_read_sfdp(0x06, tmp, 1);
+
+	// find first jedec pheader (with ID == 0)
+	for (ptable = 0x08, i = 0; i <= tmp[0]; i++, ptable += 8) {
+		spi_flash_read_sfdp(ptable, tmp, 1);
+		if (tmp[0] == 0)
+			break;
+	}
+
+	// read ptable pointer from pheader
+	spi_flash_read_sfdp(ptable + 4, &ptable, 3);
+
+	// get flash density (size in bits)
+	if (spi_flash_read_sfdp(ptable + 4, &bitsize, 4) < 0 || !bitsize)
+		return;
+
+	// find smallest available sector
+	for (i = 0; i < 4; i++) {
+		tmp[0] = 0;
+		if (spi_flash_read_sfdp(ptable + 0x1C + i*2, &tmp, 2) >= 0 &&
+				tmp[0]) {
+			spi_flash_desc.sector_size = 1 << tmp[0];
+			spi_flash_desc.sector_erase_op = tmp[1];
+			spi_flash_desc.sector_count = (bitsize + 1) >> (3 + tmp[0]);
+			break;
+		}
+	}
+	if (!spi_flash_desc.sector_size)
+		return;
+
+	spi_flash_desc.present = true;
+*/
+}
+
+uint8_t txbuf1[] = "This film came out on DVD yesterday and I rushed to buy it. \
+		    This version is the first to render all the detail and perfection \
+		    of Jack Cardiff's amazing compositions and brilliant, varied photography. \
+		    As a collection of memorable images, this film is better than any comparable \
+		    historical epic of the period and even gives GWTW a run for its money. \
+		    King Vidor's direction is a series of 'tableaux vivants' where the \
+		    characters are not posing but acting in a very natural, period-specific way. \
+		    I have never had a problem with this adaptation of Tolstoy's novel. \
+		    I think it is a wonderful introduction to the period and the novel and that \
+		    it is a very poetic, very original work in its own right. Henry Fonda's \
+		    characterization is especially moving, including great memorable interactions \
+		    with/reations to Mel Ferrer, Audrey Hepburn, Helmut Dantine and John Mills, but \
+		    all members of the cast are actually perfect. The harrowing last 45 minutes of \
+		    the film manage to convey a sense of history, a sense of grandeur as well as to \
+		    communicate very clearly Tolstoy's ideas about the meaning of life, by relying \
+		    mostly on the power of memorable images. The most conspicuous handicap of this movie, \
+		    in my opinion, is its soundtrack (in glorious mono). The barely hi-fi recording of \
+		    dialogues and music sounds pinched, hollow and tinny and it always has in very version \
+		    I have ever seen: in the theatres, on TV and on video. Even the soundtrack album is \
+		    an atrocity. In some scenes, before the necessary adjustments of bass and treble, \
+		    Audrey Hepburn's and Mel Ferrer's voices actually hurt your ear. Nino Rota's very \
+		    Russian-sounding score is serviceable and melodic, although rather sparse in its \
+		    orchestration and in the number of players. One can only wonder what 'War and Peace' \
+		    could have sounded like with a cohort of Hollywood arrangers, decent recording facilities \
+		    and lavish, varied orchestrations in true high fidelity and stereophonic sound. \
+		    According to Lukas Kendall of 'Film Score Monthly', the original recording elements \
+		    of the soundtrack have long ago disappeared, which is the common lot of international, \
+		    independent co-productions of the era. Someone somewhere is certainly guilty of \
+		    skimping on quality or embezzlement for this 1956 movie to sound so much worse \
+		    than a 1939, pre-hi-fi epic like GWTW. Like all VistaVision films, this one was \
+		    meant to be shown in Perspecta Stereophonic Sound where the mono dialog track was \
+		    meant to be channelled to three different directions, making it directional, while \
+		    the separate mono music + sound effects track was generally directed to all three \
+		    speakers at the same time. The results fooled the viewers into thinking everything \
+		    was in true stereo and the reproduction of the music was usually in very high fidelity. \
+		    Maybe the soundtrack used on the DVD is a mono reduction of those two separate tracks \
+		    that has squandered that fidelity and maybe the DVD can be issued again with better \
+		    results in some kind of 4.0 presentation. When they do, very little electronic \
+		    restoration work will be needed to make the image absolutely perfect. \
+		    But let's concentrate on the positive: This film is a summit of visual \
+		    splendour and its sets, costumes, colour photography, composition and lighting \
+		    achieve, in every single scene, wonders of artistry, creativity and delicacy \
+		    that will probably never be equalled. Suffice it to say that it has, \
+		    among many other treasures, a sunrise duel scene in the snow that still has viewers \
+		    wondering whether it was shot outdoors or in a studio and that will have them wondering forever.\r\n";
+
+uint8_t txbuf2[] = "STM32F4xx SPI Firmware Library Example: communication with an M25P SPI FLASH\r\n";
+
+#define countof(a) (sizeof(a) / sizeof(*(a)))
+#define  bufsize1 (countof(txbuf1)-1)
+#define  bufsize2 (countof(txbuf2)-1)
+
+uint8_t  rxbuf1[bufsize1] = {0};
+uint8_t  rxbuf2[bufsize2] = {0};
+
+void spi_flash_test(void) {
+    if (!spi_flash_init())
+	return;
+    int ret = 0, addr = 0, offset = 0;
+
+    spi_flash_read(0, rxbuf1, bufsize1, 0);
+    spi_flash_erase_sector(0,0);
+    spi_flash_read(0, rxbuf1, bufsize1, 0);
+    
+    spi_flash_write(addr, txbuf1, bufsize1, 0);
+
+    memset(rxbuf1, 0, bufsize1);
+    spi_flash_read(0, rxbuf1, bufsize1, 0);
+
+    if (memcmp(txbuf1, rxbuf1, bufsize1) != 0)
+	return;
+
+    spi_flash_erase_sector(0,0);
+    spi_flash_read(0, rxbuf1, bufsize1, 0);
+
+    spi_flash_write(0, txbuf2, bufsize2, 0);
+
+    memset(rxbuf2, 0, bufsize2);
+    spi_flash_read(0, rxbuf2, bufsize2, 0);
+
+
+/*
+ * TODO restore spi_flash_init();
+	spi_flash_init();
+	if (!spi_flash_desc.present)
+		return -1;
+	printf("\tPresent: %d sectors, %d bytes per sector (%d bytes total)\n",
+		spi_flash_desc.sector_count,
+		spi_flash_desc.sector_size,
+		spi_flash_desc.sector_size * spi_flash_desc.sector_count);
+	return 0;
+*/
+    
+}

+ 2 - 1
peripheral_modules/src/usart.c

@@ -121,7 +121,8 @@ int ups_getchar(unsigned int timeout) {
 
 
 
-inline void rs232_irq_handler(void)
+//inline void rs232_irq_handler(void)
+void rs232_irq_handler(void)
 {
 	uint32_t c = 0;
 

+ 2387 - 0
projects/iar/bt-670x.ewp

@@ -0,0 +1,2387 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<project>
+  <fileVersion>2</fileVersion>
+  <configuration>
+    <name>Debug</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>1</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>24</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>ExePath</name>
+          <state>Debug\Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>Debug\Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>Debug\List</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input variant</name>
+          <version>3</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state>Full formatting.</state>
+        </option>
+        <option>
+          <name>Output variant</name>
+          <version>2</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state>Full formatting.</state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>2</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>2</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state>Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod.</state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>5.10.0.159</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>7.50.2.10499</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state>STM32F407VG	ST STM32F407VG</state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Full.h</state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>22</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GRuntimeLibThreads</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CoreVariant</name>
+          <version>22</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GFPUDeviceSlave</name>
+          <state>STM32F407VG	ST STM32F407VG</state>
+        </option>
+        <option>
+          <name>FPU2</name>
+          <version>0</version>
+          <state>4</state>
+        </option>
+        <option>
+          <name>NrRegs</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>NEON</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave2</name>
+          <version>22</version>
+          <state>39</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>31</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDefines</name>
+          <state>USE_STDPERIPH_DRIVER</state>
+          <state>STM32F407xx</state>
+          <state>HARDWARE_BT6702</state>
+          <state>OS_FREERTOS</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state>Pa050</state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>00000000</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state>$PROJ_DIR$\..\..\user</state>
+          <state>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\inc</state>
+          <state>$PROJ_DIR$\..\..\stm32\system</state>
+          <state>$PROJ_DIR$\..\..\config</state>
+          <state>$PROJ_DIR$\..\..\peripheral_modules\inc</state>
+          <state>$PROJ_DIR$\..\..\modules</state>
+          <state>$PROJ_DIR$\..\..\modules\common</state>
+          <state>$PROJ_DIR$\..\..\modules\buttons</state>
+          <state>$PROJ_DIR$\..\..\modules\leds</state>
+          <state>$PROJ_DIR$\..\..\modules\d_inouts</state>
+          <state>$PROJ_DIR$\..\..\modules\HTTP_Server</state>
+          <state>$PROJ_DIR$\..\..\modules\MegaTec</state>
+          <state>$PROJ_DIR$\..\..\modules\Ethernet</state>
+          <state>$PROJ_DIR$\..\..\modules\monitor</state>
+          <state>$PROJ_DIR$\..\..\modules\jumper</state>
+          <state>$PROJ_DIR$\..\..\modules\STM32F4x7_ETH_Driver</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\portable\IAR\ARM_CM4F</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\src\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\src\include\lwip</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\port\FreeRTOS</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\src\include\ipv4</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\port</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\lwip\arch</state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IInterwork2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCppDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccExceptions</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccRTTI</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCNoLiteralPool</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategySlave</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCGuardCalls</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>9</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>AMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\include</state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AsmNoLiteralPool</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>3</version>
+          <state>3</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state>bt-670x.bin</state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+        <hasPrio>0</hasPrio>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>16</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>c.out</state>
+        </option>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state>$PROJ_DIR$\stm32f407xG.icf</state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state>__iar_program_start</state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkThreadsSlave</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+  </configuration>
+  <configuration>
+    <name>Release</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>0</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>24</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>ExePath</name>
+          <state>Release\Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>Release\Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>Release\List</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input variant</name>
+          <version>3</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state></state>
+        </option>
+        <option>
+          <name>Output variant</name>
+          <version>2</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state></state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state></state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>5.10.0.159</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>7.50.2.0</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state></state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>22</version>
+          <state>38</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GRuntimeLibThreads</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CoreVariant</name>
+          <version>22</version>
+          <state>38</state>
+        </option>
+        <option>
+          <name>GFPUDeviceSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>FPU2</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>NrRegs</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>NEON</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave2</name>
+          <version>22</version>
+          <state>38</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>31</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDefines</name>
+          <state>NDEBUG</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>11111110</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IInterwork2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>3</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>3</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCppDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccExceptions</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccRTTI</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCNoLiteralPool</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategySlave</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCGuardCalls</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>9</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AsmNoLiteralPool</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>3</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+        <hasPrio>0</hasPrio>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>16</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>c.out</state>
+        </option>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state></state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkThreadsSlave</name>
+          <state>1</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>0</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+  </configuration>
+  <group>
+    <name>config</name>
+    <file>
+      <name>$PROJ_DIR$\..\..\config\board.h</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\config\board_bt6702.h</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\config\common_config.h</name>
+    </file>
+  </group>
+  <group>
+    <name>modules</name>
+    <group>
+      <name>buttons</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\buttons\buttons.c</name>
+      </file>
+    </group>
+    <group>
+      <name>common</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\common\ring_buf.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\common\urlcode.c</name>
+      </file>
+    </group>
+    <group>
+      <name>d_inouts</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\d_inouts\d_inouts.c</name>
+      </file>
+    </group>
+    <group>
+      <name>ethernet</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\netconf.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\private_mib.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\snmp_api.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\sntp.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\trap_api.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\Ethernet\udp_netsetting.c</name>
+      </file>
+    </group>
+    <group>
+      <name>http_server</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\HTTP_Server\http_server.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\HTTP_Server\web_params_api.c</name>
+      </file>
+    </group>
+    <group>
+      <name>jumper</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\jumper\jumper.c</name>
+      </file>
+    </group>
+    <group>
+      <name>leds</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\leds\led.c</name>
+      </file>
+    </group>
+    <group>
+      <name>megatec</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\MegaTec\megatec.c</name>
+      </file>
+    </group>
+    <group>
+      <name>monitor</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\monitor\ups_monitor.c</name>
+      </file>
+    </group>
+    <group>
+      <name>STM32F4x7_ETH_Driver</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\STM32F4x7_ETH_Driver\stm32f4x7_eth.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\STM32F4x7_ETH_Driver\stm32f4x7_eth_bsp.c</name>
+      </file>
+    </group>
+    <file>
+      <name>$PROJ_DIR$\..\..\modules\parameters.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\modules\settings_api.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\modules\wdg.c</name>
+    </file>
+  </group>
+  <group>
+    <name>peripheral_modules</name>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\gpio.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\rng.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\rtc.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\spi_flash.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\stm32_uid.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\peripheral_modules\src\usart.c</name>
+    </file>
+  </group>
+  <group>
+    <name>stm32</name>
+    <group>
+      <name>stm32f4x7_ethernet</name>
+    </group>
+    <group>
+      <name>stm32f4xx_spl</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\misc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_adc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_can.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_crc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_cryp.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_cryp_aes.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_cryp_des.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_cryp_tdes.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_dac.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_dbgmcu.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_dcmi.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_dma.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_exti.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_flash.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_fsmc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_gpio.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_hash.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_hash_md5.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_hash_sha1.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_i2c.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_iwdg.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_pwr.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_rcc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_rng.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_rtc.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_sdio.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_spi.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_syscfg.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_tim.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_usart.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\stm32f4xx_spl\src\stm32f4xx_wwdg.c</name>
+      </file>
+    </group>
+    <group>
+      <name>system</name>
+      <file>
+        <name>$PROJ_DIR$\startup_stm32f4xx.s</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\system\stm32f4xx.h</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\stm32\system\system_stm32f4xx.c</name>
+      </file>
+    </group>
+  </group>
+  <group>
+    <name>thirdparty</name>
+    <group>
+      <name>freertos</name>
+      <group>
+        <name>portable</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\portable\IAR\ARM_CM4F\port.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\portable\IAR\ARM_CM4F\portasm.s</name>
+        </file>
+      </group>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\croutine.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\event_groups.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\include\FreeRTOSConfig.h</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\portable\MemMang\heap_4.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\list.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\queue.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\tasks.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\timers.c</name>
+        <excluded>
+          <configuration>Debug</configuration>
+        </excluded>
+      </file>
+    </group>
+    <group>
+      <name>lwip</name>
+      <group>
+        <name>api</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\api_lib.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\api_msg.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\err.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\netbuf.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\netdb.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\netifapi.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\sockets.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\api\tcpip.c</name>
+        </file>
+      </group>
+      <group>
+        <name>core</name>
+        <group>
+          <name>ipv4</name>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\autoip.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\def.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\dhcp.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\dns.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\icmp.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\igmp.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\inet.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\inet_chksum.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\init.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\ip.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\ip_addr.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\ipv4\ip_frag.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\mem.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\memp.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\netif.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\pbuf.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\raw.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\stats.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\sys.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\tcp.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\tcp_in.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\tcp_out.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\timers.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\udp.c</name>
+          </file>
+        </group>
+        <group>
+          <name>snmp</name>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\asn1_dec.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\asn1_enc.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\mib2.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\mib_structs.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\msg_in.c</name>
+          </file>
+          <file>
+            <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\core\snmp\msg_out.c</name>
+          </file>
+        </group>
+      </group>
+      <group>
+        <name>netif</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\netif\etharp.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\src\netif\slipif.c</name>
+        </file>
+      </group>
+      <group>
+        <name>port</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\port\FreeRTOS\ethernetif.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\lwip\port\FreeRTOS\sys_arch.c</name>
+        </file>
+      </group>
+    </group>
+  </group>
+  <group>
+    <name>user</name>
+    <file>
+      <name>$PROJ_DIR$\..\..\user\init_task.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\user\main.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\..\user\stm32f4xx_it.c</name>
+    </file>
+  </group>
+</project>
+
+

+ 639 - 0
projects/iar/startup_stm32f4xx.s

@@ -0,0 +1,639 @@
+;/******************** (C) COPYRIGHT 2012 STMicroelectronics ********************
+;* File Name          : startup_stm32f4xx.s
+;* Author             : MCD Application Team
+;* Version            : V1.0.2
+;* Date               : 05-March-2012
+;* Description        : STM32F4xx devices vector table for EWARM toolchain.
+;*                      This module performs:
+;*                      - Set the initial SP
+;*                      - Set the initial PC == _iar_program_start,
+;*                      - Set the vector table entries with the exceptions ISR 
+;*                        address.
+;*                      - Configure the system clock and the external SRAM mounted on 
+;*                        STM324xG-EVAL board to be used as data memory (optional, 
+;*                        to be enabled by user)
+;*                      - Branches to main in the C library (which eventually
+;*                        calls main()).
+;*                      After Reset the Cortex-M4 processor is in Thread mode,
+;*                      priority is Privileged, and the Stack is set to Main.
+;********************************************************************************
+;* 
+;* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+;* You may not use this file except in compliance with the License.
+;* You may obtain a copy of the License at:
+;* 
+;*        http://www.st.com/software_license_agreement_liberty_v2
+;* 
+;* Unless required by applicable law or agreed to in writing, software 
+;* distributed under the License is distributed on an "AS IS" BASIS, 
+;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;* See the License for the specific language governing permissions and
+;* limitations under the License.
+;* 
+;*******************************************************************************/
+;
+;
+; The modules in this file are included in the libraries, and may be replaced
+; by any user-defined modules that define the PUBLIC symbol _program_start or
+; a user defined start symbol.
+; To override the cstartup defined in the library, simply add your modified
+; version to the workbench project.
+;
+; The vector table is normally located at address 0.
+; When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
+; The name "__vector_table" has special meaning for C-SPY:
+; it is where the SP start value is found, and the NVIC vector
+; table register (VTOR) is initialized to this address if != 0.
+;
+; Cortex-M version
+;
+        ;; Якорь для определения начала файла при обновлении бутлоадером
+        ;;SECTION .anchorsection:CODE
+        ;;DCB     "01234567"
+		
+        MODULE  ?cstartup
+
+        ;; Forward declaration of sections.
+        SECTION CSTACK:DATA:NOROOT(3)
+
+        SECTION .intvec:CODE:NOROOT(2)
+
+        EXTERN  __iar_program_start
+        EXTERN  SystemInit
+        PUBLIC  __vector_table
+
+        DATA
+__vector_table
+        DCD     sfe(CSTACK)
+        DCD     Reset_Handler             ; Reset Handler
+
+        DCD     NMI_Handler               ; NMI Handler
+        DCD     HardFault_Handler         ; Hard Fault Handler
+        DCD     MemManage_Handler         ; MPU Fault Handler
+        DCD     BusFault_Handler          ; Bus Fault Handler
+        DCD     UsageFault_Handler        ; Usage Fault Handler
+        DCD     0                         ; Reserved
+        DCD     0                         ; Reserved
+        DCD     0                         ; Reserved
+        DCD     0                         ; Reserved
+        DCD     SVC_Handler               ; SVCall Handler
+        DCD     DebugMon_Handler          ; Debug Monitor Handler
+        DCD     0                         ; Reserved
+        DCD     PendSV_Handler            ; PendSV Handler
+        DCD     SysTick_Handler           ; SysTick Handler
+
+         ; External Interrupts
+        DCD     WWDG_IRQHandler                   ; Window WatchDog                                        
+        DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                        
+        DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line            
+        DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
+        DCD     FLASH_IRQHandler                  ; FLASH                                           
+        DCD     RCC_IRQHandler                    ; RCC                                             
+        DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
+        DCD     EXTI1_IRQHandler                  ; EXTI Line1                                             
+        DCD     EXTI2_IRQHandler                  ; EXTI Line2                                             
+        DCD     EXTI3_IRQHandler                  ; EXTI Line3                                             
+        DCD     EXTI4_IRQHandler                  ; EXTI Line4                                             
+        DCD     DMA1_Stream0_IRQHandler           ; DMA1 Stream 0                                   
+        DCD     DMA1_Stream1_IRQHandler           ; DMA1 Stream 1                                   
+        DCD     DMA1_Stream2_IRQHandler           ; DMA1 Stream 2                                   
+        DCD     DMA1_Stream3_IRQHandler           ; DMA1 Stream 3                                   
+        DCD     DMA1_Stream4_IRQHandler           ; DMA1 Stream 4                                   
+        DCD     DMA1_Stream5_IRQHandler           ; DMA1 Stream 5                                   
+        DCD     DMA1_Stream6_IRQHandler           ; DMA1 Stream 6                                   
+        DCD     ADC_IRQHandler                    ; ADC1, ADC2 and ADC3s                            
+        DCD     CAN1_TX_IRQHandler                ; CAN1 TX                                                
+        DCD     CAN1_RX0_IRQHandler               ; CAN1 RX0                                               
+        DCD     CAN1_RX1_IRQHandler               ; CAN1 RX1                                               
+        DCD     CAN1_SCE_IRQHandler               ; CAN1 SCE                                               
+        DCD     EXTI9_5_IRQHandler                ; External Line[9:5]s                                    
+        DCD     TIM1_BRK_TIM9_IRQHandler          ; TIM1 Break and TIM9                   
+        DCD     TIM1_UP_TIM10_IRQHandler          ; TIM1 Update and TIM10                 
+        DCD     TIM1_TRG_COM_TIM11_IRQHandler     ; TIM1 Trigger and Commutation and TIM11
+        DCD     TIM1_CC_IRQHandler                ; TIM1 Capture Compare                                   
+        DCD     TIM2_IRQHandler                   ; TIM2                                            
+        DCD     TIM3_IRQHandler                   ; TIM3                                            
+        DCD     TIM4_IRQHandler                   ; TIM4                                            
+        DCD     I2C1_EV_IRQHandler                ; I2C1 Event                                             
+        DCD     I2C1_ER_IRQHandler                ; I2C1 Error                                             
+        DCD     I2C2_EV_IRQHandler                ; I2C2 Event                                             
+        DCD     I2C2_ER_IRQHandler                ; I2C2 Error                                               
+        DCD     SPI1_IRQHandler                   ; SPI1                                            
+        DCD     SPI2_IRQHandler                   ; SPI2                                            
+        DCD     USART1_IRQHandler                 ; USART1                                          
+        DCD     USART2_IRQHandler                 ; USART2                                          
+        DCD     USART3_IRQHandler                 ; USART3                                          
+        DCD     EXTI15_10_IRQHandler              ; External Line[15:10]s                                  
+        DCD     RTC_Alarm_IRQHandler              ; RTC Alarm (A and B) through EXTI Line                  
+        DCD     OTG_FS_WKUP_IRQHandler            ; USB OTG FS Wakeup through EXTI line                        
+        DCD     TIM8_BRK_TIM12_IRQHandler         ; TIM8 Break and TIM12                  
+        DCD     TIM8_UP_TIM13_IRQHandler          ; TIM8 Update and TIM13                 
+        DCD     TIM8_TRG_COM_TIM14_IRQHandler     ; TIM8 Trigger and Commutation and TIM14
+        DCD     TIM8_CC_IRQHandler                ; TIM8 Capture Compare                                   
+        DCD     DMA1_Stream7_IRQHandler           ; DMA1 Stream7                                           
+        DCD     FSMC_IRQHandler                   ; FSMC                                            
+        DCD     SDIO_IRQHandler                   ; SDIO                                            
+        DCD     TIM5_IRQHandler                   ; TIM5                                            
+        DCD     SPI3_IRQHandler                   ; SPI3                                            
+        DCD     UART4_IRQHandler                  ; UART4                                           
+        DCD     UART5_IRQHandler                  ; UART5                                           
+        DCD     TIM6_DAC_IRQHandler               ; TIM6 and DAC1&2 underrun errors                   
+        DCD     TIM7_IRQHandler                   ; TIM7                   
+        DCD     DMA2_Stream0_IRQHandler           ; DMA2 Stream 0                                   
+        DCD     DMA2_Stream1_IRQHandler           ; DMA2 Stream 1                                   
+        DCD     DMA2_Stream2_IRQHandler           ; DMA2 Stream 2                                   
+        DCD     DMA2_Stream3_IRQHandler           ; DMA2 Stream 3                                   
+        DCD     DMA2_Stream4_IRQHandler           ; DMA2 Stream 4                                   
+        DCD     ETH_IRQHandler                    ; Ethernet                                        
+        DCD     ETH_WKUP_IRQHandler               ; Ethernet Wakeup through EXTI line                      
+        DCD     CAN2_TX_IRQHandler                ; CAN2 TX                                                
+        DCD     CAN2_RX0_IRQHandler               ; CAN2 RX0                                               
+        DCD     CAN2_RX1_IRQHandler               ; CAN2 RX1                                               
+        DCD     CAN2_SCE_IRQHandler               ; CAN2 SCE                                               
+        DCD     OTG_FS_IRQHandler                 ; USB OTG FS                                      
+        DCD     DMA2_Stream5_IRQHandler           ; DMA2 Stream 5                                   
+        DCD     DMA2_Stream6_IRQHandler           ; DMA2 Stream 6                                   
+        DCD     DMA2_Stream7_IRQHandler           ; DMA2 Stream 7                                   
+        DCD     USART6_IRQHandler                 ; USART6                                           
+        DCD     I2C3_EV_IRQHandler                ; I2C3 event                                             
+        DCD     I2C3_ER_IRQHandler                ; I2C3 error                                             
+        DCD     OTG_HS_EP1_OUT_IRQHandler         ; USB OTG HS End Point 1 Out                      
+        DCD     OTG_HS_EP1_IN_IRQHandler          ; USB OTG HS End Point 1 In                       
+        DCD     OTG_HS_WKUP_IRQHandler            ; USB OTG HS Wakeup through EXTI                         
+        DCD     OTG_HS_IRQHandler                 ; USB OTG HS                                      
+        DCD     DCMI_IRQHandler                   ; DCMI                                            
+        DCD     CRYP_IRQHandler                   ; CRYP crypto                                     
+        DCD     HASH_RNG_IRQHandler               ; Hash and Rng
+        DCD     FPU_IRQHandler                    ; FPU
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Default interrupt handlers.
+;;
+        THUMB
+        PUBWEAK Reset_Handler
+        SECTION .text:CODE:NOROOT:REORDER(2)
+Reset_Handler
+
+        LDR     R0, =SystemInit
+        BLX     R0
+        LDR     R0, =__iar_program_start
+        BX      R0
+
+        PUBWEAK NMI_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+NMI_Handler
+        B NMI_Handler
+
+        PUBWEAK HardFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+HardFault_Handler
+        B HardFault_Handler
+
+        PUBWEAK MemManage_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+MemManage_Handler
+        B MemManage_Handler
+
+        PUBWEAK BusFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+BusFault_Handler
+        B BusFault_Handler
+
+        PUBWEAK UsageFault_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UsageFault_Handler
+        B UsageFault_Handler
+
+        PUBWEAK SVC_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SVC_Handler
+        B SVC_Handler
+
+        PUBWEAK DebugMon_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DebugMon_Handler
+        B DebugMon_Handler
+
+        PUBWEAK PendSV_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+PendSV_Handler
+        B PendSV_Handler
+
+        PUBWEAK SysTick_Handler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SysTick_Handler
+        B SysTick_Handler
+
+        PUBWEAK WWDG_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+WWDG_IRQHandler  
+        B WWDG_IRQHandler
+
+        PUBWEAK PVD_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+PVD_IRQHandler  
+        B PVD_IRQHandler
+
+        PUBWEAK TAMP_STAMP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TAMP_STAMP_IRQHandler  
+        B TAMP_STAMP_IRQHandler
+
+        PUBWEAK RTC_WKUP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+RTC_WKUP_IRQHandler  
+        B RTC_WKUP_IRQHandler
+
+        PUBWEAK FLASH_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+FLASH_IRQHandler  
+        B FLASH_IRQHandler
+
+        PUBWEAK RCC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+RCC_IRQHandler  
+        B RCC_IRQHandler
+
+        PUBWEAK EXTI0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI0_IRQHandler  
+        B EXTI0_IRQHandler
+
+        PUBWEAK EXTI1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI1_IRQHandler  
+        B EXTI1_IRQHandler
+
+        PUBWEAK EXTI2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI2_IRQHandler  
+        B EXTI2_IRQHandler
+
+        PUBWEAK EXTI3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+EXTI3_IRQHandler
+        B EXTI3_IRQHandler
+
+        PUBWEAK EXTI4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+EXTI4_IRQHandler  
+        B EXTI4_IRQHandler
+
+        PUBWEAK DMA1_Stream0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream0_IRQHandler  
+        B DMA1_Stream0_IRQHandler
+
+        PUBWEAK DMA1_Stream1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream1_IRQHandler  
+        B DMA1_Stream1_IRQHandler
+
+        PUBWEAK DMA1_Stream2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream2_IRQHandler  
+        B DMA1_Stream2_IRQHandler
+
+        PUBWEAK DMA1_Stream3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream3_IRQHandler  
+        B DMA1_Stream3_IRQHandler
+
+        PUBWEAK DMA1_Stream4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream4_IRQHandler  
+        B DMA1_Stream4_IRQHandler
+
+        PUBWEAK DMA1_Stream5_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream5_IRQHandler  
+        B DMA1_Stream5_IRQHandler
+
+        PUBWEAK DMA1_Stream6_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream6_IRQHandler  
+        B DMA1_Stream6_IRQHandler
+
+        PUBWEAK ADC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ADC_IRQHandler  
+        B ADC_IRQHandler
+
+        PUBWEAK CAN1_TX_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+CAN1_TX_IRQHandler  
+        B CAN1_TX_IRQHandler
+
+        PUBWEAK CAN1_RX0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN1_RX0_IRQHandler  
+        B CAN1_RX0_IRQHandler
+
+        PUBWEAK CAN1_RX1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN1_RX1_IRQHandler  
+        B CAN1_RX1_IRQHandler
+
+        PUBWEAK CAN1_SCE_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN1_SCE_IRQHandler  
+        B CAN1_SCE_IRQHandler
+
+        PUBWEAK EXTI9_5_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+EXTI9_5_IRQHandler  
+        B EXTI9_5_IRQHandler
+
+        PUBWEAK TIM1_BRK_TIM9_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM1_BRK_TIM9_IRQHandler  
+        B TIM1_BRK_TIM9_IRQHandler
+
+        PUBWEAK TIM1_UP_TIM10_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM1_UP_TIM10_IRQHandler  
+        B TIM1_UP_TIM10_IRQHandler
+
+        PUBWEAK TIM1_TRG_COM_TIM11_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM1_TRG_COM_TIM11_IRQHandler  
+        B TIM1_TRG_COM_TIM11_IRQHandler
+        
+        PUBWEAK TIM1_CC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM1_CC_IRQHandler  
+        B TIM1_CC_IRQHandler
+
+        PUBWEAK TIM2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIM2_IRQHandler  
+        B TIM2_IRQHandler
+
+        PUBWEAK TIM3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIM3_IRQHandler  
+        B TIM3_IRQHandler
+
+        PUBWEAK TIM4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIM4_IRQHandler  
+        B TIM4_IRQHandler
+
+        PUBWEAK I2C1_EV_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C1_EV_IRQHandler  
+        B I2C1_EV_IRQHandler
+
+        PUBWEAK I2C1_ER_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C1_ER_IRQHandler  
+        B I2C1_ER_IRQHandler
+
+        PUBWEAK I2C2_EV_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C2_EV_IRQHandler  
+        B I2C2_EV_IRQHandler
+
+        PUBWEAK I2C2_ER_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C2_ER_IRQHandler  
+        B I2C2_ER_IRQHandler
+
+        PUBWEAK SPI1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI1_IRQHandler  
+        B SPI1_IRQHandler
+
+        PUBWEAK SPI2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI2_IRQHandler  
+        B SPI2_IRQHandler
+
+        PUBWEAK USART1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART1_IRQHandler  
+        B USART1_IRQHandler
+
+        PUBWEAK USART2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART2_IRQHandler  
+        B USART2_IRQHandler
+
+        PUBWEAK USART3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART3_IRQHandler  
+        B USART3_IRQHandler
+
+        PUBWEAK EXTI15_10_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)   
+EXTI15_10_IRQHandler  
+        B EXTI15_10_IRQHandler
+
+        PUBWEAK RTC_Alarm_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)   
+RTC_Alarm_IRQHandler  
+        B RTC_Alarm_IRQHandler
+
+        PUBWEAK OTG_FS_WKUP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+OTG_FS_WKUP_IRQHandler  
+        B OTG_FS_WKUP_IRQHandler
+      
+        PUBWEAK TIM8_BRK_TIM12_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM8_BRK_TIM12_IRQHandler  
+        B TIM8_BRK_TIM12_IRQHandler
+
+        PUBWEAK TIM8_UP_TIM13_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM8_UP_TIM13_IRQHandler  
+        B TIM8_UP_TIM13_IRQHandler
+
+        PUBWEAK TIM8_TRG_COM_TIM14_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+TIM8_TRG_COM_TIM14_IRQHandler  
+        B TIM8_TRG_COM_TIM14_IRQHandler
+
+        PUBWEAK TIM8_CC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+TIM8_CC_IRQHandler  
+        B TIM8_CC_IRQHandler
+
+        PUBWEAK DMA1_Stream7_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA1_Stream7_IRQHandler  
+        B DMA1_Stream7_IRQHandler
+
+        PUBWEAK FSMC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+FSMC_IRQHandler  
+        B FSMC_IRQHandler
+
+        PUBWEAK SDIO_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SDIO_IRQHandler  
+        B SDIO_IRQHandler
+
+        PUBWEAK TIM5_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+TIM5_IRQHandler  
+        B TIM5_IRQHandler
+
+        PUBWEAK SPI3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+SPI3_IRQHandler  
+        B SPI3_IRQHandler
+
+        PUBWEAK UART4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART4_IRQHandler  
+        B UART4_IRQHandler
+
+        PUBWEAK UART5_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+UART5_IRQHandler  
+        B UART5_IRQHandler
+
+        PUBWEAK TIM6_DAC_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)   
+TIM6_DAC_IRQHandler  
+        B TIM6_DAC_IRQHandler
+
+        PUBWEAK TIM7_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)   
+TIM7_IRQHandler  
+        B TIM7_IRQHandler
+
+        PUBWEAK DMA2_Stream0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream0_IRQHandler  
+        B DMA2_Stream0_IRQHandler
+
+        PUBWEAK DMA2_Stream1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream1_IRQHandler  
+        B DMA2_Stream1_IRQHandler
+
+        PUBWEAK DMA2_Stream2_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream2_IRQHandler  
+        B DMA2_Stream2_IRQHandler
+
+        PUBWEAK DMA2_Stream3_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream3_IRQHandler  
+        B DMA2_Stream3_IRQHandler
+
+        PUBWEAK DMA2_Stream4_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream4_IRQHandler  
+        B DMA2_Stream4_IRQHandler
+
+        PUBWEAK ETH_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+ETH_IRQHandler  
+        B ETH_IRQHandler
+
+        PUBWEAK ETH_WKUP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+ETH_WKUP_IRQHandler  
+        B ETH_WKUP_IRQHandler
+
+        PUBWEAK CAN2_TX_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+CAN2_TX_IRQHandler  
+        B CAN2_TX_IRQHandler
+
+        PUBWEAK CAN2_RX0_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN2_RX0_IRQHandler  
+        B CAN2_RX0_IRQHandler
+
+        PUBWEAK CAN2_RX1_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN2_RX1_IRQHandler  
+        B CAN2_RX1_IRQHandler
+
+        PUBWEAK CAN2_SCE_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+CAN2_SCE_IRQHandler  
+        B CAN2_SCE_IRQHandler
+
+        PUBWEAK OTG_FS_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+OTG_FS_IRQHandler  
+        B OTG_FS_IRQHandler
+
+        PUBWEAK DMA2_Stream5_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream5_IRQHandler  
+        B DMA2_Stream5_IRQHandler
+
+        PUBWEAK DMA2_Stream6_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream6_IRQHandler  
+        B DMA2_Stream6_IRQHandler
+
+        PUBWEAK DMA2_Stream7_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+DMA2_Stream7_IRQHandler  
+        B DMA2_Stream7_IRQHandler
+
+        PUBWEAK USART6_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+USART6_IRQHandler  
+        B USART6_IRQHandler
+
+        PUBWEAK I2C3_EV_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C3_EV_IRQHandler  
+        B I2C3_EV_IRQHandler
+
+        PUBWEAK I2C3_ER_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1) 
+I2C3_ER_IRQHandler  
+        B I2C3_ER_IRQHandler
+
+        PUBWEAK OTG_HS_EP1_OUT_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+OTG_HS_EP1_OUT_IRQHandler  
+        B OTG_HS_EP1_OUT_IRQHandler
+
+        PUBWEAK OTG_HS_EP1_IN_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+OTG_HS_EP1_IN_IRQHandler  
+        B OTG_HS_EP1_IN_IRQHandler
+
+        PUBWEAK OTG_HS_WKUP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)    
+OTG_HS_WKUP_IRQHandler  
+        B OTG_HS_WKUP_IRQHandler
+
+        PUBWEAK OTG_HS_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+OTG_HS_IRQHandler  
+        B OTG_HS_IRQHandler
+
+        PUBWEAK DCMI_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+DCMI_IRQHandler  
+        B DCMI_IRQHandler
+
+        PUBWEAK CRYP_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)
+CRYP_IRQHandler  
+        B CRYP_IRQHandler
+
+        PUBWEAK HASH_RNG_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+HASH_RNG_IRQHandler  
+        B HASH_RNG_IRQHandler
+
+        PUBWEAK FPU_IRQHandler
+        SECTION .text:CODE:NOROOT:REORDER(1)  
+FPU_IRQHandler  
+        B FPU_IRQHandler
+
+        END
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 42 - 0
projects/iar/stm32f407xG.icf

@@ -0,0 +1,42 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08020000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08020000;
+define symbol __ICFEDIT_region_ROM_end__   = 0x0807FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__   = 0x2001FFFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x4000;
+define symbol __ICFEDIT_size_heap__   = 0x3000;
+define symbol __ICFEDIT_size_anchor__  = 0xC;
+define symbol __ICFEDIT_size_crc__  = 0x4;
+/**** End of ICF editor section. ###ICF###*/
+
+define symbol __region_RAM1_start__ = 0x10000000;
+define symbol __region_RAM1_end__   = 0x1000FFFF;
+
+define memory mem with size = 4G;
+define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__ - __ICFEDIT_size_anchor__];
+define region ANCHOR_region = mem:[from __ICFEDIT_region_ROM_end__ - __ICFEDIT_size_anchor__ - __ICFEDIT_size_crc__ size __ICFEDIT_size_anchor__];
+define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
+define region RAM1_region  = mem:[from __region_RAM1_start__   to __region_RAM1_end__];
+
+define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
+define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
+
+initialize by copy { readwrite, section .sram };
+do not initialize  { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region   { readonly };
+place in ANCHOR_region { section .anchorsection };
+place in RAM_region   { readwrite,
+                        block CSTACK, block HEAP };
+place in RAM1_region  { section .sram };
+
+place at address mem:__ICFEDIT_region_ROM_end__-3 { readonly section .checksum };
+

+ 1 - 1
stm32/stm32f4x7_ethernet/stm32f4x7_eth_bsp.c

@@ -67,7 +67,7 @@ void ETH_BSP_Config(void)
   ETH_GPIO_Config();
   
   /* Config NVIC for Ethernet */
-  //ETH_NVIC_Config();
+  ETH_NVIC_Config();
 
   /* Configure the Ethernet MAC/DMA */
   ETH_MACDMA_Config();

+ 163 - 163
thirdparty/FreeRTOS/include/FreeRTOSConfig.h

@@ -1,163 +1,163 @@
-/*
-    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
-    All rights reserved
-
-    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
-    This file is part of the FreeRTOS distribution.
-
-    FreeRTOS is free software; you can redistribute it and/or modify it under
-    the terms of the GNU General Public License (version 2) as published by the
-    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
-
-	***************************************************************************
-    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
-    >>!   distribute a combined work that includes FreeRTOS without being   !<<
-    >>!   obliged to provide the source code for proprietary components     !<<
-    >>!   outside of the FreeRTOS kernel.                                   !<<
-	***************************************************************************
-
-    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
-    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
-    link: http://www.freertos.org/a00114.html
-
-    ***************************************************************************
-     *                                                                       *
-     *    FreeRTOS provides completely free yet professionally developed,    *
-     *    robust, strictly quality controlled, supported, and cross          *
-     *    platform software that is more than just the market leader, it     *
-     *    is the industry's de facto standard.                               *
-     *                                                                       *
-     *    Help yourself get started quickly while simultaneously helping     *
-     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
-     *    tutorial book, reference manual, or both:                          *
-     *    http://www.FreeRTOS.org/Documentation                              *
-     *                                                                       *
-    ***************************************************************************
-
-    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
-	the FAQ page "My application does not run, what could be wrong?".  Have you
-	defined configASSERT()?
-
-	http://www.FreeRTOS.org/support - In return for receiving this top quality
-	embedded software for free we request you assist our global community by
-	participating in the support forum.
-
-	http://www.FreeRTOS.org/training - Investing in training allows your team to
-	be as productive as possible as early as possible.  Now you can receive
-	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
-	Ltd, and the world's leading authority on the world's leading RTOS.
-
-    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
-    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
-    compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
-    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
-    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
-    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
-    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
-    licenses offer ticketed support, indemnification and commercial middleware.
-
-    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
-    engineered and independently SIL3 certified version for use in safety and
-    mission critical applications that require provable dependability.
-
-    1 tab == 4 spaces!
-*/
-
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- *
- * See http://www.freertos.org/a00110.html.
- *----------------------------------------------------------*/
-
-/* Use a guard to ensure the following few definitions are'nt included in
-assembly files that include this header file. */
-#ifndef __IASMARM__
-	#include <stdint.h>
-	extern uint32_t SystemCoreClock;
-#endif
-
-#define configENABLE_BACKWARD_COMPATIBILITY 1
-
-#define configUSE_PREEMPTION			1
-#define configUSE_IDLE_HOOK				0
-#define configUSE_TICK_HOOK				0
-#define configCPU_CLOCK_HZ				( SystemCoreClock )
-#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )
-#define configMAX_PRIORITIES			( 5 )
-#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 128 )
-#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 60 * 1024 ) )
-#define configMAX_TASK_NAME_LEN			( 16 )
-#define configUSE_TRACE_FACILITY		1
-#define configUSE_16_BIT_TICKS			0
-#define configIDLE_SHOULD_YIELD			1
-#define configUSE_MUTEXES				1
-#define configQUEUE_REGISTRY_SIZE		0
-#define configGENERATE_RUN_TIME_STATS	0
-#define configCHECK_FOR_STACK_OVERFLOW	0
-#define configUSE_RECURSIVE_MUTEXES		1
-#define configUSE_MALLOC_FAILED_HOOK	0
-#define configUSE_APPLICATION_TASK_TAG	0
-#define configUSE_COUNTING_SEMAPHORES	1
-#define configUSE_STATS_FORMATTING_FUNCTIONS	1
-#define configAPPLICATION_ALLOCATED_HEAP        1
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 		0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
-
-/* Software timer definitions. */
-#define configUSE_TIMERS				1
-#define configTIMER_TASK_PRIORITY		( 2 )
-#define configTIMER_QUEUE_LENGTH		10
-#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet		1
-#define INCLUDE_uxTaskPriorityGet		1
-#define INCLUDE_vTaskDelete				1
-#define INCLUDE_vTaskCleanUpResources	1
-#define INCLUDE_vTaskSuspend			1
-#define INCLUDE_vTaskDelayUntil			1
-#define INCLUDE_vTaskDelay				1
-
-/* Use the system definition, if there is one */
-#ifdef __NVIC_PRIO_BITS
-	#define configPRIO_BITS       		__NVIC_PRIO_BITS
-#else
-	#define configPRIO_BITS       		4        /* 15 priority levels */
-#endif
-
-#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0xf
-#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5
-
-/* The lowest priority. */
-#define configKERNEL_INTERRUPT_PRIORITY 	( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-/* Priority 5, or 160 as only the top three bits are implemented. */
-/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
-See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
-#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-	
-#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }	
-	
-#define vPortSVCHandler SVC_Handler
-#define xPortPendSVHandler PendSV_Handler
-#define vPortSVCHandler SVC_Handler
-#define xPortSysTickHandler SysTick_Handler
-
-#endif /* FREERTOS_CONFIG_H */
-
+/*
+    FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
+    All rights reserved
+
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+    This file is part of the FreeRTOS distribution.
+
+    FreeRTOS is free software; you can redistribute it and/or modify it under
+    the terms of the GNU General Public License (version 2) as published by the
+    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
+
+	***************************************************************************
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<
+    >>!   obliged to provide the source code for proprietary components     !<<
+    >>!   outside of the FreeRTOS kernel.                                   !<<
+	***************************************************************************
+
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
+    link: http://www.freertos.org/a00114.html
+
+    ***************************************************************************
+     *                                                                       *
+     *    FreeRTOS provides completely free yet professionally developed,    *
+     *    robust, strictly quality controlled, supported, and cross          *
+     *    platform software that is more than just the market leader, it     *
+     *    is the industry's de facto standard.                               *
+     *                                                                       *
+     *    Help yourself get started quickly while simultaneously helping     *
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
+     *    tutorial book, reference manual, or both:                          *
+     *    http://www.FreeRTOS.org/Documentation                              *
+     *                                                                       *
+    ***************************************************************************
+
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
+	the FAQ page "My application does not run, what could be wrong?".  Have you
+	defined configASSERT()?
+
+	http://www.FreeRTOS.org/support - In return for receiving this top quality
+	embedded software for free we request you assist our global community by
+	participating in the support forum.
+
+	http://www.FreeRTOS.org/training - Investing in training allows your team to
+	be as productive as possible as early as possible.  Now you can receive
+	FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+	Ltd, and the world's leading authority on the world's leading RTOS.
+
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
+    licenses offer ticketed support, indemnification and commercial middleware.
+
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+    engineered and independently SIL3 certified version for use in safety and
+    mission critical applications that require provable dependability.
+
+    1 tab == 4 spaces!
+*/
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+/* Use a guard to ensure the following few definitions are'nt included in
+assembly files that include this header file. */
+#ifndef __IASMARM__
+	#include <stdint.h>
+	extern uint32_t SystemCoreClock;
+#endif
+
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+
+#define configUSE_PREEMPTION			1
+#define configUSE_IDLE_HOOK				0
+#define configUSE_TICK_HOOK				0
+#define configCPU_CLOCK_HZ				( SystemCoreClock )
+#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )
+#define configMAX_PRIORITIES			( 5 )
+#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 128 )
+#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 60 * 1024 ) )
+#define configMAX_TASK_NAME_LEN			( 16 )
+#define configUSE_TRACE_FACILITY		1
+#define configUSE_16_BIT_TICKS			0
+#define configIDLE_SHOULD_YIELD			1
+#define configUSE_MUTEXES				1
+#define configQUEUE_REGISTRY_SIZE		0
+#define configGENERATE_RUN_TIME_STATS	0
+#define configCHECK_FOR_STACK_OVERFLOW	0
+#define configUSE_RECURSIVE_MUTEXES		1
+#define configUSE_MALLOC_FAILED_HOOK	0
+#define configUSE_APPLICATION_TASK_TAG	0
+#define configUSE_COUNTING_SEMAPHORES	1
+#define configUSE_STATS_FORMATTING_FUNCTIONS	1
+#define configAPPLICATION_ALLOCATED_HEAP        1
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 		0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS				0
+#define configTIMER_TASK_PRIORITY		( 2 )
+#define configTIMER_QUEUE_LENGTH		10
+#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet		1
+#define INCLUDE_uxTaskPriorityGet		1
+#define INCLUDE_vTaskDelete				1
+#define INCLUDE_vTaskCleanUpResources	1
+#define INCLUDE_vTaskSuspend			1
+#define INCLUDE_vTaskDelayUntil			1
+#define INCLUDE_vTaskDelay				1
+
+/* Use the system definition, if there is one */
+#ifdef __NVIC_PRIO_BITS
+	#define configPRIO_BITS       		__NVIC_PRIO_BITS
+#else
+	#define configPRIO_BITS       		4        /* 15 priority levels */
+#endif
+
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0xf
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5
+
+/* The lowest priority. */
+#define configKERNEL_INTERRUPT_PRIORITY 	( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+/* Priority 5, or 160 as only the top three bits are implemented. */
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+	
+#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }	
+	
+#define vPortSVCHandler SVC_Handler
+#define xPortPendSVHandler PendSV_Handler
+#define vPortSVCHandler SVC_Handler
+#define xPortSysTickHandler SysTick_Handler
+
+#endif /* FREERTOS_CONFIG_H */
+

+ 1491 - 1490
thirdparty/lwip/src/core/snmp/msg_in.c

@@ -1,1490 +1,1491 @@
-/**
- * @file
- * SNMP input message processing (RFC1157).
- */
-
-/*
- * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * Author: Christiaan Simons <christiaan.simons@axon.tv>
- */
-
-#include "lwip/opt.h"
-#include "settings_api.h"
-
-#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/snmp.h"
-#include "lwip/snmp_asn1.h"
-#include "lwip/snmp_msg.h"
-#include "lwip/snmp_structs.h"
-#include "lwip/ip_addr.h"
-#include "lwip/memp.h"
-#include "lwip/udp.h"
-#include "lwip/stats.h"
-
-#include <string.h>
-
-/* public (non-static) constants */
-/** SNMP v1 == 0 */
-const s32_t snmp_version = 0;
-/** default SNMP community string */
-const char snmp_publiccommunity[7] = "public";
-
-/**
-  * @brief  Общая структура настроек
-  */
-extern SETTINGS_t sSettings;
-
-/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */
-struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS];
-/* UDP Protocol Control Block */
-struct udp_pcb *snmp1_pcb;
-
-static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
-static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
-static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
-
-
-/**
- * Starts SNMP Agent.
- * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161.
- */
-void
-snmp_init(void)
-{
-  struct snmp_msg_pstat *msg_ps;
-  u8_t i;
-
-  snmp1_pcb = udp_new();
-  if (snmp1_pcb != NULL)
-  {
-    udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT);
-    udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT);
-  }
-  msg_ps = &msg_input_list[0];
-  for (i=0; i<SNMP_CONCURRENT_REQUESTS; i++)
-  {
-    msg_ps->state = SNMP_MSG_EMPTY;
-    msg_ps->error_index = 0;
-    msg_ps->error_status = SNMP_ES_NOERROR;
-    msg_ps++;
-  }
-  trap_msg.pcb = snmp1_pcb;
-
-#ifdef SNMP_PRIVATE_MIB_INIT
-  /* If defined, this must be a function-like define to initialize the
-   * private MIB after the stack has been initialized.
-   * The private MIB can also be initialized in tcpip_callback (or after
-   * the stack is initialized), this define is only for convenience. */
-  SNMP_PRIVATE_MIB_INIT();
-#endif /* SNMP_PRIVATE_MIB_INIT */
-
-  /* The coldstart trap will only be output
-     if our outgoing interface is up & configured  */
-  //snmp_coldstart_trap();
-}
-
-static void
-snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error)
-{
-  /* move names back from outvb to invb */
-  int v;
-  struct snmp_varbind *vbi = msg_ps->invb.head;
-  struct snmp_varbind *vbo = msg_ps->outvb.head;
-  for (v=0; v<msg_ps->vb_idx; v++) {
-    vbi->ident_len = vbo->ident_len;
-    vbo->ident_len = 0;
-    vbi->ident = vbo->ident;
-    vbo->ident = NULL;
-    vbi = vbi->next;
-    vbo = vbo->next;
-  }
-  /* free outvb */
-  snmp_varbind_list_free(&msg_ps->outvb);
-  /* we send invb back */
-  msg_ps->outvb = msg_ps->invb;
-  msg_ps->invb.head = NULL;
-  msg_ps->invb.tail = NULL;
-  msg_ps->invb.count = 0;
-  msg_ps->error_status = error;
-  /* error index must be 0 for error too big */
-  msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0;
-  snmp_send_response(msg_ps);
-  snmp_varbind_list_free(&msg_ps->outvb);
-  msg_ps->state = SNMP_MSG_EMPTY;
-}
-
-static void
-snmp_ok_response(struct snmp_msg_pstat *msg_ps)
-{
-  err_t err_ret;
-
-  err_ret = snmp_send_response(msg_ps);
-  if (err_ret == ERR_MEM)
-  {
-    /* serious memory problem, can't return tooBig */
-  }
-  else
-  {
-    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status));
-  }
-  /* free varbinds (if available) */
-  snmp_varbind_list_free(&msg_ps->invb);
-  snmp_varbind_list_free(&msg_ps->outvb);
-  msg_ps->state = SNMP_MSG_EMPTY;
-}
-
-/**
- * Service an internal or external event for SNMP GET.
- *
- * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
- * @param msg_ps points to the assosicated message process state
- */
-static void
-snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
-{
-  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
-
-  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
-  {
-    struct mib_external_node *en;
-    struct snmp_name_ptr np;
-
-    /* get_object_def() answer*/
-    en = msg_ps->ext_mib_node;
-    np = msg_ps->ext_name_ptr;
-
-    /* translate answer into a known lifeform */
-    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
-    if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) &&
-        (msg_ps->ext_object_def.access & MIB_ACCESS_READ))
-    {
-      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
-      en->get_value_q(request_id, &msg_ps->ext_object_def);
-    }
-    else
-    {
-      en->get_object_def_pc(request_id, np.ident_len, np.ident);
-      /* search failed, object id points to unknown object (nosuchname) */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
-  {
-    struct mib_external_node *en;
-    struct snmp_varbind *vb;
-
-    /* get_value() answer */
-    en = msg_ps->ext_mib_node;
-
-    /* allocate output varbind */
-    vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
-    if (vb != NULL)
-    {
-      vb->next = NULL;
-      vb->prev = NULL;
-
-      /* move name from invb to outvb */
-      vb->ident = msg_ps->vb_ptr->ident;
-      vb->ident_len = msg_ps->vb_ptr->ident_len;
-      /* ensure this memory is refereced once only */
-      msg_ps->vb_ptr->ident = NULL;
-      msg_ps->vb_ptr->ident_len = 0;
-
-      vb->value_type = msg_ps->ext_object_def.asn_type;
-      LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
-      vb->value_len = (u8_t)msg_ps->ext_object_def.v_len;
-      if (vb->value_len > 0)
-      {
-        LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
-        vb->value = memp_malloc(MEMP_SNMP_VALUE);
-        if (vb->value != NULL)
-        {
-          en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
-          snmp_varbind_tail_add(&msg_ps->outvb, vb);
-          /* search again (if vb_idx < msg_ps->invb.count) */
-          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-          msg_ps->vb_idx += 1;
-        }
-        else
-        {
-          en->get_value_pc(request_id, &msg_ps->ext_object_def);
-          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n"));
-          msg_ps->vb_ptr->ident = vb->ident;
-          msg_ps->vb_ptr->ident_len = vb->ident_len;
-          memp_free(MEMP_SNMP_VARBIND, vb);
-          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-        }
-      }
-      else
-      {
-        /* vb->value_len == 0, empty value (e.g. empty string) */
-        en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL);
-        vb->value = NULL;
-        snmp_varbind_tail_add(&msg_ps->outvb, vb);
-        /* search again (if vb_idx < msg_ps->invb.count) */
-        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-        msg_ps->vb_idx += 1;
-      }
-    }
-    else
-    {
-      en->get_value_pc(request_id, &msg_ps->ext_object_def);
-      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n"));
-      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-    }
-  }
-
-  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-         (msg_ps->vb_idx < msg_ps->invb.count))
-  {
-    struct mib_node *mn;
-    struct snmp_name_ptr np;
-
-    if (msg_ps->vb_idx == 0)
-    {
-      msg_ps->vb_ptr = msg_ps->invb.head;
-    }
-    else
-    {
-      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
-    }
-    /** test object identifier for .iso.org.dod.internet prefix */
-    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
-    {
-      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
-                             msg_ps->vb_ptr->ident + 4, &np);
-      if (mn != NULL)
-      {
-        if (mn->node_type == MIB_NODE_EX)
-        {
-          /* external object */
-          struct mib_external_node *en = (struct mib_external_node*)mn;
-
-          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
-          /* save en && args in msg_ps!! */
-          msg_ps->ext_mib_node = en;
-          msg_ps->ext_name_ptr = np;
-
-          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
-        }
-        else
-        {
-          /* internal object */
-          struct obj_def object_def;
-
-          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
-          mn->get_object_def(np.ident_len, np.ident, &object_def);
-          if ((object_def.instance != MIB_OBJECT_NONE) &&
-            (object_def.access & MIB_ACCESS_READ))
-          {
-            mn = mn;
-          }
-          else
-          {
-            /* search failed, object id points to unknown object (nosuchname) */
-            mn =  NULL;
-          }
-          if (mn != NULL)
-          {
-            struct snmp_varbind *vb;
-
-            msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
-            /* allocate output varbind */
-            vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
-            if (vb != NULL)
-            {
-              vb->next = NULL;
-              vb->prev = NULL;
-
-              /* move name from invb to outvb */
-              vb->ident = msg_ps->vb_ptr->ident;
-              vb->ident_len = msg_ps->vb_ptr->ident_len;
-              /* ensure this memory is refereced once only */
-              msg_ps->vb_ptr->ident = NULL;
-              msg_ps->vb_ptr->ident_len = 0;
-
-              vb->value_type = object_def.asn_type;
-              LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
-              vb->value_len = (u8_t)object_def.v_len;
-              if (vb->value_len > 0)
-              {
-                LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low",
-                  vb->value_len <= SNMP_MAX_VALUE_SIZE);
-                vb->value = memp_malloc(MEMP_SNMP_VALUE);
-                if (vb->value != NULL)
-                {
-                  mn->get_value(&object_def, vb->value_len, vb->value);
-                  snmp_varbind_tail_add(&msg_ps->outvb, vb);
-                  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-                  msg_ps->vb_idx += 1;
-                }
-                else
-                {
-                  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n"));
-                  msg_ps->vb_ptr->ident = vb->ident;
-                  msg_ps->vb_ptr->ident_len = vb->ident_len;
-                  vb->ident = NULL;
-                  vb->ident_len = 0;
-                  memp_free(MEMP_SNMP_VARBIND, vb);
-                  snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-                }
-              }
-              else
-              {
-                /* vb->value_len == 0, empty value (e.g. empty string) */
-                vb->value = NULL;
-                snmp_varbind_tail_add(&msg_ps->outvb, vb);
-                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-                msg_ps->vb_idx += 1;
-              }
-            }
-            else
-            {
-              LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n"));
-              snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-            }
-          }
-        }
-      }
-    }
-    else
-    {
-      mn = NULL;
-    }
-    if (mn == NULL)
-    {
-      /* mn == NULL, noSuchName */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-      (msg_ps->vb_idx == msg_ps->invb.count))
-  {
-    snmp_ok_response(msg_ps);
-  }
-}
-
-/**
- * Service an internal or external event for SNMP GETNEXT.
- *
- * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
- * @param msg_ps points to the assosicated message process state
- */
-static void
-snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
-{
-  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
-
-  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
-  {
-    struct mib_external_node *en;
-
-    /* get_object_def() answer*/
-    en = msg_ps->ext_mib_node;
-
-    /* translate answer into a known lifeform */
-    en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def);
-    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
-    {
-      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
-      en->get_value_q(request_id, &msg_ps->ext_object_def);
-    }
-    else
-    {
-      en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]);
-      /* search failed, object id points to unknown object (nosuchname) */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
-  {
-    struct mib_external_node *en;
-    struct snmp_varbind *vb;
-
-    /* get_value() answer */
-    en = msg_ps->ext_mib_node;
-
-    LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
-    vb = snmp_varbind_alloc(&msg_ps->ext_oid,
-                            msg_ps->ext_object_def.asn_type,
-                            (u8_t)msg_ps->ext_object_def.v_len);
-    if (vb != NULL)
-    {
-      en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
-      snmp_varbind_tail_add(&msg_ps->outvb, vb);
-      msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-      msg_ps->vb_idx += 1;
-    }
-    else
-    {
-      en->get_value_pc(request_id, &msg_ps->ext_object_def);
-      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n"));
-      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-    }
-  }
-
-  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-         (msg_ps->vb_idx < msg_ps->invb.count))
-  {
-    struct mib_node *mn;
-    struct snmp_obj_id oid;
-
-    if (msg_ps->vb_idx == 0)
-    {
-      msg_ps->vb_ptr = msg_ps->invb.head;
-    }
-    else
-    {
-      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
-    }
-    if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid))
-    {
-      if (msg_ps->vb_ptr->ident_len > 3)
-      {
-        /* can offset ident_len and ident */
-        mn = snmp_expand_tree((struct mib_node*)&internet,
-                              msg_ps->vb_ptr->ident_len - 4,
-                              msg_ps->vb_ptr->ident + 4, &oid);
-      }
-      else
-      {
-        /* can't offset ident_len -4, ident + 4 */
-        mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid);
-      }
-    }
-    else
-    {
-      mn = NULL;
-    }
-    if (mn != NULL)
-    {
-      if (mn->node_type == MIB_NODE_EX)
-      {
-        /* external object */
-        struct mib_external_node *en = (struct mib_external_node*)mn;
-
-        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
-        /* save en && args in msg_ps!! */
-        msg_ps->ext_mib_node = en;
-        msg_ps->ext_oid = oid;
-
-        en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]);
-      }
-      else
-      {
-        /* internal object */
-        struct obj_def object_def;
-        struct snmp_varbind *vb;
-
-        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
-        mn->get_object_def(1, &oid.id[oid.len - 1], &object_def);
-
-        LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
-        vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len);
-        if (vb != NULL)
-        {
-          msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
-          mn->get_value(&object_def, object_def.v_len, vb->value);
-          snmp_varbind_tail_add(&msg_ps->outvb, vb);
-          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-          msg_ps->vb_idx += 1;
-        }
-        else
-        {
-          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n"));
-          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
-        }
-      }
-    }
-    if (mn == NULL)
-    {
-      /* mn == NULL, noSuchName */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-      (msg_ps->vb_idx == msg_ps->invb.count))
-  {
-    snmp_ok_response(msg_ps);
-  }
-}
-
-/**
- * Service an internal or external event for SNMP SET.
- *
- * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
- * @param msg_ps points to the assosicated message process state
- */
-static void
-snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
-{
-  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
-
-  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
-  {
-    struct mib_external_node *en;
-    struct snmp_name_ptr np;
-
-    /* get_object_def() answer*/
-    en = msg_ps->ext_mib_node;
-    np = msg_ps->ext_name_ptr;
-
-    /* translate answer into a known lifeform */
-    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
-    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
-    {
-      msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST;
-      en->set_test_q(request_id, &msg_ps->ext_object_def);
-    }
-    else
-    {
-      en->get_object_def_pc(request_id, np.ident_len, np.ident);
-      /* search failed, object id points to unknown object (nosuchname) */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST)
-  {
-    struct mib_external_node *en;
-
-    /* set_test() answer*/
-    en = msg_ps->ext_mib_node;
-
-    if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE)
-    {
-       if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) &&
-           (en->set_test_a(request_id,&msg_ps->ext_object_def,
-                           msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
-      {
-        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-        msg_ps->vb_idx += 1;
-      }
-      else
-      {
-        en->set_test_pc(request_id,&msg_ps->ext_object_def);
-        /* bad value */
-        snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
-      }
-    }
-    else
-    {
-      en->set_test_pc(request_id,&msg_ps->ext_object_def);
-      /* object not available for set */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S)
-  {
-    struct mib_external_node *en;
-    struct snmp_name_ptr np;
-
-    /* get_object_def() answer*/
-    en = msg_ps->ext_mib_node;
-    np = msg_ps->ext_name_ptr;
-
-    /* translate answer into a known lifeform */
-    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
-    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
-    {
-      msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE;
-      en->set_value_q(request_id, &msg_ps->ext_object_def,
-                      msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
-    }
-    else
-    {
-      en->get_object_def_pc(request_id, np.ident_len, np.ident);
-      /* set_value failed, object has disappeared for some odd reason?? */
-      snmp_error_response(msg_ps,SNMP_ES_GENERROR);
-    }
-  }
-  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE)
-  {
-    struct mib_external_node *en;
-
-    /** set_value_a() */
-    en = msg_ps->ext_mib_node;
-    en->set_value_a(request_id, &msg_ps->ext_object_def,
-      msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value);
-
-    /** @todo use set_value_pc() if toobig */
-    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
-    msg_ps->vb_idx += 1;
-  }
-
-  /* test all values before setting */
-  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-         (msg_ps->vb_idx < msg_ps->invb.count))
-  {
-    struct mib_node *mn;
-    struct snmp_name_ptr np;
-
-    if (msg_ps->vb_idx == 0)
-    {
-      msg_ps->vb_ptr = msg_ps->invb.head;
-    }
-    else
-    {
-      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
-    }
-    /** test object identifier for .iso.org.dod.internet prefix */
-    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
-    {
-      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
-                             msg_ps->vb_ptr->ident + 4, &np);
-      if (mn != NULL)
-      {
-        if (mn->node_type == MIB_NODE_EX)
-        {
-          /* external object */
-          struct mib_external_node *en = (struct mib_external_node*)mn;
-
-          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
-          /* save en && args in msg_ps!! */
-          msg_ps->ext_mib_node = en;
-          msg_ps->ext_name_ptr = np;
-
-          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
-        }
-        else
-        {
-          /* internal object */
-          struct obj_def object_def;
-
-          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
-          mn->get_object_def(np.ident_len, np.ident, &object_def);
-          if (object_def.instance != MIB_OBJECT_NONE)
-          {
-            mn = mn;
-          }
-          else
-          {
-            /* search failed, object id points to unknown object (nosuchname) */
-            mn = NULL;
-          }
-          if (mn != NULL)
-          {
-            msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST;
-
-            if (object_def.access & MIB_ACCESS_WRITE)
-            {
-              if ((object_def.asn_type == msg_ps->vb_ptr->value_type) &&
-                  (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
-              {
-                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-                msg_ps->vb_idx += 1;
-              }
-              else
-              {
-                /* bad value */
-                snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
-              }
-            }
-            else
-            {
-              /* object not available for set */
-              snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-            }
-          }
-        }
-      }
-    }
-    else
-    {
-      mn = NULL;
-    }
-    if (mn == NULL)
-    {
-      /* mn == NULL, noSuchName */
-      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
-    }
-  }
-
-  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
-      (msg_ps->vb_idx == msg_ps->invb.count))
-  {
-    msg_ps->vb_idx = 0;
-    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
-  }
-
-  /* set all values "atomically" (be as "atomic" as possible) */
-  while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
-         (msg_ps->vb_idx < msg_ps->invb.count))
-  {
-    struct mib_node *mn;
-    struct snmp_name_ptr np;
-
-    if (msg_ps->vb_idx == 0)
-    {
-      msg_ps->vb_ptr = msg_ps->invb.head;
-    }
-    else
-    {
-      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
-    }
-    /* skip iso prefix test, was done previously while settesting() */
-    mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
-                           msg_ps->vb_ptr->ident + 4, &np);
-    /* check if object is still available
-       (e.g. external hot-plug thingy present?) */
-    if (mn != NULL)
-    {
-      if (mn->node_type == MIB_NODE_EX)
-      {
-        /* external object */
-        struct mib_external_node *en = (struct mib_external_node*)mn;
-
-        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S;
-        /* save en && args in msg_ps!! */
-        msg_ps->ext_mib_node = en;
-        msg_ps->ext_name_ptr = np;
-
-        en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
-      }
-      else
-      {
-        /* internal object */
-        struct obj_def object_def;
-
-        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S;
-        mn->get_object_def(np.ident_len, np.ident, &object_def);
-        msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
-        mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
-        msg_ps->vb_idx += 1;
-      }
-    }
-  }
-  if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
-      (msg_ps->vb_idx == msg_ps->invb.count))
-  {
-    /* simply echo the input if we can set it
-       @todo do we need to return the actual value?
-       e.g. if value is silently modified or behaves sticky? */
-    msg_ps->outvb = msg_ps->invb;
-    msg_ps->invb.head = NULL;
-    msg_ps->invb.tail = NULL;
-    msg_ps->invb.count = 0;
-    snmp_ok_response(msg_ps);
-  }
-}
-
-
-/**
- * Handle one internal or external event.
- * Called for one async event. (recv external/private answer)
- *
- * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
- */
-void
-snmp_msg_event(u8_t request_id)
-{
-  struct snmp_msg_pstat *msg_ps;
-
-  if (request_id < SNMP_CONCURRENT_REQUESTS)
-  {
-    msg_ps = &msg_input_list[request_id];
-    if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
-    {
-      snmp_msg_getnext_event(request_id, msg_ps);
-    }
-    else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
-    {
-      snmp_msg_get_event(request_id, msg_ps);
-    }
-    else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
-    {
-      snmp_msg_set_event(request_id, msg_ps);
-    }
-  }
-}
-
-
-/* lwIP UDP receive callback function */
-static void
-snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
-{
-  volatile struct snmp_msg_pstat *msg_ps;
-  u8_t req_idx;
-  err_t err_ret;
-  u16_t payload_len = p->tot_len;
-  u16_t payload_ofs = 0;
-  u16_t varbind_ofs = 0;
-
-  /* suppress unused argument warning */
-  LWIP_UNUSED_ARG(arg);
-
-  /* traverse input message process list, look for SNMP_MSG_EMPTY */
-  msg_ps = &msg_input_list[0];
-  req_idx = 0;
-  while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY))
-  {
-    req_idx++;
-    msg_ps++;
-  }
-  if (req_idx == SNMP_CONCURRENT_REQUESTS)
-  {
-    /* exceeding number of concurrent requests */
-    pbuf_free(p);
-    return;
-  }
-
-  /* accepting request */
-  snmp_inc_snmpinpkts();
-  /* record used 'protocol control block' */
-  msg_ps->pcb = pcb;
-  /* source address (network order) */
-  msg_ps->sip = *addr;
-  /* source port (host order (lwIP oddity)) */
-  msg_ps->sp = port;
-
-  /* check total length, version, community, pdu type */
-  err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps);
-  /* Only accept requests and requests without error (be robust) */
-  /* Reject response and trap headers or error requests as input! */
-  if ((err_ret != ERR_OK) ||
-      ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) &&
-       (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) &&
-       (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) ||
-      ((msg_ps->error_status != SNMP_ES_NOERROR) ||
-       (msg_ps->error_index != 0)) )
-  {
-    /* header check failed drop request silently, do not return error! */
-    pbuf_free(p);
-    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n"));
-    return;
-  }
-  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community));
-
-  /* Builds a list of variable bindings. Copy the varbinds from the pbuf
-    chain to glue them when these are divided over two or more pbuf's. */
-  err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
-  /* we've decoded the incoming message, release input msg now */
-  pbuf_free(p);
-  if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0))
-  {
-    /* varbind-list decode failed, or varbind list empty.
-       drop request silently, do not return error!
-       (errors are only returned for a specific varbind failure) */
-    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n"));
-    return;
-  }
-
-  msg_ps->error_status = SNMP_ES_NOERROR;
-  msg_ps->error_index = 0;
-  /* find object for each variable binding */
-  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
-  /* first variable binding from list to inspect */
-  msg_ps->vb_idx = 0;
-
-  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count));
-
-  /* handle input event and as much objects as possible in one go */
-  snmp_msg_event(req_idx);
-}
-
-/**
- * Checks and decodes incoming SNMP message header, logs header errors.
- *
- * @param p points to pbuf chain of SNMP message (UDP payload)
- * @param ofs points to first octet of SNMP message
- * @param pdu_len the length of the UDP payload
- * @param ofs_ret returns the ofset of the variable bindings
- * @param m_stat points to the current message request state return
- * @return
- * - ERR_OK SNMP header is sane and accepted
- * - ERR_ARG SNMP header is either malformed or rejected
- */
-static err_t
-snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
-{
-  err_t derr;
-  u16_t len, ofs_base;
-  u8_t  len_octets;
-  u8_t  type;
-  s32_t version;
-
-  ofs_base = ofs;
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) ||
-      (pdu_len != (1 + len_octets + len)) ||
-      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
-  {
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  ofs += (1 + len_octets);
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
-  {
-    /* can't decode or no integer (version) */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version);
-  if (derr != ERR_OK)
-  {
-    /* can't decode */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  if (version != 0)
-  {
-    /* not version 1 */
-    snmp_inc_snmpinbadversions();
-    return ERR_ARG;
-  }
-  ofs += (1 + len_octets + len);
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
-  {
-    /* can't decode or no octet string (community) */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community);
-  if (derr != ERR_OK)
-  {
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  /* add zero terminator */
-  len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
-  m_stat->community[len] = 0;
-  m_stat->com_strlen = (u8_t)len;
-  
-  /* Проверка public communuty */
-  /*
-  if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
-  {
-    // @todo: move this if we need to check more names 
-    snmp_inc_snmpinbadcommunitynames();
-    snmp_authfail_trap();
-    return ERR_ARG;
-  }*/
-  
-  ofs += (1 + len_octets + len);
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if (derr != ERR_OK)
-  {
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  
-  /* FIX for write/read communuty */
-  /* GetRequest PDU */
-  if (type == (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ)) 
-  {	
-  	if (strncmp(sSettings.sSnmp.readCommunity, (const char*)m_stat->community, strlen(sSettings.sSnmp.readCommunity)) != 0
-		|| (strlen(sSettings.sSnmp.readCommunity) != strlen((const char*)m_stat->community)) )
-    {
-      snmp_inc_snmpinbadcommunitynames();
-      snmp_authfail_trap();
-      return ERR_ARG;
-    }
-  }	
-  /* SetRequest PDU */
-  else if (type == (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ)) 	
-  {
-    if (strncmp(sSettings.sSnmp.writeCommunity, (const char*)m_stat->community, strlen(sSettings.sSnmp.writeCommunity)) != 0
-		|| (strlen(sSettings.sSnmp.writeCommunity) != strlen((const char*)m_stat->community)) )
-    {
-      snmp_inc_snmpinbadcommunitynames();
-      snmp_authfail_trap();
-      return ERR_ARG;
-    }
-  }	
-  
-  switch(type)
-  {
-    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ):
-      // GetRequest PDU 
-      snmp_inc_snmpingetrequests();
-      derr = ERR_OK;
-      break;
-
-    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ):
-      // GetNextRequest PDU 
-      snmp_inc_snmpingetnexts();
-      derr = ERR_OK;
-      break;
-
-    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP):
-      // GetResponse PDU 
-      snmp_inc_snmpingetresponses();
-      derr = ERR_ARG;
-      break;
-    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ):
-      // SetRequest PDU 
-      snmp_inc_snmpinsetrequests();
-      derr = ERR_OK;
-      break;
-    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP):
-      // Trap PDU 
-      snmp_inc_snmpintraps();
-      derr = ERR_ARG;
-      break;
-    default:
-      snmp_inc_snmpinasnparseerrs();
-      derr = ERR_ARG;
-      break;
-  }
-  if (derr != ERR_OK)
-  {
-    /* unsupported input PDU for this agent (no parse error) */
-    return ERR_ARG;
-  }
-  m_stat->rt = type & 0x1F;
-  ofs += (1 + len_octets);
-  if (len != (pdu_len - (ofs - ofs_base)))
-  {
-    /* decoded PDU length does not equal actual payload length */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
-  {
-    /* can't decode or no integer (request ID) */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid);
-  if (derr != ERR_OK)
-  {
-    /* can't decode */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  ofs += (1 + len_octets + len);
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
-  {
-    /* can't decode or no integer (error-status) */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  /* must be noError (0) for incoming requests.
-     log errors for mib-2 completeness and for debug purposes */
-  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status);
-  if (derr != ERR_OK)
-  {
-    /* can't decode */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  switch (m_stat->error_status)
-  {
-    case SNMP_ES_TOOBIG:
-      snmp_inc_snmpintoobigs();
-      break;
-    case SNMP_ES_NOSUCHNAME:
-      snmp_inc_snmpinnosuchnames();
-      break;
-    case SNMP_ES_BADVALUE:
-      snmp_inc_snmpinbadvalues();
-      break;
-    case SNMP_ES_READONLY:
-      snmp_inc_snmpinreadonlys();
-      break;
-    case SNMP_ES_GENERROR:
-      snmp_inc_snmpingenerrs();
-      break;
-  }
-  ofs += (1 + len_octets + len);
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
-  {
-    /* can't decode or no integer (error-index) */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  /* must be 0 for incoming requests.
-     decode anyway to catch bad integers (and dirty tricks) */
-  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index);
-  if (derr != ERR_OK)
-  {
-    /* can't decode */
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  ofs += (1 + len_octets + len);
-  *ofs_ret = ofs;
-  return ERR_OK;
-}
-
-static err_t
-snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
-{
-  err_t derr;
-  u16_t len, vb_len;
-  u8_t  len_octets;
-  u8_t type;
-
-  /* variable binding list */
-  snmp_asn1_dec_type(p, ofs, &type);
-  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len);
-  if ((derr != ERR_OK) ||
-      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
-  {
-    snmp_inc_snmpinasnparseerrs();
-    return ERR_ARG;
-  }
-  ofs += (1 + len_octets);
-
-  /* start with empty list */
-  m_stat->invb.count = 0;
-  m_stat->invb.head = NULL;
-  m_stat->invb.tail = NULL;
-
-  while (vb_len > 0)
-  {
-    struct snmp_obj_id oid, oid_value;
-    struct snmp_varbind *vb;
-
-    snmp_asn1_dec_type(p, ofs, &type);
-    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-    if ((derr != ERR_OK) ||
-        (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) ||
-        (len == 0) || (len > vb_len))
-    {
-      snmp_inc_snmpinasnparseerrs();
-      /* free varbinds (if available) */
-      snmp_varbind_list_free(&m_stat->invb);
-      return ERR_ARG;
-    }
-    ofs += (1 + len_octets);
-    vb_len -= (1 + len_octets);
-
-    snmp_asn1_dec_type(p, ofs, &type);
-    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-    if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)))
-    {
-      /* can't decode object name length */
-      snmp_inc_snmpinasnparseerrs();
-      /* free varbinds (if available) */
-      snmp_varbind_list_free(&m_stat->invb);
-      return ERR_ARG;
-    }
-    derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid);
-    if (derr != ERR_OK)
-    {
-      /* can't decode object name */
-      snmp_inc_snmpinasnparseerrs();
-      /* free varbinds (if available) */
-      snmp_varbind_list_free(&m_stat->invb);
-      return ERR_ARG;
-    }
-    ofs += (1 + len_octets + len);
-    vb_len -= (1 + len_octets + len);
-
-    snmp_asn1_dec_type(p, ofs, &type);
-    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
-    if (derr != ERR_OK)
-    {
-      /* can't decode object value length */
-      snmp_inc_snmpinasnparseerrs();
-      /* free varbinds (if available) */
-      snmp_varbind_list_free(&m_stat->invb);
-      return ERR_ARG;
-    }
-
-    switch (type)
-    {
-      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
-        vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t));
-        if (vb != NULL)
-        {
-          s32_t *vptr = (s32_t*)vb->value;
-
-          derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr);
-          snmp_varbind_tail_add(&m_stat->invb, vb);
-        }
-        else
-        {
-          derr = ERR_ARG;
-        }
-        break;
-      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
-      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
-      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
-        vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t));
-        if (vb != NULL)
-        {
-          u32_t *vptr = (u32_t*)vb->value;
-
-          derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr);
-          snmp_varbind_tail_add(&m_stat->invb, vb);
-        }
-        else
-        {
-          derr = ERR_ARG;
-        }
-        break;
-      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
-      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
-        LWIP_ASSERT("invalid length", len <= 0xff);
-        vb = snmp_varbind_alloc(&oid, type, (u8_t)len);
-        if (vb != NULL)
-        {
-          derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
-          snmp_varbind_tail_add(&m_stat->invb, vb);
-        }
-        else
-        {
-          derr = ERR_ARG;
-        }
-        break;
-      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
-        vb = snmp_varbind_alloc(&oid, type, 0);
-        if (vb != NULL)
-        {
-          snmp_varbind_tail_add(&m_stat->invb, vb);
-          derr = ERR_OK;
-        }
-        else
-        {
-          derr = ERR_ARG;
-        }
-        break;
-      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
-        derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value);
-        if (derr == ERR_OK)
-        {
-          vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t));
-          if (vb != NULL)
-          {
-            u8_t i = oid_value.len;
-            s32_t *vptr = (s32_t*)vb->value;
-
-            while(i > 0)
-            {
-              i--;
-              vptr[i] = oid_value.id[i];
-            }
-            snmp_varbind_tail_add(&m_stat->invb, vb);
-            derr = ERR_OK;
-          }
-          else
-          {
-            derr = ERR_ARG;
-          }
-        }
-        break;
-      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
-        if (len == 4)
-        {
-          /* must be exactly 4 octets! */
-          vb = snmp_varbind_alloc(&oid, type, 4);
-          if (vb != NULL)
-          {
-            derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
-            snmp_varbind_tail_add(&m_stat->invb, vb);
-          }
-          else
-          {
-            derr = ERR_ARG;
-          }
-        }
-        else
-        {
-          derr = ERR_ARG;
-        }
-        break;
-      default:
-        derr = ERR_ARG;
-        break;
-    }
-    if (derr != ERR_OK)
-    {
-      snmp_inc_snmpinasnparseerrs();
-      /* free varbinds (if available) */
-      snmp_varbind_list_free(&m_stat->invb);
-      return ERR_ARG;
-    }
-    ofs += (1 + len_octets + len);
-    vb_len -= (1 + len_octets + len);
-  }
-
-  if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ)
-  {
-    snmp_add_snmpintotalsetvars(m_stat->invb.count);
-  }
-  else
-  {
-    snmp_add_snmpintotalreqvars(m_stat->invb.count);
-  }
-
-  *ofs_ret = ofs;
-  return ERR_OK;
-}
-
-struct snmp_varbind*
-snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
-{
-  struct snmp_varbind *vb;
-
-  vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
-  if (vb != NULL)
-  {
-    u8_t i;
-
-    vb->next = NULL;
-    vb->prev = NULL;
-    i = oid->len;
-    vb->ident_len = i;
-    if (i > 0)
-    {
-      LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH);
-      /* allocate array of s32_t for our object identifier */
-      vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE);
-      if (vb->ident == NULL)
-      {
-        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n"));
-        memp_free(MEMP_SNMP_VARBIND, vb);
-        return NULL;
-      }
-      while(i > 0)
-      {
-        i--;
-        vb->ident[i] = oid->id[i];
-      }
-    }
-    else
-    {
-      /* i == 0, pass zero length object identifier */
-      vb->ident = NULL;
-    }
-    vb->value_type = type;
-    vb->value_len = len;
-    if (len > 0)
-    {
-      LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
-      /* allocate raw bytes for our object value */
-      vb->value = memp_malloc(MEMP_SNMP_VALUE);
-      if (vb->value == NULL)
-      {
-        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n"));
-        if (vb->ident != NULL)
-        {
-          memp_free(MEMP_SNMP_VALUE, vb->ident);
-        }
-        memp_free(MEMP_SNMP_VARBIND, vb);
-        return NULL;
-      }
-    }
-    else
-    {
-      /* ASN1_NUL type, or zero length ASN1_OC_STR */
-      vb->value = NULL;
-    }
-  }
-  else
-  {
-    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n"));
-  }
-  return vb;
-}
-
-void
-snmp_varbind_free(struct snmp_varbind *vb)
-{
-  if (vb->value != NULL )
-  {
-    memp_free(MEMP_SNMP_VALUE, vb->value);
-  }
-  if (vb->ident != NULL )
-  {
-    memp_free(MEMP_SNMP_VALUE, vb->ident);
-  }
-  memp_free(MEMP_SNMP_VARBIND, vb);
-}
-
-void
-snmp_varbind_list_free(struct snmp_varbind_root *root)
-{
-  struct snmp_varbind *vb, *prev;
-
-  vb = root->tail;
-  while ( vb != NULL )
-  {
-    prev = vb->prev;
-    snmp_varbind_free(vb);
-    vb = prev;
-  }
-  root->count = 0;
-  root->head = NULL;
-  root->tail = NULL;
-}
-
-void
-snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
-{
-  if (root->count == 0)
-  {
-    /* add first varbind to list */
-    root->head = vb;
-    root->tail = vb;
-  }
-  else
-  {
-    /* add nth varbind to list tail */
-    root->tail->next = vb;
-    vb->prev = root->tail;
-    root->tail = vb;
-  }
-  root->count += 1;
-}
-
-struct snmp_varbind*
-snmp_varbind_tail_remove(struct snmp_varbind_root *root)
-{
-  struct snmp_varbind* vb;
-
-  if (root->count > 0)
-  {
-    /* remove tail varbind */
-    vb = root->tail;
-    root->tail = vb->prev;
-    vb->prev->next = NULL;
-    root->count -= 1;
-  }
-  else
-  {
-    /* nothing to remove */
-    vb = NULL;
-  }
-  return vb;
-}
-
-#endif /* LWIP_SNMP */
+/**
+ * @file
+ * SNMP input message processing (RFC1157).
+ */
+
+/*
+ * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * Author: Christiaan Simons <christiaan.simons@axon.tv>
+ */
+
+#include "lwip/opt.h"
+#include "settings_api.h"
+
+#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
+
+#include "lwip/snmp.h"
+#include "lwip/snmp_asn1.h"
+#include "lwip/snmp_msg.h"
+#include "lwip/snmp_structs.h"
+#include "lwip/ip_addr.h"
+#include "lwip/memp.h"
+#include "lwip/udp.h"
+#include "lwip/stats.h"
+
+#include <string.h>
+
+/* public (non-static) constants */
+/** SNMP v1 == 0 */
+const s32_t snmp_version = 0;
+/** default SNMP community string */
+const char snmp_publiccommunity[7] = "public";
+
+/**
+  * @brief  Общая структура настроек
+  */
+extern SETTINGS_t sSettings;
+
+/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */
+struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS];
+/* UDP Protocol Control Block */
+struct udp_pcb *snmp1_pcb;
+
+static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port);
+static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
+static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
+
+
+/**
+ * Starts SNMP Agent.
+ * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161.
+ */
+void
+snmp_init(void)
+{
+  struct snmp_msg_pstat *msg_ps;
+  u8_t i;
+
+  snmp1_pcb = udp_new();
+  if (snmp1_pcb != NULL)
+  {
+    udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT);
+    udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT);
+  }
+  msg_ps = &msg_input_list[0];
+  for (i=0; i<SNMP_CONCURRENT_REQUESTS; i++)
+  {
+    msg_ps->state = SNMP_MSG_EMPTY;
+    msg_ps->error_index = 0;
+    msg_ps->error_status = SNMP_ES_NOERROR;
+    msg_ps++;
+  }
+  trap_msg.pcb = snmp1_pcb;
+
+#ifdef SNMP_PRIVATE_MIB_INIT
+  /* If defined, this must be a function-like define to initialize the
+   * private MIB after the stack has been initialized.
+   * The private MIB can also be initialized in tcpip_callback (or after
+   * the stack is initialized), this define is only for convenience. */
+  SNMP_PRIVATE_MIB_INIT();
+#endif /* SNMP_PRIVATE_MIB_INIT */
+
+  /* The coldstart trap will only be output
+     if our outgoing interface is up & configured  */
+  //snmp_coldstart_trap();
+}
+
+static void
+snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error)
+{
+  /* move names back from outvb to invb */
+  int v;
+  struct snmp_varbind *vbi = msg_ps->invb.head;
+  struct snmp_varbind *vbo = msg_ps->outvb.head;
+  for (v=0; v<msg_ps->vb_idx; v++) {
+    vbi->ident_len = vbo->ident_len;
+    vbo->ident_len = 0;
+    vbi->ident = vbo->ident;
+    vbo->ident = NULL;
+    vbi = vbi->next;
+    vbo = vbo->next;
+  }
+  /* free outvb */
+  snmp_varbind_list_free(&msg_ps->outvb);
+  /* we send invb back */
+  msg_ps->outvb = msg_ps->invb;
+  msg_ps->invb.head = NULL;
+  msg_ps->invb.tail = NULL;
+  msg_ps->invb.count = 0;
+  msg_ps->error_status = error;
+  /* error index must be 0 for error too big */
+  msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0;
+  snmp_send_response(msg_ps);
+  snmp_varbind_list_free(&msg_ps->outvb);
+  msg_ps->state = SNMP_MSG_EMPTY;
+}
+
+static void
+snmp_ok_response(struct snmp_msg_pstat *msg_ps)
+{
+  err_t err_ret;
+
+  err_ret = snmp_send_response(msg_ps);
+  if (err_ret == ERR_MEM)
+  {
+    /* serious memory problem, can't return tooBig */
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status));
+  }
+  /* free varbinds (if available) */
+  snmp_varbind_list_free(&msg_ps->invb);
+  snmp_varbind_list_free(&msg_ps->outvb);
+  msg_ps->state = SNMP_MSG_EMPTY;
+}
+
+/**
+ * Service an internal or external event for SNMP GET.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) &&
+        (msg_ps->ext_object_def.access & MIB_ACCESS_READ))
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
+      en->get_value_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
+  {
+    struct mib_external_node *en;
+    struct snmp_varbind *vb;
+
+    /* get_value() answer */
+    en = msg_ps->ext_mib_node;
+
+    /* allocate output varbind */
+    vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+    if (vb != NULL)
+    {
+      vb->next = NULL;
+      vb->prev = NULL;
+
+      /* move name from invb to outvb */
+      vb->ident = msg_ps->vb_ptr->ident;
+      vb->ident_len = msg_ps->vb_ptr->ident_len;
+      /* ensure this memory is refereced once only */
+      msg_ps->vb_ptr->ident = NULL;
+      msg_ps->vb_ptr->ident_len = 0;
+
+      vb->value_type = msg_ps->ext_object_def.asn_type;
+      LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
+      vb->value_len = (u8_t)msg_ps->ext_object_def.v_len;
+      if (vb->value_len > 0)
+      {
+        LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
+        vb->value = memp_malloc(MEMP_SNMP_VALUE);
+        if (vb->value != NULL)
+        {
+          en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
+          snmp_varbind_tail_add(&msg_ps->outvb, vb);
+          /* search again (if vb_idx < msg_ps->invb.count) */
+          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+          msg_ps->vb_idx += 1;
+        }
+        else
+        {
+          en->get_value_pc(request_id, &msg_ps->ext_object_def);
+          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n"));
+          msg_ps->vb_ptr->ident = vb->ident;
+          msg_ps->vb_ptr->ident_len = vb->ident_len;
+          memp_free(MEMP_SNMP_VARBIND, vb);
+          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+        }
+      }
+      else
+      {
+        /* vb->value_len == 0, empty value (e.g. empty string) */
+        en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL);
+        vb->value = NULL;
+        snmp_varbind_tail_add(&msg_ps->outvb, vb);
+        /* search again (if vb_idx < msg_ps->invb.count) */
+        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+        msg_ps->vb_idx += 1;
+      }
+    }
+    else
+    {
+      en->get_value_pc(request_id, &msg_ps->ext_object_def);
+      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n"));
+      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+    }
+  }
+
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /** test object identifier for .iso.org.dod.internet prefix */
+    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
+    {
+      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                             msg_ps->vb_ptr->ident + 4, &np);
+      if (mn != NULL)
+      {
+        if (mn->node_type == MIB_NODE_EX)
+        {
+          /* external object */
+          struct mib_external_node *en = (struct mib_external_node*)mn;
+
+          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+          /* save en && args in msg_ps!! */
+          msg_ps->ext_mib_node = en;
+          msg_ps->ext_name_ptr = np;
+
+          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+        }
+        else
+        {
+          /* internal object */
+          struct obj_def object_def;
+
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+          mn->get_object_def(np.ident_len, np.ident, &object_def);
+          if ((object_def.instance != MIB_OBJECT_NONE) &&
+            (object_def.access & MIB_ACCESS_READ))
+          {
+            mn = mn;
+          }
+          else
+          {
+            /* search failed, object id points to unknown object (nosuchname) */
+            mn =  NULL;
+          }
+          if (mn != NULL)
+          {
+            struct snmp_varbind *vb;
+
+            msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
+            /* allocate output varbind */
+            vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+            if (vb != NULL)
+            {
+              vb->next = NULL;
+              vb->prev = NULL;
+
+              /* move name from invb to outvb */
+              vb->ident = msg_ps->vb_ptr->ident;
+              vb->ident_len = msg_ps->vb_ptr->ident_len;
+              /* ensure this memory is refereced once only */
+              msg_ps->vb_ptr->ident = NULL;
+              msg_ps->vb_ptr->ident_len = 0;
+
+              vb->value_type = object_def.asn_type;
+              LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
+              vb->value_len = (u8_t)object_def.v_len;
+              if (vb->value_len > 0)
+              {
+                LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low",
+                  vb->value_len <= SNMP_MAX_VALUE_SIZE);
+                vb->value = memp_malloc(MEMP_SNMP_VALUE);
+                if (vb->value != NULL)
+                {
+                  mn->get_value(&object_def, vb->value_len, vb->value);
+                  snmp_varbind_tail_add(&msg_ps->outvb, vb);
+                  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                  msg_ps->vb_idx += 1;
+                }
+                else
+                {
+                  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n"));
+                  msg_ps->vb_ptr->ident = vb->ident;
+                  msg_ps->vb_ptr->ident_len = vb->ident_len;
+                  vb->ident = NULL;
+                  vb->ident_len = 0;
+                  memp_free(MEMP_SNMP_VARBIND, vb);
+                  snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+                }
+              }
+              else
+              {
+                /* vb->value_len == 0, empty value (e.g. empty string) */
+                vb->value = NULL;
+                snmp_varbind_tail_add(&msg_ps->outvb, vb);
+                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                msg_ps->vb_idx += 1;
+              }
+            }
+            else
+            {
+              LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n"));
+              snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    snmp_ok_response(msg_ps);
+  }
+}
+
+/**
+ * Service an internal or external event for SNMP GETNEXT.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE;
+      en->get_value_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE)
+  {
+    struct mib_external_node *en;
+    struct snmp_varbind *vb;
+
+    /* get_value() answer */
+    en = msg_ps->ext_mib_node;
+
+    LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff);
+    vb = snmp_varbind_alloc(&msg_ps->ext_oid,
+                            msg_ps->ext_object_def.asn_type,
+                            (u8_t)msg_ps->ext_object_def.v_len);
+    if (vb != NULL)
+    {
+      en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value);
+      snmp_varbind_tail_add(&msg_ps->outvb, vb);
+      msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+      msg_ps->vb_idx += 1;
+    }
+    else
+    {
+      en->get_value_pc(request_id, &msg_ps->ext_object_def);
+      LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n"));
+      snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+    }
+  }
+
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_obj_id oid;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid))
+    {
+      if (msg_ps->vb_ptr->ident_len > 3)
+      {
+        /* can offset ident_len and ident */
+        mn = snmp_expand_tree((struct mib_node*)&internet,
+                              msg_ps->vb_ptr->ident_len - 4,
+                              msg_ps->vb_ptr->ident + 4, &oid);
+      }
+      else
+      {
+        /* can't offset ident_len -4, ident + 4 */
+        mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid);
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn != NULL)
+    {
+      if (mn->node_type == MIB_NODE_EX)
+      {
+        /* external object */
+        struct mib_external_node *en = (struct mib_external_node*)mn;
+
+        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+        /* save en && args in msg_ps!! */
+        msg_ps->ext_mib_node = en;
+        msg_ps->ext_oid = oid;
+
+        en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]);
+      }
+      else
+      {
+        /* internal object */
+        struct obj_def object_def;
+        struct snmp_varbind *vb;
+
+        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+        mn->get_object_def(1, &oid.id[oid.len - 1], &object_def);
+
+        LWIP_ASSERT("invalid length", object_def.v_len <= 0xff);
+        vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len);
+        if (vb != NULL)
+        {
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE;
+          mn->get_value(&object_def, object_def.v_len, vb->value);
+          snmp_varbind_tail_add(&msg_ps->outvb, vb);
+          msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+          msg_ps->vb_idx += 1;
+        }
+        else
+        {
+          LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n"));
+          snmp_error_response(msg_ps,SNMP_ES_TOOBIG);
+        }
+      }
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    snmp_ok_response(msg_ps);
+  }
+}
+
+/**
+ * Service an internal or external event for SNMP SET.
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ * @param msg_ps points to the assosicated message process state
+ */
+static void
+snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps)
+{
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state));
+
+  if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST;
+      en->set_test_q(request_id, &msg_ps->ext_object_def);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* search failed, object id points to unknown object (nosuchname) */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST)
+  {
+    struct mib_external_node *en;
+
+    /* set_test() answer*/
+    en = msg_ps->ext_mib_node;
+
+    if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE)
+    {
+       if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) &&
+           (en->set_test_a(request_id,&msg_ps->ext_object_def,
+                           msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
+      {
+        msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+        msg_ps->vb_idx += 1;
+      }
+      else
+      {
+        en->set_test_pc(request_id,&msg_ps->ext_object_def);
+        /* bad value */
+        snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
+      }
+    }
+    else
+    {
+      en->set_test_pc(request_id,&msg_ps->ext_object_def);
+      /* object not available for set */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S)
+  {
+    struct mib_external_node *en;
+    struct snmp_name_ptr np;
+
+    /* get_object_def() answer*/
+    en = msg_ps->ext_mib_node;
+    np = msg_ps->ext_name_ptr;
+
+    /* translate answer into a known lifeform */
+    en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def);
+    if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE)
+    {
+      msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE;
+      en->set_value_q(request_id, &msg_ps->ext_object_def,
+                      msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
+    }
+    else
+    {
+      en->get_object_def_pc(request_id, np.ident_len, np.ident);
+      /* set_value failed, object has disappeared for some odd reason?? */
+      snmp_error_response(msg_ps,SNMP_ES_GENERROR);
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE)
+  {
+    struct mib_external_node *en;
+
+    /** set_value_a() */
+    en = msg_ps->ext_mib_node;
+    en->set_value_a(request_id, &msg_ps->ext_object_def,
+      msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value);
+
+    /** @todo use set_value_pc() if toobig */
+    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+    msg_ps->vb_idx += 1;
+  }
+
+  /* test all values before setting */
+  while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /** test object identifier for .iso.org.dod.internet prefix */
+    if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
+    {
+      mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                             msg_ps->vb_ptr->ident + 4, &np);
+      if (mn != NULL)
+      {
+        if (mn->node_type == MIB_NODE_EX)
+        {
+          /* external object */
+          struct mib_external_node *en = (struct mib_external_node*)mn;
+
+          msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF;
+          /* save en && args in msg_ps!! */
+          msg_ps->ext_mib_node = en;
+          msg_ps->ext_name_ptr = np;
+
+          en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+        }
+        else
+        {
+          /* internal object */
+          struct obj_def object_def;
+
+          msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF;
+          mn->get_object_def(np.ident_len, np.ident, &object_def);
+          if (object_def.instance != MIB_OBJECT_NONE)
+          {
+            mn = mn;
+          }
+          else
+          {
+            /* search failed, object id points to unknown object (nosuchname) */
+            mn = NULL;
+          }
+          if (mn != NULL)
+          {
+            msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST;
+
+            if (object_def.access & MIB_ACCESS_WRITE)
+            {
+              if ((object_def.asn_type == msg_ps->vb_ptr->value_type) &&
+                  (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0))
+              {
+                msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+                msg_ps->vb_idx += 1;
+              }
+              else
+              {
+                /* bad value */
+                snmp_error_response(msg_ps,SNMP_ES_BADVALUE);
+              }
+            }
+            else
+            {
+              /* object not available for set */
+              snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+            }
+          }
+        }
+      }
+    }
+    else
+    {
+      mn = NULL;
+    }
+    if (mn == NULL)
+    {
+      /* mn == NULL, noSuchName */
+      snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME);
+    }
+  }
+
+  if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    msg_ps->vb_idx = 0;
+    msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+  }
+
+  /* set all values "atomically" (be as "atomic" as possible) */
+  while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
+         (msg_ps->vb_idx < msg_ps->invb.count))
+  {
+    struct mib_node *mn;
+    struct snmp_name_ptr np;
+
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+    }
+    /* skip iso prefix test, was done previously while settesting() */
+    mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                           msg_ps->vb_ptr->ident + 4, &np);
+    /* check if object is still available
+       (e.g. external hot-plug thingy present?) */
+    if (mn != NULL)
+    {
+      if (mn->node_type == MIB_NODE_EX)
+      {
+        /* external object */
+        struct mib_external_node *en = (struct mib_external_node*)mn;
+
+        msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S;
+        /* save en && args in msg_ps!! */
+        msg_ps->ext_mib_node = en;
+        msg_ps->ext_name_ptr = np;
+
+        en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident);
+      }
+      else
+      {
+        /* internal object */
+        struct obj_def object_def;
+
+        msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S;
+        mn->get_object_def(np.ident_len, np.ident, &object_def);
+        msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE;
+        mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value);
+        msg_ps->vb_idx += 1;
+      }
+    }
+  }
+  if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) &&
+      (msg_ps->vb_idx == msg_ps->invb.count))
+  {
+    /* simply echo the input if we can set it
+       @todo do we need to return the actual value?
+       e.g. if value is silently modified or behaves sticky? */
+    msg_ps->outvb = msg_ps->invb;
+    msg_ps->invb.head = NULL;
+    msg_ps->invb.tail = NULL;
+    msg_ps->invb.count = 0;
+    snmp_ok_response(msg_ps);
+  }
+}
+
+
+/**
+ * Handle one internal or external event.
+ * Called for one async event. (recv external/private answer)
+ *
+ * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1)
+ */
+void
+snmp_msg_event(u8_t request_id)
+{
+  struct snmp_msg_pstat *msg_ps;
+
+  if (request_id < SNMP_CONCURRENT_REQUESTS)
+  {
+    msg_ps = &msg_input_list[request_id];
+    if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
+    {
+      snmp_msg_getnext_event(request_id, msg_ps);
+    }
+    else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
+    {
+      snmp_msg_get_event(request_id, msg_ps);
+    }
+    else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
+    {
+      snmp_msg_set_event(request_id, msg_ps);
+    }
+  }
+}
+
+
+/* lwIP UDP receive callback function */
+static void
+snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
+{
+  //volatile struct snmp_msg_pstat *msg_ps;
+  struct snmp_msg_pstat *msg_ps;
+  u8_t req_idx;
+  err_t err_ret;
+  u16_t payload_len = p->tot_len;
+  u16_t payload_ofs = 0;
+  u16_t varbind_ofs = 0;
+
+  /* suppress unused argument warning */
+  LWIP_UNUSED_ARG(arg);
+
+  /* traverse input message process list, look for SNMP_MSG_EMPTY */
+  msg_ps = &msg_input_list[0];
+  req_idx = 0;
+  while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY))
+  {
+    req_idx++;
+    msg_ps++;
+  }
+  if (req_idx == SNMP_CONCURRENT_REQUESTS)
+  {
+    /* exceeding number of concurrent requests */
+    pbuf_free(p);
+    return;
+  }
+
+  /* accepting request */
+  snmp_inc_snmpinpkts();
+  /* record used 'protocol control block' */
+  msg_ps->pcb = pcb;
+  /* source address (network order) */
+  msg_ps->sip = *addr;
+  /* source port (host order (lwIP oddity)) */
+  msg_ps->sp = port;
+
+  /* check total length, version, community, pdu type */
+  err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps);
+  /* Only accept requests and requests without error (be robust) */
+  /* Reject response and trap headers or error requests as input! */
+  if ((err_ret != ERR_OK) ||
+      ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) &&
+       (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) &&
+       (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) ||
+      ((msg_ps->error_status != SNMP_ES_NOERROR) ||
+       (msg_ps->error_index != 0)) )
+  {
+    /* header check failed drop request silently, do not return error! */
+    pbuf_free(p);
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n"));
+    return;
+  }
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community));
+
+  /* Builds a list of variable bindings. Copy the varbinds from the pbuf
+    chain to glue them when these are divided over two or more pbuf's. */
+  err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
+  /* we've decoded the incoming message, release input msg now */
+  pbuf_free(p);
+  if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0))
+  {
+    /* varbind-list decode failed, or varbind list empty.
+       drop request silently, do not return error!
+       (errors are only returned for a specific varbind failure) */
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n"));
+    return;
+  }
+
+  msg_ps->error_status = SNMP_ES_NOERROR;
+  msg_ps->error_index = 0;
+  /* find object for each variable binding */
+  msg_ps->state = SNMP_MSG_SEARCH_OBJ;
+  /* first variable binding from list to inspect */
+  msg_ps->vb_idx = 0;
+
+  LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count));
+
+  /* handle input event and as much objects as possible in one go */
+  snmp_msg_event(req_idx);
+}
+
+/**
+ * Checks and decodes incoming SNMP message header, logs header errors.
+ *
+ * @param p points to pbuf chain of SNMP message (UDP payload)
+ * @param ofs points to first octet of SNMP message
+ * @param pdu_len the length of the UDP payload
+ * @param ofs_ret returns the ofset of the variable bindings
+ * @param m_stat points to the current message request state return
+ * @return
+ * - ERR_OK SNMP header is sane and accepted
+ * - ERR_ARG SNMP header is either malformed or rejected
+ */
+static err_t
+snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
+{
+  err_t derr;
+  u16_t len, ofs_base;
+  u8_t  len_octets;
+  u8_t  type;
+  s32_t version;
+
+  ofs_base = ofs;
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) ||
+      (pdu_len != (1 + len_octets + len)) ||
+      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (version) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  if (version != 0)
+  {
+    /* not version 1 */
+    snmp_inc_snmpinbadversions();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
+  {
+    /* can't decode or no octet string (community) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community);
+  if (derr != ERR_OK)
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* add zero terminator */
+  len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
+  m_stat->community[len] = 0;
+  m_stat->com_strlen = (u8_t)len;
+  
+  /* Проверка public communuty */
+  /*
+  if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
+  {
+    // @todo: move this if we need to check more names 
+    snmp_inc_snmpinbadcommunitynames();
+    snmp_authfail_trap();
+    return ERR_ARG;
+  }*/
+  
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if (derr != ERR_OK)
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  
+  /* FIX for write/read communuty */
+  /* GetRequest PDU */
+  if (type == (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ)) 
+  {	
+  	if (strncmp(sSettings.sSnmp.readCommunity, (const char*)m_stat->community, strlen(sSettings.sSnmp.readCommunity)) != 0
+		|| (strlen(sSettings.sSnmp.readCommunity) != strlen((const char*)m_stat->community)) )
+    {
+      snmp_inc_snmpinbadcommunitynames();
+      snmp_authfail_trap();
+      return ERR_ARG;
+    }
+  }	
+  /* SetRequest PDU */
+  else if (type == (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ)) 	
+  {
+    if (strncmp(sSettings.sSnmp.writeCommunity, (const char*)m_stat->community, strlen(sSettings.sSnmp.writeCommunity)) != 0
+		|| (strlen(sSettings.sSnmp.writeCommunity) != strlen((const char*)m_stat->community)) )
+    {
+      snmp_inc_snmpinbadcommunitynames();
+      snmp_authfail_trap();
+      return ERR_ARG;
+    }
+  }	
+  
+  switch(type)
+  {
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ):
+      // GetRequest PDU 
+      snmp_inc_snmpingetrequests();
+      derr = ERR_OK;
+      break;
+
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ):
+      // GetNextRequest PDU 
+      snmp_inc_snmpingetnexts();
+      derr = ERR_OK;
+      break;
+
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP):
+      // GetResponse PDU 
+      snmp_inc_snmpingetresponses();
+      derr = ERR_ARG;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ):
+      // SetRequest PDU 
+      snmp_inc_snmpinsetrequests();
+      derr = ERR_OK;
+      break;
+    case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP):
+      // Trap PDU 
+      snmp_inc_snmpintraps();
+      derr = ERR_ARG;
+      break;
+    default:
+      snmp_inc_snmpinasnparseerrs();
+      derr = ERR_ARG;
+      break;
+  }
+  if (derr != ERR_OK)
+  {
+    /* unsupported input PDU for this agent (no parse error) */
+    return ERR_ARG;
+  }
+  m_stat->rt = type & 0x1F;
+  ofs += (1 + len_octets);
+  if (len != (pdu_len - (ofs - ofs_base)))
+  {
+    /* decoded PDU length does not equal actual payload length */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (request ID) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (error-status) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* must be noError (0) for incoming requests.
+     log errors for mib-2 completeness and for debug purposes */
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  switch (m_stat->error_status)
+  {
+    case SNMP_ES_TOOBIG:
+      snmp_inc_snmpintoobigs();
+      break;
+    case SNMP_ES_NOSUCHNAME:
+      snmp_inc_snmpinnosuchnames();
+      break;
+    case SNMP_ES_BADVALUE:
+      snmp_inc_snmpinbadvalues();
+      break;
+    case SNMP_ES_READONLY:
+      snmp_inc_snmpinreadonlys();
+      break;
+    case SNMP_ES_GENERROR:
+      snmp_inc_snmpingenerrs();
+      break;
+  }
+  ofs += (1 + len_octets + len);
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+  if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
+  {
+    /* can't decode or no integer (error-index) */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  /* must be 0 for incoming requests.
+     decode anyway to catch bad integers (and dirty tricks) */
+  derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index);
+  if (derr != ERR_OK)
+  {
+    /* can't decode */
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets + len);
+  *ofs_ret = ofs;
+  return ERR_OK;
+}
+
+static err_t
+snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat)
+{
+  err_t derr;
+  u16_t len, vb_len;
+  u8_t  len_octets;
+  u8_t type;
+
+  /* variable binding list */
+  snmp_asn1_dec_type(p, ofs, &type);
+  derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len);
+  if ((derr != ERR_OK) ||
+      (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)))
+  {
+    snmp_inc_snmpinasnparseerrs();
+    return ERR_ARG;
+  }
+  ofs += (1 + len_octets);
+
+  /* start with empty list */
+  m_stat->invb.count = 0;
+  m_stat->invb.head = NULL;
+  m_stat->invb.tail = NULL;
+
+  while (vb_len > 0)
+  {
+    struct snmp_obj_id oid, oid_value;
+    struct snmp_varbind *vb;
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if ((derr != ERR_OK) ||
+        (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) ||
+        (len == 0) || (len > vb_len))
+    {
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets);
+    vb_len -= (1 + len_octets);
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)))
+    {
+      /* can't decode object name length */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid);
+    if (derr != ERR_OK)
+    {
+      /* can't decode object name */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets + len);
+    vb_len -= (1 + len_octets + len);
+
+    snmp_asn1_dec_type(p, ofs, &type);
+    derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
+    if (derr != ERR_OK)
+    {
+      /* can't decode object value length */
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+
+    switch (type)
+    {
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG):
+        vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t));
+        if (vb != NULL)
+        {
+          s32_t *vptr = (s32_t*)vb->value;
+
+          derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS):
+        vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t));
+        if (vb != NULL)
+        {
+          u32_t *vptr = (u32_t*)vb->value;
+
+          derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR):
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE):
+        LWIP_ASSERT("invalid length", len <= 0xff);
+        vb = snmp_varbind_alloc(&oid, type, (u8_t)len);
+        if (vb != NULL)
+        {
+          derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL):
+        vb = snmp_varbind_alloc(&oid, type, 0);
+        if (vb != NULL)
+        {
+          snmp_varbind_tail_add(&m_stat->invb, vb);
+          derr = ERR_OK;
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID):
+        derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value);
+        if (derr == ERR_OK)
+        {
+          vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t));
+          if (vb != NULL)
+          {
+            u8_t i = oid_value.len;
+            s32_t *vptr = (s32_t*)vb->value;
+
+            while(i > 0)
+            {
+              i--;
+              vptr[i] = oid_value.id[i];
+            }
+            snmp_varbind_tail_add(&m_stat->invb, vb);
+            derr = ERR_OK;
+          }
+          else
+          {
+            derr = ERR_ARG;
+          }
+        }
+        break;
+      case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR):
+        if (len == 4)
+        {
+          /* must be exactly 4 octets! */
+          vb = snmp_varbind_alloc(&oid, type, 4);
+          if (vb != NULL)
+          {
+            derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value);
+            snmp_varbind_tail_add(&m_stat->invb, vb);
+          }
+          else
+          {
+            derr = ERR_ARG;
+          }
+        }
+        else
+        {
+          derr = ERR_ARG;
+        }
+        break;
+      default:
+        derr = ERR_ARG;
+        break;
+    }
+    if (derr != ERR_OK)
+    {
+      snmp_inc_snmpinasnparseerrs();
+      /* free varbinds (if available) */
+      snmp_varbind_list_free(&m_stat->invb);
+      return ERR_ARG;
+    }
+    ofs += (1 + len_octets + len);
+    vb_len -= (1 + len_octets + len);
+  }
+
+  if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ)
+  {
+    snmp_add_snmpintotalsetvars(m_stat->invb.count);
+  }
+  else
+  {
+    snmp_add_snmpintotalreqvars(m_stat->invb.count);
+  }
+
+  *ofs_ret = ofs;
+  return ERR_OK;
+}
+
+struct snmp_varbind*
+snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
+{
+  struct snmp_varbind *vb;
+
+  vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND);
+  if (vb != NULL)
+  {
+    u8_t i;
+
+    vb->next = NULL;
+    vb->prev = NULL;
+    i = oid->len;
+    vb->ident_len = i;
+    if (i > 0)
+    {
+      LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH);
+      /* allocate array of s32_t for our object identifier */
+      vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE);
+      if (vb->ident == NULL)
+      {
+        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n"));
+        memp_free(MEMP_SNMP_VARBIND, vb);
+        return NULL;
+      }
+      while(i > 0)
+      {
+        i--;
+        vb->ident[i] = oid->id[i];
+      }
+    }
+    else
+    {
+      /* i == 0, pass zero length object identifier */
+      vb->ident = NULL;
+    }
+    vb->value_type = type;
+    vb->value_len = len;
+    if (len > 0)
+    {
+      LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE);
+      /* allocate raw bytes for our object value */
+      vb->value = memp_malloc(MEMP_SNMP_VALUE);
+      if (vb->value == NULL)
+      {
+        LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n"));
+        if (vb->ident != NULL)
+        {
+          memp_free(MEMP_SNMP_VALUE, vb->ident);
+        }
+        memp_free(MEMP_SNMP_VARBIND, vb);
+        return NULL;
+      }
+    }
+    else
+    {
+      /* ASN1_NUL type, or zero length ASN1_OC_STR */
+      vb->value = NULL;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n"));
+  }
+  return vb;
+}
+
+void
+snmp_varbind_free(struct snmp_varbind *vb)
+{
+  if (vb->value != NULL )
+  {
+    memp_free(MEMP_SNMP_VALUE, vb->value);
+  }
+  if (vb->ident != NULL )
+  {
+    memp_free(MEMP_SNMP_VALUE, vb->ident);
+  }
+  memp_free(MEMP_SNMP_VARBIND, vb);
+}
+
+void
+snmp_varbind_list_free(struct snmp_varbind_root *root)
+{
+  struct snmp_varbind *vb, *prev;
+
+  vb = root->tail;
+  while ( vb != NULL )
+  {
+    prev = vb->prev;
+    snmp_varbind_free(vb);
+    vb = prev;
+  }
+  root->count = 0;
+  root->head = NULL;
+  root->tail = NULL;
+}
+
+void
+snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
+{
+  if (root->count == 0)
+  {
+    /* add first varbind to list */
+    root->head = vb;
+    root->tail = vb;
+  }
+  else
+  {
+    /* add nth varbind to list tail */
+    root->tail->next = vb;
+    vb->prev = root->tail;
+    root->tail = vb;
+  }
+  root->count += 1;
+}
+
+struct snmp_varbind*
+snmp_varbind_tail_remove(struct snmp_varbind_root *root)
+{
+  struct snmp_varbind* vb;
+
+  if (root->count > 0)
+  {
+    /* remove tail varbind */
+    vb = root->tail;
+    root->tail = vb->prev;
+    vb->prev->next = NULL;
+    root->count -= 1;
+  }
+  else
+  {
+    /* nothing to remove */
+    vb = NULL;
+  }
+  return vb;
+}
+
+#endif /* LWIP_SNMP */

+ 4 - 6
user/init_task.c

@@ -9,7 +9,6 @@
  * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
  *******************************************************************************
  */
-  
 #include "init_task.h"
 #include "common_config.h"   
 #include "wdg.h"
@@ -75,12 +74,12 @@ void InitTask(void *params)
 // -----------------------------------------------------------------------------    
  // xTaskCreate(vTaskWdt, "WDT", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
 // -----------------------------------------------------------------------------    
-  InitUSART();
+  //InitUSART();
   ups_megatec_init();
 // -----------------------------------------------------------------------------    
  // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
-/*  SETTINGS_SetDefaultDebug();
-  SETTINGS_Save();*/
+  //SETTINGS_SetDefaultDebug();
+  //SETTINGS_Save();
   SETTINGS_Load();
 
   set_mode_jumper();
@@ -119,7 +118,7 @@ void InitTask(void *params)
 // -----------------------------------------------------------------------------      
   
   /* UDP for net settings */
-  UDP_netsetting_init();
+  //UDP_netsetting_init();
 // -----------------------------------------------------------------------------
 #ifdef UPS_ENABLE
  /* UPS_Init();
@@ -213,5 +212,4 @@ static void vTaskDebug(void *pvParameters)
 
 
 
-
 /********************************* (C) РОТЕК **********************************/

+ 9 - 3
user/main.c

@@ -11,9 +11,15 @@
 #include "spi_flash.h"
 
 /* Размещение стека FreeRTOS в CCRAM */
+#if defined ( __ICCARM__ ) // IAR Compiler 
+#pragma location = ".sram"
+uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
+#else
 uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".mb1text")));
+#endif
+
 /* Секция размещения СRC прошивки */
-uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
+//uint32_t crc __attribute__ ((section (".crc"))) = 0xAABBCCDD;
 
 void vApplicationTickHook(void) {
 }
@@ -28,7 +34,7 @@ int main()
 	NVIC_SetPriorityGrouping(0);
 	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
 	__enable_irq();
-	//WDG_Init();
+	WDG_Init();
 
 	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
 
@@ -38,7 +44,7 @@ int main()
 
 	gpio_init();
 
-	spi_flash_test();
+	//spi_flash_test();
 //  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
   
   xTaskCreate( InitTask, "InitTask", 1000, NULL, tskIDLE_PRIORITY, NULL);

+ 3 - 3
user/stm32f4xx_it.c

@@ -29,7 +29,7 @@
 
 /* Includes ------------------------------------------------------------------*/
 #include "stm32f4xx_it.h"
-#include "usart.h"
+//#include "usart.h"
 
 #ifdef OS_FREERTOS
 /* Scheduler includes */
@@ -116,7 +116,7 @@ void HardFault_Output(uint32_t *sp)
   * @param  None
   * @retval None
   */
-__attribute__( (naked) )
+/*__attribute__( (naked) )
 void HardFault_Handler(void)
 {
 __asm volatile
@@ -129,7 +129,7 @@ __asm volatile
         "bx r1                                         \n"
         "debugHardfault_address: .word HardFault_Output  \n"
     );
-}
+}*/
 
 /**
   * @brief  This function handles Memory Manage exception.