source: S-port/trunk/Core/Src/freertos.c

Last change on this file was 1, checked in by AlexLir, 3 years ago
File size: 57.2 KB
Line 
1/* USER CODE BEGIN Header */
2/**
3 ******************************************************************************
4 * File Name : freertos.c
5 * Description : Code for freertos applications
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under Ultimate Liberty license
13 * SLA0044, the "License"; You may not use this file except in compliance with
14 * the License. You may obtain a copy of the License at:
15 * www.st.com/SLA0044
16 *
17 ******************************************************************************
18 */
19#include "FreeRTOS.h"
20#include "task.h"
21#include "main.h"
22#include "cmsis_os.h"
23#include <stdlib.h>
24#include "ethernetif.h"
25#include "lwip/api.h"
26#include "lwip/tcpip.h"
27#include "lwip/ip4_addr.h"
28#include "snmp_core.h"
29#include "usbd_cdc_if.h"
30#include "my_snmp.h"
31#include "Time.h"
32#include "lwip.h"
33#include "AT45DB.h"
34#include "usart.h"
35#include "plc.h"
36#include "ff.h"
37#include "spi.h"
38#include "fatfs.h"
39#include "TFTP.h"
40#include "api.h"
41#include "rng.h"
42#include "log_and_debug.h"
43#include "sntp.h"
44#include "temp.h"
45#include "xml.h"
46
47#define ADDR_VERSION 0x080FFFF8
48#define START_ADDR_OTP_REG_MAC 0x1FFF7800
49#define END_ADDR_OTP_REG_MAC 0x1FFF78FF
50#define START_ADDR_OTP_REG_SN 0x1FFF7900
51#define END_ADDR_OTP_REG_SN 0x1FFF79FF
52
53extern ETH_HandleTypeDef heth;
54extern I2C_HandleTypeDef hi2c1;
55extern UART_HandleTypeDef huart2;
56extern struct eth_addr MACAddr;
57extern plc_common_typeDef plc_common;
58extern RealTimeClock_typeDef RealTimeClock;
59
60network_settings table_network[MAX_IP] = {0};
61
62enum linkState{
63 LINK_DOWN,
64 LINK_UP
65} ETH_linkState = LINK_DOWN;
66
67enum speedState{
68 SPEED_10half = 1,
69 SPEED_100half = 2,
70 SPEED_10full = 5,
71 SPEED_100full = 6
72}ETH_speedState = SPEED_10half;
73
74struct dev {
75 uint8_t num_dev;
76 struct board board[1];
77};
78
79struct {
80 struct dev dev; // [0] - 3v device, [1] - 12v device, [2] - 5v device
81}device_info[3] = {{{0, {{0, "uncknown"}}}}, {{1, {{16, "MC04-PLC"}}}}, {{0, {{0, "uncknown"}}}}};
82
83struct board *curr_device;
84
85char *StringCause[5] = {"Unknown", "Watchdog reset", "Software reset", "Hardware reset", "Pin NRST reset"};
86uint8_t NumCauseReset;
87_Bool ClearPassword = 0;
88BYTE work[_MAX_SS];
89uint32_t FW_Version[2] = {0};
90uint8_t SN[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
91extern FATFS USERFatFS;
92extern FIL USERFile;
93extern char USERPath[4];
94//char list[1024] = {0};
95uint32_t timeTest = 0;
96
97xSemaphoreHandle MutexAccessFlash;
98SemaphoreHandle_t SemaphoreIRQ_PHY, SemaphorePolling;
99
100static void vPLCTask(void *param);
101static void vEthernetTask(void *param);
102extern void vClockTask(void *param);
103static void WebServer_task(void *param);
104void StartDefaultTask(void *argument);
105extern void MX_FATFS_Init(void);
106extern void MX_USB_DEVICE_Init(void);
107void MX_FREERTOS_Init(void);
108void __logWrite(const char * format, ...);
109
110void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
111
112static StaticTask_t xIdleTaskTCBBuffer;
113static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
114
115void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
116{
117 *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
118 *ppxIdleTaskStackBuffer = &xIdleStack[0];
119 *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
120}
121
122void HW_init_DWT(void)
123{
124 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
125 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
126 DWT->CYCCNT = 0;
127}
128
129void MX_FREERTOS_Init(void)
130{
131 wdt_init(2000);
132 MX_USB_DEVICE_Init();
133
134 MutexAccessFlash = xSemaphoreCreateMutex();
135
136 SemaphoreIRQ_PHY = xSemaphoreCreateBinary();
137 SemaphorePolling = xSemaphoreCreateBinary();
138
139 __debug_init();
140 xTaskCreate(StartDefaultTask, "defaultTask", 512, NULL, osPriorityNormal, NULL);
141}
142
143/* ######################################################################################### */
144/* DEFAULT TASK --------------------------------------------------------------------------- */
145void StartDefaultTask(void * argument)
146{
147 wdt_reset();
148 HAL_GPIO_WritePin(PHY_LEDy_GPIO_Port, PHY_LEDy_Pin, GPIO_PIN_SET);
149 uint8_t Flash_ID[4] = {0};
150 FRESULT res;
151
152 /* âû÷èòûâàåì âåðñèþ è ïîäâåðñèþ ïëàòû */
153 FW_Version[1] = (*(__IO uint32_t*) ADDR_VERSION);
154 FW_Version[0] = (*(__IO uint32_t*) (ADDR_VERSION + 4));
155
156 /* âû÷èòûâàåì SN àäðåññ ñ OTP ðåãèñòðà */
157 uint8_t CurrSN[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
158 uint32_t TmpSN, Offset = 0;
159 do{
160 TmpSN = (*(__IO uint32_t*) (START_ADDR_OTP_REG_SN + Offset)); /* ÷èòàåì SN ñ OTP ðåãèñòðà */
161 CurrSN[5] = TmpSN;
162 CurrSN[4] = TmpSN >> 8;
163 CurrSN[3] = TmpSN >> 16;
164 CurrSN[2] = TmpSN >> 24;
165 TmpSN = (*(__IO uint32_t*) (START_ADDR_OTP_REG_SN + (Offset + 4))); /* ÷èòàåì SN ñ OTP ðåãèñòðà */
166 CurrSN[1] = TmpSN;
167 CurrSN[0] = TmpSN >> 8;
168
169 if((CurrSN[0] != 0xFF) && (CurrSN[1] != 0xFF) && (CurrSN[2] != 0xFF) && (CurrSN[3] != 0xFF) && (CurrSN[4] != 0xFF) && (CurrSN[5] != 0xFF)) {
170 memcpy(SN, CurrSN, 6);
171 if(END_ADDR_OTP_REG_SN - (START_ADDR_OTP_REG_SN + Offset) >= 6)Offset += 6;
172 else break;
173 }
174 else break;
175 }while(1);
176
177 osDelay(800);
178 __debug(DEBUG_SERVSE, "\r\n%s\r\nS-port: Firmware v%d.%d, ", StringCause[NumCauseReset], FW_Version[1], FW_Version[0]);
179 if((SN[0] == 0xFF) && (SN[1] == 0xFF) && (SN[2] == 0xFF) && (SN[3] == 0xFF) && (SN[4] == 0xFF) && (SN[5] == 0xFF))__debug(DEBUG_SERVSE, "S-port SN: n/a\r\n");
180 else __debug(DEBUG_SERVSE, "Serial number: %s\r\n", SN);
181 clock_init();
182 osDelay(200);
183
184 MX_SPI3_Init();
185 HAL_GPIO_WritePin(FL_RES_GPIO_Port, FL_RES_Pin, GPIO_PIN_SET);
186 Flash_Read_ID(Flash_ID);
187 __debug(DEBUG_SERVSE, "Flash device: Manufacturer ID: 0x%02X, Device ID: 0x%02X%02X\r\n", Flash_ID[0], Flash_ID[1], Flash_ID[2]);
188
189 MX_FATFS_Init();
190 res = f_mount(&USERFatFS,(TCHAR const*)USERPath, 1);
191 taskENTER_CRITICAL();
192 if(res == FR_NO_FILESYSTEM){
193 __debug(DEBUG_SERVSE,"NO Filesystem\r\n");
194 if(!(ReadStatusFlash() & (1 << 0)))Flash_SetPage512();
195 res = f_mkfs((TCHAR const*)USERPath, FM_ANY, 0, work, sizeof work);
196 __debug(DEBUG_SERVSE,"f_mkfs result - %d\r\n", res);
197 if(res == FR_OK) f_mount(&USERFatFS,(TCHAR const*)USERPath, 1);
198 }
199 if(res == FR_OK) __debug(DEBUG_SERVSE,"Filesystem: OK\r\n");
200 else __debug(DEBUG_SERVSE,"f_mount result - %d\r\n", res);
201
202 taskEXIT_CRITICAL();
203 __logWrite("%s\n", StringCause[NumCauseReset]);
204 __logWrite("Flash device: Manufacturer ID: 0x%02X, Device ID: 0x%02X%02X\n", Flash_ID[0], Flash_ID[1], Flash_ID[2]);
205
206 uint8_t execution = ((~EXECUTION_GPIO_Port->IDR >> 3) & 0x07) >> 1;
207 if(execution < 0x04) {
208 uint8_t type = (~VERSION_GPIO_Port->IDR >> 9) & 0x1F;
209 for(uint8_t i = 0; i < device_info[execution].dev.num_dev; i++){
210 if(type == device_info[execution].dev.board[i].type){
211 curr_device =& device_info[execution].dev.board[i]; // áåðåì óêàçàòåëü íà íàéäåííûé äåâàéñ
212 break;
213 }
214 }
215 }
216 if(curr_device == NULL){
217 __debug(DEBUG_SERVSE,"Uncknown device\r\n");
218 __logWrite("Uncknown device\n");
219 while(1){
220 wdt_reset();
221 osDelay(5000);
222 }
223 }
224 __debug(DEBUG_SERVSE,"S-Port SNMP device: %s\r\n", curr_device->Name);
225 __logWrite("S-Port SNMP device: %s\n", curr_device->Name);
226
227 HW_init_DWT();
228 RNG_init();
229 xTaskCreate(vEthernetTask, "EthTask", 2048, NULL, osPriorityNormal, NULL); // priority: above normal
230
231 temp_sensor_init();
232
233 HAL_GPIO_WritePin(PHY_LEDy_GPIO_Port, PHY_LEDy_Pin, GPIO_PIN_RESET);
234
235 for(;;)
236 {
237 wdt_reset();
238 // vTaskList(list);
239 //HAL_GPIO_TogglePin(PHY_LEDy_GPIO_Port, PHY_LEDy_Pin);
240 osDelay(500);
241 }
242}
243
244/* ######################################################################################### */
245/* ETHERNET TASK --------------------------------------------------------------------------- */
246static void vEthernetTask(void *param)
247{
248 __logWrite("ETH daemon started\n");
249
250 uint32_t PHY_ReadData = 0;
251 char ip[17] = {0}, nm[17] = {0}, gw[17] = {0}, ip_ntp[17] = {0};
252 HAL_GPIO_WritePin(PHY_nRST_GPIO_Port, PHY_nRST_Pin, GPIO_PIN_SET);
253 osDelay(50);
254
255 /*âû÷èòûâàåì MAC àäðåññ ñ OTP ðåãèñòðà*/
256 uint32_t CurrMAC = 0xFFFFFFFF, TmpMAC = 0xFFFFFFFF, offset = 0;
257 do{
258 CurrMAC = (*(__IO uint32_t*) (START_ADDR_OTP_REG_MAC + offset)) & 0x00FFFFFF; // åñëè òóò 000001 - çàïèñàííûé MAC, òî ïðîâåðèòü ñëåäóþùèå òðè áàéòà, åñëè îíè FFFFFF, òî ïåðåäûäóùèé áûë íóæíûé MAC
259 if(END_ADDR_OTP_REG_MAC - (START_ADDR_OTP_REG_MAC + offset) >= 3)offset += 3;
260 else break;
261 TmpMAC = (*(__IO uint32_t*) (START_ADDR_OTP_REG_MAC + offset)) & 0x00FFFFFF;
262 if(TmpMAC == 0x00FFFFFF){ // çíà÷èò ïðåäûäóùèå òðè ÿ÷åéêè ýòî íóæíûé ìàñ
263 MACAddr.addr[3] = CurrMAC >> 16;
264 MACAddr.addr[4] = CurrMAC >> 8;
265 MACAddr.addr[5] = CurrMAC;
266 break;
267 }
268 }while(1);
269
270 __debug(DEBUG_SERVSE, "S-port MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", MACAddr.addr[0], MACAddr.addr[1], MACAddr.addr[2], MACAddr.addr[3], MACAddr.addr[4], MACAddr.addr[5]);
271 if(xml_get_tag("config.xml", "net", NULL, "ip", ip) != XML_OK) memcpy(ip, "192.168.0.254", 13);
272 if(xml_get_tag("config.xml", "net", NULL, "netmask", nm) != XML_OK) memcpy(nm, "255.255.255.0", 13);
273 if(xml_get_tag("config.xml", "net", NULL, "gateway", gw) != XML_OK) memcpy(gw, "192.168.0.1", 11);
274
275 tcpip_init(NULL, NULL);
276 LWIP_SetNetSettings(&table_network[0], ip, nm, gw); // òóò ïðîèñõîäèò çàïèñü â òàáëèöó è â netif
277 MX_LWIP_Init(&table_network[0]); // netif äîáàâëÿåòñÿ â netiflist
278
279 if(curr_device->type == 16){ // åñëè äåâàéñ ó íàñ PLC, òî ïîäíèìàåì åùå 3 èíòåðôåéñà â lwip
280 for(int8_t i = MAX_IP - 1; i > 0; i--) {
281 LWIP_SetNetSettings(&table_network[i], "192.168.0.254", "255.255.255.0", "192.168.0.1");
282 MX_LWIP_Init(&table_network[i]);
283 }
284 }
285
286 if(HAL_GPIO_ReadPin(RES_IP_GPIO_Port, RES_IP_Pin) == GPIO_PIN_RESET){
287 LWIP_resetIP(&table_network[0]); // òîëüêî çàïèñü â netif
288 memcpy(table_network[0].ipv4_addr, ip, strlen(ip));
289 memcpy(table_network[0].ipv4_nm, nm, strlen(nm));
290 memcpy(table_network[0].ipv4_gw, gw, strlen(gw));
291 __debug(DEBUG_SERVSE, "Default IP is set\r\nS-port IP:192.168.0.254, mask:255.255.255.0, gw:192.168.0.1\r\n");
292 __logWrite("Default IP is set\n");
293 ClearPassword = 1; // âûñòàâëÿåì ôëàã, ÷òî î÷èñòêà ïàðîëÿ
294 }
295 else __debug(DEBUG_SERVSE, "S-port IP:%s, mask:%s, gw:%s\r\n", table_network[0].ipv4_addr, table_network[0].ipv4_nm, table_network[0].ipv4_gw);
296
297 mac_init();
298 netif_set_default(&table_network[0].netif);
299
300 /* ñ÷èòàåì link ïðèíóäèòåëüíî */
301 HAL_ETH_ReadPHYRegister(&heth, 0x01, &PHY_ReadData);
302 ETH_linkState = (enum linkState)((PHY_ReadData & (1 << 2)) >> 2);
303 if(ETH_linkState == LINK_UP) netif_set_up(&table_network[0].netif);
304 else netif_set_down(&table_network[0].netif);
305 /* link interrupt enable */
306 HAL_ETH_WritePHYRegister(&heth, 0x1B, 0x500);
307
308 xTaskCreate(WebServer_task, "WebServer", 4096, NULL, osPriorityRealtime + 1, NULL);
309
310 if(xml_get_tag("config.xml", "net", NULL, "ntp", ip_ntp) == XML_OK){
311 ip_addr_t sntp_addr;
312 ip4addr_aton(ip_ntp, &sntp_addr);
313 sntp_setserver(0, &sntp_addr);
314 sntp_init();
315 __debug(DEBUG_SERVSE, "NTP server started: ip:%s\r\n", ip_ntp);
316 }
317 else sntp_setserver(0, NULL);
318
319 tftpServer_init(); // ïîêà ÷òî çàïóñêàåì ïîòîì áóäåì äåëàòü ÷åðåç êîíñîëü
320
321 if(curr_device->type == 16){ // device PLC
322 SnmpPrepare(PLC); // snmp agent start
323 xTaskCreate(vPLCTask, "PLCTask", 2048, NULL, osPriorityNormal, NULL); //priority: high
324 }
325 else {} // äðóãèå äåâàéñû
326
327 for(;;){
328 if(xSemaphoreTake(SemaphoreIRQ_PHY, portMAX_DELAY) == pdPASS){
329 HAL_ETH_ReadPHYRegister(&heth, 0x01, &PHY_ReadData);
330 ETH_linkState = (enum linkState)((PHY_ReadData & (1 << 2)) >> 2);
331 if(ETH_linkState == LINK_UP) {
332 netif_set_up(&table_network[0].netif);
333 __debug(DEBUG_ETH,"ETH LINK UP\r\n");
334 }
335 else {
336 netif_set_down(&table_network[0].netif);
337 __debug(DEBUG_ETH, "ETH LINK DOWN\r\n");
338 }
339 HAL_ETH_ReadPHYRegister(&heth, 0x1E, &PHY_ReadData);
340 ETH_speedState = (enum speedState)(PHY_ReadData & 0x07);
341 if((ETH_speedState == SPEED_10full) || (ETH_speedState == SPEED_10half)) HAL_GPIO_WritePin(PHY_LEDy_GPIO_Port, PHY_LEDy_Pin, GPIO_PIN_SET);
342 else HAL_GPIO_WritePin(PHY_LEDy_GPIO_Port, PHY_LEDy_Pin, GPIO_PIN_RESET);
343
344 HAL_ETH_ReadPHYRegister(&heth, 0x1B, &PHY_ReadData);
345 }
346 vTaskDelay(1);
347 }
348}
349/* ----------------------------------------------------------------------------------------- */
350/* ######################################################################################### */
351/* PLC TIMER POLLING ----------------------------------------------------------------------- */
352xQueueHandle QueueCmdTxPLC, QueueCmdRxPLC;
353extern plc_data_typeDef PLC_Data[AMOUNT_BLOCK_PLC];
354
355void TimerPolling_Callback(void const *argument)
356{
357 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
358 xSemaphoreGiveFromISR(SemaphorePolling, &xHigherPriorityTaskWoken);
359}
360
361#define UDP_RECORD_LIVE_TIME 180; // ñåêóíä = 3 ìèíóòû
362#define UDP_MAX_RECORDS 3 // ìàêñèìóì òðè çàïèñè â òàáëèöå
363
364struct table_records_UDP{
365 unsigned short port; // àäðåñ íà êîòîðûé îòïðàâëÿòü
366 ip_addr_t addr; // ïîðò íà êîòîðûé îòïðàâëÿòü
367 uint32_t time; // âðåìÿ êîãäà çàïèñü ïðîòóõíåò
368 struct {
369 volatile _Bool valid;
370 }flags;
371}table_records_UDP[UDP_MAX_RECORDS] = {0};
372/* ----------------------------------------------------------------------------------------- */
373/* PLC TASK -------------------------------------------------------------------------------- */
374static void vPLCTask(void *param)
375{
376 #define AMOUNT_BOARD_CMD 9
377 #define MAX_ELEMENTS_TX 16
378
379 __debug(DEBUG_SERVSE,"PLC daemon started\r\n");
380 __logWrite("PLC daemon started\n");
381
382 plc_TxData_typeDef PLCTxData = {0};
383 plc_RxData_typeDef PLCRxData = {0};
384 QueueCmdTxPLC = xQueueCreate(MAX_ELEMENTS_TX, sizeof(plc_TxData_typeDef));
385 QueueCmdRxPLC = xQueueCreate(16, sizeof(plc_RxData_typeDef));
386
387 osTimerId TimerPolling;
388 osTimerDef(Timer_Polling, TimerPolling_Callback);
389 TimerPolling = osTimerCreate(osTimer(Timer_Polling), osTimerPeriodic, NULL);
390
391 err_t err;
392 ip_addr_t *addr;
393 volatile _Bool bindUDP = 0, record_find = 0;
394 uint8_t *UDP_PLCData;
395 uint16_t UDP_LenData;
396 uint8_t ID_Unit = 0;
397 unsigned short port;
398 struct netbuf *nbufRX, *nbufTX;
399 struct netconn *connUDP;
400 plc_buff_typeDef buffUDP_send = {0};
401
402 struct {
403 uint8_t shift;
404 uint8_t mask;
405 uint8_t byte;
406 _Bool isID : 1;
407 _Bool end : 1;
408 _Bool add : 1;
409 _Bool nextID : 1;
410 _Bool noCopy : 1;
411 }UDP_flag;
412
413 volatile uint16_t sBuffCnt = 0;
414 char sBuffer[2048] = {0};
415 char ip[16] = {0}, nm[16] = {0}, gw[16] = {0}, str_xml[25] = {0};
416 uint8_t cntByte = 0;
417 plc_data_typeDef *PointPLCData =& PLC_Data[0];
418 uint32_t TimerCounter = 0;
419 uint8_t board = 0;
420 const uint8_t Kosh_sigMass[10] = {10, 13, 16, 20, 25, 32, 40, 50, 63, 79}; // 10^0.0, 10^0.1 è òä. óìíîæåííîå íà 10
421
422 struct {
423 _Bool all_en;
424 const uint16_t BoardCmd[AMOUNT_BOARD_CMD]; // â ñòàðøåì áàéòå àäðåñ ïëàòû, ìëàäøèé áàéò êîìàíäà
425 uint8_t CurrentIndexBlock;
426 uint8_t CurrentIndexUM;
427 struct {
428 _Bool En;
429 uint8_t PointBoardCmd; // ïî êîëë-âó áëîêîâ(ó êàæäîãî áëîêà ñâîé óêàçàòåëü íà êîìàíäó êîòîðóþ ïåðåäàåì)
430 uint32_t NewTime;
431 uint8_t Timeout;
432 uint8_t RequestCnt; // ñ÷åò÷èê çàïðîñîâ, êîãäà áëîê îòâå÷àåò, òî åãî ñáðàñûâàåì
433 uint8_t Alarm;
434 _Bool Presece;
435 _Bool FirstRequest;
436 struct {
437 _Bool Presence;
438 uint8_t RequestCnt; // ñ÷åò÷èê äëÿ ïåðåçàïðîñà îòñòóòñâóþùåé ïëàòû ÓÌ
439 }UM[2];
440 }Block[AMOUNT_BLOCK_PLC];
441 }Common = {0, {0x0401, 0x0411, 0x0412, 0x0413, 0x0415, 0x0416, 0x0417, 0x0A01, 0x0C01}, 0x00, 0xFF,
442 {{0, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 1, {{1, 0x00},{1, 0x00}}},
443 {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 1, {{1, 0x00},{1, 0x00}}},
444 {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 1, {{1, 0x00},{1, 0x00}}},
445 {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 1, {{1, 0x00},{1, 0x00}}}}};
446
447 sprintf(PLC_Data[0].NameBlock, "");
448 sprintf(PLC_Data[1].NameBlock, "");
449 sprintf(PLC_Data[2].NameBlock, "");
450 sprintf(PLC_Data[3].NameBlock, "");
451 if(xml_get_attr("config.xml", "blocks", NULL, "num", str_xml) == XML_OK) plc_common.num = atoi(str_xml);
452 else plc_common.num = 1;
453
454 PLC_Data[1].PollingTimeout = 5;
455 PLC_Data[2].PollingTimeout = 5;
456 PLC_Data[3].PollingTimeout = 5;
457
458 for(uint8_t i = 0; i < plc_common.num; i++){
459 PLC_Data[i].EnablePoll = 1;
460 sprintf(sBuffer, (const char*)"id=\"%d\"", i);
461 if(xml_get_attr("config.xml", "block", sBuffer, "name", str_xml) == XML_OK) memcpy(PLC_Data[i].NameBlock, str_xml, strlen(str_xml));
462 else sprintf(PLC_Data[i].NameBlock, "");
463 if(xml_get_tag("config.xml", "block", sBuffer, "poll", str_xml) == XML_OK)PLC_Data[i].PollingTimeout = atoi(str_xml);
464 else PLC_Data[i].PollingTimeout = (i == 0) ? 3 : 5;
465 if(xml_get_tag("config.xml", "block", sBuffer, "filter", str_xml) == XML_OK){
466 PLC_Data[i].Type_Filter = (TypeFilter_typeDef)atoi(&str_xml[0]);
467 PLC_Data[i].FilterATT = (FilterATT_typeDef)atoi(&str_xml[2]);
468 }
469 if(i > 0){
470 if(xml_get_tag("config.xml", "block", sBuffer, "route", str_xml) == XML_OK) for(uint8_t q = 0; q < sizeof(PLC_Data[i].Route); q++)PLC_Data[i].Route[q] = atoi(&str_xml[q * 2]);
471 else for(uint8_t q = 0; q < sizeof(PLC_Data[i].Route); q++)PLC_Data[i].Route[q] = 0x00;
472 if(xml_get_tag("config.xml", "block", sBuffer, "ip", ip) != XML_OK) sprintf(ip, "");
473 if(xml_get_tag("config.xml", "block", sBuffer, "netmask", nm) != XML_OK) sprintf(nm, "");
474 if(xml_get_tag("config.xml", "block", sBuffer, "gateway", gw) != XML_OK) sprintf(gw, "");
475 LWIP_SetNetSettings(&table_network[i], ip, nm, gw);
476 netif_set_up(&table_network[i].netif);
477 }
478 }
479 MX_USART2_UART_Init();
480
481 connUDP = netconn_new(NETCONN_UDP);
482 if (connUDP!= NULL){
483 err = netconn_bind(connUDP, IP_ADDR_ANY, 12348);
484 if (err == ERR_OK) {
485 bindUDP = 1;
486 netconn_set_recvtimeout(connUDP, 10);
487 }
488 else netconn_delete(connUDP);
489 }
490
491 osTimerStart(TimerPolling, 1000); // êàæäóþ ñåêóíäó ñðàáàòûâàåò òàéìåð
492
493 for(;;){
494 if((!Common.all_en) && (plc_common.enable_all_pool)){
495 __debug(DEBUG_SERVSE, "Block polling disabled\r\n");
496 osTimerStop(TimerPolling);
497 xQueueReset(QueueCmdTxPLC);
498 Common.all_en = 1;
499 }
500 else if((Common.all_en) && (!plc_common.enable_all_pool)){
501 __debug(DEBUG_SERVSE, "Block polling enabled\r\n");
502 osTimerStart(TimerPolling, 1000);
503 Common.all_en = 0;
504 }
505
506 for(uint8_t i = 0; i < UDP_MAX_RECORDS; i++){/*ñìîòðèì ïðîòóõëà ëè òàáëèöà*/
507 if(table_records_UDP[i].flags.valid){
508 if(TimerCounter >= table_records_UDP[i].time) table_records_UDP[i].flags.valid = 0; // çàïèñü ïðîòóõëà
509 }
510 }
511
512 if(bindUDP) { // åñëè UDP ñåðâåð çàáèíäèëñÿ
513 err = netconn_recv(connUDP, &nbufRX);
514 if (err == ERR_OK){ // ïðèøëè äàííûå ñ UDP ïîðòà
515 addr = netbuf_fromaddr(nbufRX);
516 port = netbuf_fromport(nbufRX);
517
518 for(uint8_t i = 0; i < UDP_MAX_RECORDS; i++){ //èùåì çàïèñü
519 if(table_records_UDP[i].flags.valid){
520 if((table_records_UDP[i].addr.addr == addr->addr) && (table_records_UDP[i].port == port)) {
521 table_records_UDP[i].time = TimerCounter + UDP_RECORD_LIVE_TIME;
522 record_find = 1;
523 break;
524 }
525 }
526 }
527 if(!record_find){ // åñëè òàêîé çàïèñè íåò, òî äîáàâëÿåì åå
528 for(uint8_t i = 0; i < UDP_MAX_RECORDS; i++){
529 if(!table_records_UDP[i].flags.valid){ // èùåì ñâîáîäíîå ìåñòî ïîä çàïèñü
530 table_records_UDP[i].addr.addr = addr->addr;
531 table_records_UDP[i].port = port;
532 table_records_UDP[i].flags.valid = 1; // çàíèìàåì çàïèñü
533 table_records_UDP[i].time = TimerCounter + UDP_RECORD_LIVE_TIME;
534 break;
535 }
536 }
537 }
538 else record_find = 0;
539
540 netbuf_data(nbufRX, (void**)&UDP_PLCData, &UDP_LenData);
541 PLCTxData.LenBuff = 0;
542 PLCTxData.Pointer = 0x01; // óâåëè÷èâàåì óêàçàòåëü
543 PLCTxData.Buff[PLCTxData.LenBuff++] = (PLC_ADDR_BOARD << 4) & 0xF0; // ïèøåì ñâîé àäðåñ
544 UDP_LenData--; // âû÷èòàåì ïåðâûé áàéò, ýòî óêàçàòåëü äëÿ íàñ îí áåçïîëåçåí
545 if(UDP_PLCData[1] == 0x0F){// ýòî øèðîêîâåùàòåëüíîå ñîîáùåíèå äëÿ áëèæíåãî áëîêà ôîðìèðóåì 0x0E 0xF0 0x00
546 PLCTxData.Buff[PLCTxData.LenBuff++] = 0xF0;
547 PLCTxData.Buff[PLCTxData.LenBuff++] = 0x00;
548 }
549 else {
550 if(((UDP_PLCData[1] & 0x0F) > 1) && ((UDP_PLCData[1] & 0x0F) < 0x0F)) { // òóò âñåãäà áóäåò ID áëîêà
551 ID_Unit = UDP_PLCData[1] & 0x0F;// çàïîìèíèåì íàø ID äëÿ îòâåòà
552 if((UDP_PLCData[1] & 0xF0) == 0x00){
553 PLCTxData.Buff[PLCTxData.LenBuff++] = (ID_Unit << 4);
554 PLCTxData.Buff[PLCTxData.LenBuff++] = 0x00;
555 if(UDP_LenData > 0x02) {
556 UDP_LenData--;
557 memcpy(&PLCTxData.Buff[PLCTxData.LenBuff], &UDP_PLCData[2], UDP_LenData - 1);
558 PLCTxData.LenBuff += (UDP_LenData - 1);
559 }
560 }
561 else if(((UDP_PLCData[1] & 0xF0) >> 4) >= 4){ // òóò ìîæåò áûòü è ïëàòà è êàíàë
562 PLCTxData.Buff[PLCTxData.LenBuff++] = ((UDP_PLCData[1] & 0xF0) >> 4); // ýòî ïëàòà áëèæíåãî áëîêà
563 UDP_LenData--; // âû÷èòàåì âòîðîé áàéò òàê êàê ìû åãî ðàçâåðíóëè
564 memcpy(&PLCTxData.Buff[PLCTxData.LenBuff], &UDP_PLCData[PLCTxData.LenBuff], UDP_LenData - 1); //êîïèðóåì íà îäèí áàéò ìåíüøå òàê êàê òàì êîíòðîëüíàÿ ñóììà
565 PLCTxData.LenBuff += (UDP_LenData - 1);
566 }
567 else { // ýòî êàíàë
568 UDP_flag.add = 0;
569 UDP_flag.end = 0;
570 UDP_flag.isID = 0;
571 UDP_flag.nextID = 0;
572 for(uint8_t ptr = 1;; ptr++){
573 UDP_flag.mask = 0x0F; UDP_flag.shift = 0;
574 for(uint8_t i = 0; i < 2; i++){ // òàê êàê äâå òåòðàäû â áàéòå
575 if((ptr != 0x01) || ((ptr == 0x01) && (i != 0x00))) UDP_flag.byte = (UDP_PLCData[ptr] & UDP_flag.mask) >> UDP_flag.shift; // ïðîïóñêàåì ìëàäùóþ òåòðàäó ïåðâîãî ïðîñìàòðèâàåìîãî áàéòà
576 else { UDP_flag.mask = 0xF0; UDP_flag.shift = 4; continue; }
577
578 if(ptr != 0x01){
579 if(UDP_flag.byte == 0x00) {
580 UDP_flag.nextID = 1; // ñîîáùàåì ÷òî ñëåäóþùàÿ òåòðàäà ýòî ID
581 if(UDP_flag.isID) UDP_flag.end = 1; // çíà÷èò êîíåö
582 }
583 else if(UDP_flag.byte >= 0x04) {
584 if(UDP_flag.nextID){ // ýòî ID
585 if(UDP_flag.byte == 0x0F){
586 if(UDP_flag.shift == 0x00) UDP_flag.add = 1;
587 UDP_flag.noCopy = 1;
588 UDP_flag.end = 1;
589 }
590 else UDP_flag.isID = 1;
591 UDP_flag.nextID = 0;
592 }
593 else UDP_flag.end = 1;
594 }
595 else UDP_flag.isID = 0;// êàíàë
596 }
597
598 if(i == 0x00) PLCTxData.Buff[PLCTxData.LenBuff++] |= UDP_flag.byte << 4;
599 else PLCTxData.Buff[PLCTxData.LenBuff] = UDP_flag.byte;
600 if(UDP_flag.end) {
601 if(i == 0x01)PLCTxData.LenBuff++;
602 break;
603 }
604 UDP_flag.mask = 0xF0; UDP_flag.shift = 4;
605 }
606 if(UDP_flag.end){
607 if(UDP_flag.add) PLCTxData.Buff[PLCTxData.LenBuff++] = 0x00;
608 if(!UDP_flag.noCopy){
609 memcpy(&PLCTxData.Buff[PLCTxData.LenBuff], &UDP_PLCData[ptr + 1], UDP_LenData - ptr - 1);
610 PLCTxData.LenBuff += (UDP_LenData - ptr - 1);
611 }
612 else UDP_flag.noCopy = 0;
613 break;
614 }
615 }
616 }
617 }
618 }
619 if(__debug(DEBUG_PLC_TRANSIT,"********* UDP RX *********\r\n")){
620 sBuffCnt = 0;
621 sBuffCnt += sprintf(&sBuffer[sBuffCnt], "pointer:%02X\r\ndata [%d]:", PLCTxData.Pointer, PLCTxData.LenBuff);
622 for(uint16_t i = 0; i < PLCTxData.LenBuff; i++)sBuffCnt += sprintf(&sBuffer[sBuffCnt], "%02X", PLCTxData.Buff[i]);
623 __debug(DEBUG_PLC_TRANSIT,"%s\r\n***************************************\r\n", sBuffer);
624 }
625 xQueueSend(QueueCmdTxPLC, &PLCTxData, portMAX_DELAY);
626 netbuf_delete(nbufRX);
627 }
628 }
629/******************************** ÐÅÆÈÌ ÐÀÁÎÒÛ "ÎÏÐÎÑ ÁËÎÊÎÂ" ******************************/
630 if(plc_common.change_block > 0){
631 uint8_t up = 0;
632 up = plc_common.num - plc_common.change_block;
633 if(up != 0) {
634 for(uint8_t i = 0; i < up; i++){
635 memcpy(&Common.Block[plc_common.change_block], &Common.Block[plc_common.change_block + 1], sizeof(Common.Block[plc_common.change_block + 1]));
636 plc_common.change_block++;
637 }
638 }
639 plc_common.change_block = 0;
640 }
641 if(xQueueReceive(QueueCmdRxPLC, &PLCRxData, 0) == pdTRUE){ // ïîëó÷àåì äàííûå âñåãäà
642 if(PLCRxData.Valid){ // äàííûå âàëèäíûå è ãîòîâû ê äàëüíåéøåé îáðàáîòêå
643 if(PLCRxData.Query) __debug(DEBUG_PLC_CROSS,"Request me\r\n");
644 if(__debug(DEBUG_PLC_CROSS | DEBUG_PLC_TRANSIT,"********* RX CROSS *********\r\n")){ // âûâîäèì äåáàã
645 sBuffCnt = 0;
646 sBuffCnt += sprintf(&sBuffer[sBuffCnt], "pointer:%02X\r\ndata [%d]:", PLCRxData.Pointer, PLCRxData.LenBuff);
647 for(uint16_t i = 0; i < PLCRxData.LenBuff; i++)sBuffCnt += sprintf(&sBuffer[sBuffCnt], "%02X", PLCRxData.Buff[i]);
648 __debug(DEBUG_PLC_CROSS | DEBUG_PLC_TRANSIT,"%s\r\n***************************************\r\n", sBuffer);
649 }
650 Common.CurrentIndexBlock = 0;
651 if((PLCRxData.Pointer & 0x80) && (PLCRxData.Pointer & 0x01)){ // îòâåò íà çàïðîñ (óêàçàòåëü äîëæåí áûòü 1)
652 if((PLCRxData.Buff[0] & 0xF0) == (PLC_ADDR_BOARD << 4)){// êîìàíäà äëÿ ìåíÿ
653 /*************************** PLC->UDP *************************/
654 volatile uint8_t offset;
655 uint16_t tmpLenBuff = PLCRxData.LenBuff;
656 uint8_t pointer = 1;
657 buffUDP_send.len = 0;
658 buffUDP_send.data[buffUDP_send.len++] = PLCRxData.Pointer & 0x80;
659 tmpLenBuff--; //âû÷èòàåì ïåðâûé áàéò òàê êàê â íåì íàøà ïëàòà
660 if((PLCRxData.Buff[1] & 0x0F) == 0x00) { // îòâåò ID áëîêà áëèæíåãî
661 buffUDP_send.data[buffUDP_send.len++] = ((PLCRxData.Buff[pointer] & 0xF0) >> 4) | ((PLCRxData.Buff[pointer] & 0x0F) << 4); // ðâçâåðíóë äàííûå òàê êàê îòâåò ID áëîêà
662 tmpLenBuff -= 2;
663 pointer += 2;
664 }
665 else if((PLCRxData.Buff[1] & 0x0F) >= 0x04){ // òóò ìîæåò áûòü è ïëàòà è êàíàë
666 buffUDP_send.data[buffUDP_send.len++] = ((PLCRxData.Buff[pointer++] & 0x0F) << 4) | ID_Unit;// ýòî áëèæíÿÿ ïëàòà
667 tmpLenBuff--;
668 }
669 else { // ýòî êàíàë
670 UDP_flag.add = 0;
671 UDP_flag.end = 0;
672 UDP_flag.isID = 0;
673 UDP_flag.nextID = 0;
674 for(uint8_t ptr = 1;; ptr++){
675 UDP_flag.mask = 0x0F; UDP_flag.shift = 0;
676
677 for(uint8_t i = 0; i < 2; i++){
678 UDP_flag.byte = (PLCRxData.Buff[ptr] & UDP_flag.mask) >> UDP_flag.shift;
679 if((ptr == 1) && (i == 0)) buffUDP_send.data[buffUDP_send.len] = ID_Unit;
680
681 if(UDP_flag.byte == 0x00) {
682 if(UDP_flag.nextID) UDP_flag.end = 1;
683 if(UDP_flag.isID){
684 if(UDP_flag.shift == 0x04) UDP_flag.add = 1;
685 UDP_flag.end = 1;
686 }
687 else UDP_flag.nextID = 1; // ñîîáùàåì ÷òî ñëåäóþùàÿ òåòðàäà ýòî ID
688 }
689 else if(UDP_flag.byte >= 0x04) {
690 if(UDP_flag.nextID){
691 UDP_flag.isID = 1;
692 UDP_flag.nextID = 0;
693 }
694 else UDP_flag.end = 1;
695 }
696 else UDP_flag.isID = 0;// êàíàë
697
698 if(i == 0x00) buffUDP_send.data[buffUDP_send.len++] |= UDP_flag.byte << 4;
699 else buffUDP_send.data[buffUDP_send.len] = UDP_flag.byte;
700
701 if(UDP_flag.end) {
702 if((i == 0x01) && (!UDP_flag.add)) buffUDP_send.len++;
703 break;
704 }
705 UDP_flag.mask = 0xF0; UDP_flag.shift = 4;
706 }
707 if(UDP_flag.end){
708 if(UDP_flag.add) buffUDP_send.data[buffUDP_send.len++] = 0x00;
709 pointer += ptr;
710 tmpLenBuff -= ptr;
711 break;
712 }
713 }
714 }
715
716 memcpy(&buffUDP_send.data[buffUDP_send.len], &PLCRxData.Buff[pointer], tmpLenBuff);
717 buffUDP_send.len += tmpLenBuff;
718 buffUDP_send.data[buffUDP_send.len++] = ~((uint8_t)plc_calc_cs(buffUDP_send.data, buffUDP_send.len));// äàííûå â UDP
719
720 for(uint8_t i = 0; i < UDP_MAX_RECORDS; i++){
721 if(table_records_UDP[i].flags.valid){ // åñòü âàëèäíàÿ çàïèñü, òî îòïðàâëÿåì
722 netconn_connect(connUDP, &table_records_UDP[i].addr, table_records_UDP[i].port);
723 nbufTX = netbuf_new();
724 if(nbufTX != NULL){
725 netbuf_alloc(nbufTX, buffUDP_send.len);
726 pbuf_take(nbufTX->p, (void *) &buffUDP_send.data, buffUDP_send.len);
727 netconn_send(connUDP, nbufTX);
728 netbuf_free(nbufTX);
729 netbuf_delete(nbufTX);
730 netconn_disconnect(connUDP);
731 }
732 }
733 }
734 /*****************************************************/
735 /*********** îáðàáîòêà ìîèõ ïàêåòîâ èç PLC ***********/
736 PointPLCData = NULL;
737 PLCRxData.LenBuff -= 1; // âû÷òåì ïåðâûé áàéò, òàê êàê òàì ëåæèò 0xE0
738 if((PLCRxData.Buff[1] & 0x0F) >= 0x04) {// çíà÷èò ýòî ïëàòà è ýòî áëèæíèé áëîê
739 board = PLCRxData.Buff[1] & 0x0F;
740 PLCRxData.LenBuff -= 1; // âû÷èòàåì áàéò ïëàòû
741 offset = 2;
742 PointPLCData =& PLC_Data[0]; // áåðåì óêàçàòåëü áëèæíåãî áëîêà
743 }
744 else{ // ýòî ïðè ïðèõîäèò îò äàëüíåãî áëîêà
745 for(Common.CurrentIndexBlock = 1; /*(offset <= cntByte) || */(Common.CurrentIndexBlock < AMOUNT_BLOCK_PLC); ){
746 if(PLC_Data[Common.CurrentIndexBlock].Route[0] > 0){
747 cntByte = (PLC_Data[Common.CurrentIndexBlock].Route[0] + 1) / 2; // âû÷èñëÿåì ñêîëüêî áàéò
748 if((PLC_Data[Common.CurrentIndexBlock].Route[0] % 2) == 0){ // åñëè ÷åòíîå êîëëâî íèáëîâ
749 board = (PLCRxData.Buff[cntByte + 1] & 0x0F);
750 if(board < 4){ Common.CurrentIndexBlock++; continue;}
751 if(memcmp(&PLCRxData.Buff[1], &PLC_Data[Common.CurrentIndexBlock].Route[1], cntByte) == 0x00){
752 PLCRxData.LenBuff = PLCRxData.LenBuff - cntByte - 1;
753 offset = cntByte + 2;
754 PointPLCData =& PLC_Data[Common.CurrentIndexBlock];
755 break;
756 }
757 Common.CurrentIndexBlock++;
758 }
759 else { // åñëè êîëëâî íèáëîâ íå÷åòíîå
760 board = (PLCRxData.Buff[cntByte] & 0xF0) >> 4;
761 if(board < 4){ Common.CurrentIndexBlock++; continue;}
762 uint8_t tmp = PLCRxData.Buff[cntByte];
763 PLCRxData.Buff[cntByte] &= 0x0F; // òóò íå íàäî óáèðàòü àäðåññ ïëàòû
764 if(memcmp(&PLCRxData.Buff[1], &PLC_Data[Common.CurrentIndexBlock].Route[1], cntByte) == 0x00){
765 PLCRxData.LenBuff -= cntByte;
766 offset = cntByte + 1;
767 PointPLCData =& PLC_Data[Common.CurrentIndexBlock];
768 break;
769 }
770 PLCRxData.Buff[cntByte] = tmp;
771 Common.CurrentIndexBlock++;
772 }
773 }
774 else Common.CurrentIndexBlock++;
775 }
776 }
777 // åñòü óêàçàòåëü, òî çíà÷èò ìîæíî îáðàáàòûâàòü îòâåò
778 if(PointPLCData != NULL) {
779 memmove(&PLCRxData.Buff[0], &PLCRxData.Buff[offset], PLCRxData.LenBuff);
780 if(board == 0x04){ // îòâåò îò MD
781 uint8_t ch;
782 Common.Block[Common.CurrentIndexBlock].Presece = 1;// âûñòàâëÿåì ôëàã ÷òî áëîê îòâåòèë
783 Common.Block[Common.CurrentIndexBlock].RequestCnt = 0; // ñáðàñûâàåì ñ÷åò÷èê çàïðîñîâ
784 if(PLCRxData.Buff[0] == 0x01) {
785 sprintf(PointPLCData->Version, "%d", PLCRxData.Buff[1]);
786 PointPLCData->VersionMD = atoi(PointPLCData->Version);
787 Common.Block[Common.CurrentIndexBlock].FirstRequest = 0;
788 }
789 else if((PLCRxData.Buff[0] == 0x11) || (PLCRxData.Buff[0] == 0x12) || (PLCRxData.Buff[0] == 0x13)){
790 ch = (PLCRxData.Buff[0] & (0x0F)) - 1;
791 PointPLCData->HF_Channel[ch].En = (PLCRxData.Buff[2] & 0x80);
792 if(PointPLCData->HF_Channel[ch].En){
793 PointPLCData->HF_Channel[ch].Frequency_Transmitter = PLCRxData.Buff[1] | ((PLCRxData.Buff[2] & 0x03) << 8);
794 PointPLCData->HF_Channel[ch].Frequency_Receiver = PLCRxData.Buff[3] | ((PLCRxData.Buff[4] & 0x03) << 8);
795 PointPLCData->HF_Channel[ch].Mode = (ModeChannel_typeDef)((PLCRxData.Buff[5] & 0xC0) >> 6);
796 }
797 }
798 else if((PLCRxData.Buff[0] == 0x15) || (PLCRxData.Buff[0] == 0x16) || (PLCRxData.Buff[0] == 0x17)){
799 ch = (PLCRxData.Buff[0] & (0x0F)) - 5;
800 if(PointPLCData->HF_Channel[ch].En){
801 if(PLCRxData.Buff[1] & 0xE0){
802 if((PLCRxData.Buff[1] & 0x60) == 0x60) PointPLCData->HF_Channel[ch].Status_Receiver = RECEIVING;
803 else if(PLCRxData.Buff[1] & 0x40) PointPLCData->HF_Channel[ch].Status_Receiver = ACTIVATION;
804 else if(PLCRxData.Buff[1] & 0x80)PointPLCData->HF_Channel[ch].Status_Receiver = OVERLOAD;
805 }
806 else PointPLCData->HF_Channel[ch].Status_Receiver = NO_SIGNAL;
807
808 if(PLCRxData.LenBuff >= 9) { // åñëè öèôðîâîé ðåæèì ðàáîòû
809 if(PLCRxData.Buff[3] > 128)PointPLCData->HF_Channel[ch].Rate_Transmitter = ((PLCRxData.Buff[3] - 128) * 2) + 128; // rate 12.7kB/s -> 127 // *0.2
810 else PointPLCData->HF_Channel[ch].Rate_Transmitter = PLCRxData.Buff[3] * 1; // *0.1 // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10
811 if(PLCRxData.Buff[4] > 128)PointPLCData->HF_Channel[ch].Rate_Receiver = ((PLCRxData.Buff[4] - 128) * 2) + 128; // rate 12.7kB/s -> 127 // *0.2
812 else PointPLCData->HF_Channel[ch].Rate_Receiver = PLCRxData.Buff[4] * 1; // *0.1 // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10
813 PointPLCData->HF_Channel[ch].QualityNoise_Receiver = PLCRxData.Buff[5] * 10 / 8; // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10
814 if(PointPLCData->HF_Channel[ch].QualityNoise_Receiver > 0)PointPLCData->HF_Channel[ch].SNR_Receiver = PointPLCData->HF_Channel[ch].Rate_Receiver + PointPLCData->HF_Channel[ch].QualityNoise_Receiver - 20; // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10
815 else PointPLCData->HF_Channel[ch].SNR_Receiver = 0;
816
817 PointPLCData->HF_Channel[ch].CounterError = (PLCRxData.Buff[7] << 8) | PLCRxData.Buff[6];
818
819 PLCRxData.Buff[8] &= ~(1 << 7); // êÎø îáíóëÿåì 7 áèò, òàê êàê îí íåäåéñòâèòåëüíûé
820 PointPLCData->HF_Channel[ch].Kosh_raw = PLCRxData.Buff[8];
821 uint8_t k = (PLCRxData.Buff[8] / 10) + 1; // ýòî áóäåò ñòåïåíü, áåç ìèíóñà
822 uint8_t i = 10 - (PLCRxData.Buff[8] % 10); // (0,2) 2 ->10-2=8 -> íàäî ïîëó÷èòü 10^0.8
823 if(i == 10){ i = 0; k -= 1; }
824 uint8_t tmp = Kosh_sigMass[i] * 3;
825 if((tmp / 100) != 0){ tmp /= 10; k -= 1; }
826 PointPLCData->HF_Channel[ch].Kosh_sig = tmp;// * 3; // óìíîæàåì íà 3 òàê êàê îøèáêè íå áèòîâûå à ñèìâîëüíûå, ïðèìåðíî îäà ñèìâîëüíàÿ îøèáêà ýòî 3 áèòîâûõ
827 PointPLCData->HF_Channel[ch].Kosh_exp = k * (-1);
828 }
829 else {
830 PointPLCData->HF_Channel[ch].QualityNoise_Receiver = 0;
831 PointPLCData->HF_Channel[ch].Rate_Transmitter = 0;
832 PointPLCData->HF_Channel[ch].Rate_Receiver = 0;
833 PointPLCData->HF_Channel[ch].SNR_Receiver = 0;
834 PointPLCData->HF_Channel[ch].Kosh_sig = 0;
835 PointPLCData->HF_Channel[ch].Kosh_exp = 0;
836 }
837 PointPLCData->HF_Channel[ch].Level_InputSignal = PLCRxData.Buff[2] * (-2); // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10 îòðèöàòåëüíîå ÷èñëî
838
839 if(PointPLCData->Power_PRD != P_NONE){
840 float tmp = (PLCRxData.Buff[2] * -0.2) + (0.007 * PointPLCData->HF_Channel[ch].Frequency_Receiver) + 9 + (2 * (PointPLCData->Power_PRD - 1)) + (2 * PointPLCData->Type_Filter) + (PointPLCData->FilterATT * 6);
841 PointPLCData->HF_Channel[ch].Level_Receiver = (int16_t)(tmp * 10); // ïåðåäàåì ÷èñëî óìíîæåííîå íà 10 îòðèöàòåëüíîå ÷èñëî
842 }
843 else PointPLCData->HF_Channel[ch].Level_Receiver = 0;
844 if(PointPLCData->HF_Channel[ch].Status_Receiver != RECEIVING) Common.Block[Common.CurrentIndexBlock].Alarm |= (1 << ch);
845 else Common.Block[Common.CurrentIndexBlock].Alarm &= ~(1 << ch);
846 }
847 else Common.Block[Common.CurrentIndexBlock].Alarm &= ~(1 << ch);
848 }
849 }// end îòâåò îò MD
850 else { // îòâåò îò ëþáîé ïëàòû
851 Common.CurrentIndexUM = 0xFF;
852 if(board == 0x0A) Common.CurrentIndexUM = 0;// îòâåò îò UM02 ïåðâàÿ ïëàòà
853 else if(board == 0X0C) Common.CurrentIndexUM = 1;// îòâåò îò UM02 âòîðàÿ ïëàòà
854
855 if(Common.CurrentIndexUM != 0xFF){
856 if(PLCRxData.Buff[0] == 0x01){
857 PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Version = PLCRxData.Buff[1];
858 if(PLCRxData.Buff[2] & 0x1E){
859 if(PLCRxData.Buff[2] & 0x02) PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Alarm = LINE_BREAK;
860 else if(PLCRxData.Buff[2] & 0x04) PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Alarm = FAILURE_PRD;
861 else if(PLCRxData.Buff[2] & 0x08) PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Alarm = NO_SIGNAL_PWR_AMP;
862 else if(PLCRxData.Buff[2] & 0x16) PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Alarm = HIGH_TEMPERATURE;
863 Common.Block[Common.CurrentIndexBlock].Alarm |= (1 << (Common.CurrentIndexUM + 4));
864 }
865 else {
866 PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Alarm = NO_ALARM;
867 Common.Block[Common.CurrentIndexBlock].Alarm &= ~(1 << (Common.CurrentIndexUM + 4));
868 }
869 PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Level_Transmitter = PLCRxData.Buff[3];
870 PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Temp = PLCRxData.Buff[4];
871 if(PLCRxData.LenBuff == 7)PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Voltage = PLCRxData.Buff[6];
872 else PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Voltage = 0x00;
873 PointPLCData->PowerAmplifier[Common.CurrentIndexUM].Presence = 1;
874 Common.Block[Common.CurrentIndexBlock].UM[Common.CurrentIndexUM].Presence = 1; // âûñòàâëÿåì ôëàã ÷òî UM îòâåòèë
875 Common.Block[Common.CurrentIndexBlock].UM[Common.CurrentIndexUM].RequestCnt = 0;
876 }
877 }
878 if((PointPLCData->PowerAmplifier[0].Presence) && (PointPLCData->PowerAmplifier[1].Presence)) PointPLCData->Power_PRD = P_40W;
879 else if((PointPLCData->PowerAmplifier[0].Presence) || (PointPLCData->PowerAmplifier[1].Presence)) PointPLCData->Power_PRD = P_20W;
880 else PointPLCData->Power_PRD = P_NONE;
881 }
882 }
883 } // end cmd äëÿ ìåíÿ
884 }
885 else if(PLCRxData.Query){ // áûë çàïðîñ äàííûõ ó íàñ(åñëè íóæíî)
886 __debug(DEBUG_SERVSE, "my pack\r\n");
887 my_cmd_plc(&PLCRxData, &PLCTxData);
888 }
889 }
890 }
891 /* êîììîí àëàðì îáíîâëÿåì âñåãäà*/
892 for(uint8_t i = 0; i < AMOUNT_BLOCK_PLC; i++){
893 if(PLC_Data[i].EnablePoll){
894 if(PLC_Data[i].ChangeSettings){ // åñëè áûëî èçìåíåíèå íàñòðîåê ìàðøðóòà, ãîâîðèì ÷òî áëîê îòñóòñòâóåò
895 Common.Block[i].Presece = 0;
896 Common.Block[i].FirstRequest = 1; // ñêèäûâàåì äëÿ îòïðàâêè òîëüêî ïåðâîé êîìàíäû
897 Common.Block[i].RequestCnt = 0;
898 PLC_Data[i].ChangeSettings = 0;
899 }
900 if(Common.Block[i].Presece){
901 if(Common.Block[i].Alarm) PLC_Data[i].CommonAlarm = 2;
902 else PLC_Data[i].CommonAlarm = 0;
903 }
904 else {
905 PLC_Data[i].CommonAlarm = 1;// áëîê îòñóòñòâóåò
906 PLC_Data[i].VersionMD = 0;
907 for(uint8_t q = 0; q < 3; q++)PLC_Data[i].HF_Channel[q].En = 0; // ôèêñèðóåì ÷òî êàíàë âûêëþ÷åí
908 for(uint8_t q = 0; q < 2; q++)PLC_Data[i].PowerAmplifier[q].Presence = 0; // ôèêñèðóåì ÷òî ÓÌ îòñóòñòâóåò
909 }
910 }
911 }
912
913/************************ Ôîðìèðîâàíèå êîìàíä è îòïðàâêà â áëîêè *******************************/
914 if(xSemaphoreTake(SemaphorePolling, 0) == pdTRUE){ // ñåìàôîð äëÿ ïîäãîòîâêè äàííûõ äëÿ îòïðàâêè
915 uint8_t indexPoll = 0;
916 for(uint8_t i = 0; i < AMOUNT_BLOCK_PLC; i++){ // ïðîõîäèì ïî âñå 4 áëîêàì
917 if((Common.Block[i].NewTime == TimerCounter) || ((Common.Block[i].En != PLC_Data[i].EnablePoll) && (PLC_Data[i].EnablePoll))){ // ïðèøëî âðåìÿ îïðîñà èëè åñëè äîáàâèëè áëîê äëÿ îïðîñà
918 if(PLC_Data[i].EnablePoll) {// ó âñåõ áëîêîâ ñìîòðèì ýòîò ïàðàìåòð
919 if(i != 0x00){
920 if(Common.Block[i].PointBoardCmd == 0x00) Common.Block[i].Timeout = 1; //âûñòàâëÿåì âðåìÿ ìåæäó êîìàíäàìè 1 ñåê, òàê êàê ìû íà÷èíàåì íîâûé öèêë îïðîñîâ äàëüíèõ áëîêîâ
921 }
922 else Common.Block[i].Timeout = PLC_Data[i].PollingTimeout;
923 if((PLC_Data[i].Route[0] > 0) || (i == 0)) indexPoll |= (1 << i);
924 }
925 // else Common.Block[i].Timeout = PLC_Data[i].PollingTimeout; // åñëè íàì çàïðåùåíî îïðàøèâàòü êàêîé òî äàëüíèé áëîê, òî êàæäûå n ñåêóíä ïðîâåðÿåì ôëàã enable poll
926 Common.Block[i].NewTime = TimerCounter + Common.Block[i].Timeout; // âû÷èñëÿåì âðåìÿ ñëåäóþùåãî îïðîñà
927 }
928 Common.Block[i].En = PLC_Data[i].EnablePoll;
929 }
930 for(uint8_t i = 0; (indexPoll != 0) || (i < AMOUNT_BLOCK_PLC);){
931 if(indexPoll & (1 << i)){ // åñòü ôëàã äëÿ ïåðåäà÷è
932 _Bool Send = 0;
933 uint8_t routeByte = 0;
934 PLCTxData.Pointer = 0x01;
935 PLCTxData.LenBuff = 0;
936 if((!Common.Block[i].FirstRequest) && (Common.Block[i].PointBoardCmd == 0x00)) Common.Block[i].PointBoardCmd++; // ïðîïóñêàåì ïåðâóþ êîìàíäó, òàê êàê âåðñèþ çàïðàøèâàòü íå íóæíî
937 if((uint8_t)(Common.BoardCmd[Common.Block[i].PointBoardCmd] >> 8) == 0x0A) Common.CurrentIndexUM = 0;// ïåðâûé ÓÌ02
938 else if((uint8_t)(Common.BoardCmd[Common.Block[i].PointBoardCmd] >> 8) == 0x0C) Common.CurrentIndexUM = 1;// âòîðîé ÓÌ02
939 else Common.CurrentIndexUM = 0xFF;
940
941 PLCTxData.Buff[PLCTxData.LenBuff++] = (PLC_ADDR_BOARD << 4);
942 if(i != 0){
943 routeByte = (PLC_Data[i].Route[0] + 1) / 2; // âû÷èñëÿåì ñ êàêîãî áàéòà áåðåì äàííûå
944 memcpy(&PLCTxData.Buff[PLCTxData.LenBuff], &PLC_Data[i].Route[1], routeByte);
945 PLCTxData.LenBuff += routeByte;
946
947 if((PLC_Data[i].Route[0] % 2) == 0) PLCTxData.Buff[PLCTxData.LenBuff++] = (uint8_t)(Common.BoardCmd[Common.Block[i].PointBoardCmd] >> 8);// ÷åòíîå, ïîñòàâëÿåì â ìëàäøóþ
948 else PLCTxData.Buff[routeByte] |= (uint8_t)((Common.BoardCmd[Common.Block[i].PointBoardCmd] >> 8) << 4);
949 }
950 else PLCTxData.Buff[PLCTxData.LenBuff++] = (uint8_t)(Common.BoardCmd[Common.Block[i].PointBoardCmd] >> 8);
951 PLCTxData.Buff[PLCTxData.LenBuff++] = (uint8_t)Common.BoardCmd[Common.Block[i].PointBoardCmd++];
952
953 if(Common.CurrentIndexUM != 0xFF){ // ïåðåäà÷à êîìàíäû óì 02
954 if(Common.Block[i].UM[Common.CurrentIndexUM].Presence){ // óì ïðèñóòñòâóåò
955 if(Common.Block[i].UM[Common.CurrentIndexUM].RequestCnt++ == 10){
956 //__debug(DEBUG_SERVSE, "block %d, UM no answer\r\n", i);
957 PLC_Data[i].PowerAmplifier[Common.CurrentIndexUM].Presence = 0; // òóò ìû ôèêñèðóåì ÷òî ÓÌ îòñóòñòâóåò
958 PLC_Data[i].PowerAmplifier[Common.CurrentIndexUM].Level_Transmitter = 0;
959 PLC_Data[i].PowerAmplifier[Common.CurrentIndexUM].Temp = 0;
960 PLC_Data[i].PowerAmplifier[Common.CurrentIndexUM].Voltage = 0;
961 Common.Block[i].UM[Common.CurrentIndexUM].Presence = 0;
962 Common.Block[i].UM[Common.CurrentIndexUM].RequestCnt = 0;
963 }
964 else if(Common.Block[i].UM[Common.CurrentIndexUM].RequestCnt == 1) Send = 1; // îòïðàâèòü íóæíî îäèí ðàç!!! çà÷åì?????
965 }
966 else{ // óì îòñóòñòâóåò
967 if(Common.Block[i].UM[Common.CurrentIndexUM].RequestCnt++ == 10){ // ñäåëàòü áû àäàïòèâíî çàâèñÿùåå îò âðåìåíè ïîëëèíãà
968 //__debug(DEBUG_SERVSE, "block %d, UM re-request\r\n", i);
969 Common.Block[i].UM[Common.CurrentIndexUM].Presence = 1;
970 Common.Block[i].UM[Common.CurrentIndexUM].RequestCnt = 0;
971 Send = 1;
972 }
973 }
974 }
975 else Send = 1; // åòî íå UM îòïðàâëÿåì ïîëþáîìó
976
977 if(Send) {
978 if(__debug(DEBUG_PLC_CROSS,"********* TX CROSS *********\r\n")){ // âûâîäèì äåáàã
979 sBuffCnt = 0;
980 sBuffCnt += sprintf(&sBuffer[sBuffCnt], "pointer:%02X\r\ndata [%d]:", PLCTxData.Pointer, PLCTxData.LenBuff);
981 for(uint16_t i = 0; i < PLCTxData.LenBuff; i++)sBuffCnt += sprintf(&sBuffer[sBuffCnt],"%02X", PLCTxData.Buff[i]);
982 __debug(DEBUG_PLC_CROSS,"%s\r\n***************************************\r\n", sBuffer);
983 }
984 if(uxQueueMessagesWaiting(QueueCmdTxPLC) == MAX_ELEMENTS_TX){ // åñëè î÷åðåäü ïîëíàÿ íà ïåðåäà÷ó!!
985 if(xQueueSend(QueueCmdTxPLC, &PLCTxData, 3000) == errQUEUE_FULL) xQueueReset(QueueCmdTxPLC);// åñëè ÷åðåç 3 ñåê î÷åðåäü íå îïóñòåëà òî ñáðàñûâàåì åå ñàìè
986 }
987 else xQueueSend(QueueCmdTxPLC, &PLCTxData, portMAX_DELAY);
988 }
989 if(Common.Block[i].PointBoardCmd >= AMOUNT_BOARD_CMD) { // çíà÷èò áûëî 9 èëè áîëüøå è ýòèì ñàìûì ìû ïîíèìàåì ÷òî îòïðàâèëè âñå
990 Common.Block[i].PointBoardCmd = 0;
991 if(Common.Block[i].RequestCnt++ == 5){ // áûëî îòïðàâëåíî 5 çàïðîñîâ, íî áåç îòâåòà
992 Common.Block[i].Presece = 0; // ñîîáùàåì ÷òî áëîê îòñóòñòâóåò
993 Common.Block[i].FirstRequest = 1; // ñêèäûâàåì äëÿ îòïðàâêè òîëüêî ïåðâîé êîìàíäû
994 Common.Block[i].RequestCnt = 0;
995 Common.Block[i].UM[0].Presence = 1; // äëÿ ñëåäóþùèõ çàïðîñîâ
996 Common.Block[i].UM[0].RequestCnt = 0;
997 Common.Block[i].UM[1].Presence = 1; // äëÿ ñëåäóþùèõ çàïðîñîâ
998 Common.Block[i].UM[1].RequestCnt = 0;
999 }
1000 if(i != 0x00) Common.Block[i].NewTime = TimerCounter + PLC_Data[i].PollingTimeout;// åñëè ïåðåäà÷à äàëüíèõ áëîêîâ è ïåðåäàëè âñå, òî æäåì óñòàíîâëåííûé timeout;
1001 indexPoll &= ~(1 << i);
1002 i++;
1003 }
1004 else {
1005 if(Common.Block[i].FirstRequest){ // åñëè áëîêè åùå íå îòâå÷àëè
1006 Common.Block[i].PointBoardCmd = 0;
1007 if(i == 0x00) Common.Block[i].NewTime = TimerCounter + 10;// áëèæíèé áëîê
1008 else Common.Block[i].NewTime = TimerCounter + 30;
1009 indexPoll &= ~(1 << i);
1010 i++;
1011 }
1012 else if((i != 0x00) && (Send)){ // äàëüíèé áëîê, è ïåðåäàëè íå âñå
1013 indexPoll &= ~(1 << i);
1014 i++;
1015 }
1016 }
1017 Send = 0;
1018 }
1019 else i++;
1020 }
1021 TimerCounter++;
1022 }
1023/*********************************************************************************************************/
1024 osDelay(1);
1025 }
1026}
1027/* ----------------------------------------------------------------------------------------- */
1028/* ######################################################################################### */
1029void GetContentType(char *FileName, char *ContentType);
1030int32_t substr_len(char *str, char symbol, char addSymbol);
1031/* WEB SERVER TASK ------------------------------------------------------------------------- */
1032#include "cookie.h"
1033static void WebServer_task(void *param)
1034{
1035
1036 __logWrite("HTTP daemon started\n");
1037
1038 enum {
1039 STATE_WAIT_ETH_TASK,
1040 STATE_CONNECT_NEW,
1041 STATE_BIND,
1042 STATE_LISTEN
1043 }FSM_State = STATE_WAIT_ETH_TASK;
1044
1045 struct netbuf *nbuf;
1046 ip_addr_t remote_addr;
1047 uint16_t remoute_port;
1048 uint16_t TCPlenData = 0;
1049 char *TCPdata = NULL;
1050 volatile _Bool notFountPage = 0, noMemory = 0;
1051 uint16_t LenContent = 0;
1052 uint16_t cnt_timeout = 0;
1053 //ip_addr_t *addr;
1054 /**************/
1055 char ContentType[32], CodeResponse[16], HeaderHTTP[1024];
1056 char *FileNameHTTP = NULL;
1057 uint8_t *FileHTTP;
1058 uint32_t FileSizeHTTP;
1059 FIL FSFileHTTP;
1060// DIR dirFAT;
1061 /**************/
1062 request_typDef request = {0};
1063 char *Cookie = NULL;/* èùåì êóêè â õåäåðå */
1064 char *str = NULL;
1065 char response_json[512] = {0}, response_cookie[512] = {0};
1066 char *JSON_Request = NULL;
1067
1068 struct netconn *serv_conn, *conn;
1069 err_t conn_err;
1070
1071 for(;;)
1072 {
1073 switch(FSM_State){
1074 case STATE_WAIT_ETH_TASK:
1075 if(ETH_linkState == LINK_UP) FSM_State = STATE_CONNECT_NEW;
1076 vTaskDelay(1);
1077 break;
1078 case STATE_CONNECT_NEW:
1079 serv_conn = netconn_new(NETCONN_TCP);
1080 if(serv_conn != NULL) FSM_State = STATE_BIND;
1081 vTaskDelay(1);
1082 break;
1083 case STATE_BIND:
1084 conn_err = netconn_bind(serv_conn, IP_ADDR_ANY, 80);
1085 if(conn_err == ERR_OK) {
1086 netconn_listen(serv_conn);
1087 __debug(DEBUG_WEB_SERVER, "Web server listen port 80\r\n");
1088 FSM_State = STATE_LISTEN;
1089 }
1090 vTaskDelay(1);
1091 break;
1092 case STATE_LISTEN:
1093 conn_err = netconn_accept(serv_conn, &conn);
1094 if(conn_err == ERR_OK){
1095 wdt_reset();
1096 __debug(DEBUG_WEB_SERVER, "Connection\r\n");
1097 TCPlenData = 0;
1098 FileSizeHTTP = 0;
1099 notFountPage = 0;
1100 noMemory = 0;
1101 LenContent = 0;
1102 request.cookie->len = 0;
1103 request.cookie->tokenCount = 0;
1104 request.json_len = 0;
1105 netconn_set_recvtimeout(conn, 200);
1106 conn_err = netconn_recv(conn, &nbuf);
1107 if(conn_err == ERR_OK){
1108 wdt_reset();
1109 netconn_getaddr(conn, &remote_addr, &remoute_port, 0); // ïîëó÷àåì àäðåññ óäàëåííûé
1110 netbuf_data(nbuf, (void**)&TCPdata, &TCPlenData);
1111 TCPdata[TCPlenData] = 0;
1112 if(strncmp(TCPdata, "GET /", 5) == 0){
1113 int16_t lenNameFile = substr_len(&TCPdata[5], ' ', NULL);
1114 if(lenNameFile == 0){
1115 FileNameHTTP = pvPortMalloc(15);
1116 if(FileNameHTTP != NULL){
1117 strcpy(FileNameHTTP, "web/index.html");
1118 FileNameHTTP[14] = 0;
1119 }
1120 else noMemory = 1;
1121 }
1122 else if(lenNameFile > 0){
1123 FileNameHTTP = pvPortMalloc(lenNameFile + 5);
1124 if(FileNameHTTP != NULL){
1125 if((strncmp(&TCPdata[5], "config.xml", 10) == 0) || (strncmp(&TCPdata[5], "mibs/", 5) == 0))memcpy(FileNameHTTP, &TCPdata[5], lenNameFile);
1126 else {
1127 sprintf(FileNameHTTP, "web/");
1128 memcpy(&FileNameHTTP[4], &TCPdata[5], lenNameFile);
1129 lenNameFile += 4;
1130 }
1131 FileNameHTTP[lenNameFile] = 0;
1132 }
1133 else noMemory = 1;
1134 }
1135 if(noMemory){
1136 __debug(DEBUG_WEB_SERVER, "No memory\r\n", nbuf->addr.addr);
1137 netconn_close(conn);
1138 netbuf_delete(nbuf);
1139 netconn_delete(conn);
1140 continue;
1141 }
1142 if(xSemaphoreTake(MutexAccessFlash, portMAX_DELAY) == pdTRUE){
1143 //struct dirpath *dir = f_get_path((char*)FileNameHTTP);
1144 //if(dir != NULL){
1145 //if(dir->dirname != NULL){
1146 // if(f_opendir(&dirFAT, dir->dirname) == FR_NO_PATH) {
1147 // f_closedir(&dirFAT);
1148 // f_dir_path_free(dir);
1149 // notFountPage = 1;
1150 // }
1151 //else dir->statedir = OPEN_DIR;
1152 //}
1153 //if(dir->fname != NULL) {
1154 if(f_open(&FSFileHTTP, FileNameHTTP/*dir->fname*/, FA_READ) == FR_OK){ // åñòü ôàéë, òî îòäàåì åãî
1155 FileSizeHTTP = f_size(&FSFileHTTP);
1156 strcpy(CodeResponse, "200 OK");
1157 GetContentType(FileNameHTTP/*dir->fname*/, ContentType);
1158 sprintf(HeaderHTTP, "HTTP/1.1 %s\r\nContent-Type: %s; charset=utf-8\r\nConnection: close\r\nContent-Length: %d\r\n\r\n", CodeResponse, ContentType, FileSizeHTTP);
1159 netconn_write(conn, HeaderHTTP, strlen(HeaderHTTP), FileSizeHTTP ? (NETCONN_NOCOPY | NETCONN_MORE) : NETCONN_NOCOPY);
1160 if(FileSizeHTTP > 0){
1161 uint32_t ByteCountRead = 0, ByteRead = 0, ByteWritten = 0;
1162 uint8_t TCP_Flag = NETCONN_COPY | NETCONN_MORE;
1163 if(FileSizeHTTP > TCP_MSS) FileHTTP = pvPortMalloc(TCP_MSS);
1164 else FileHTTP = pvPortMalloc(FileSizeHTTP);
1165 if(FileHTTP != NULL){
1166 while(1){
1167 if((FileSizeHTTP - ByteRead) > TCP_MSS) ByteCountRead = TCP_MSS;
1168 else {
1169 TCP_Flag &= ~NETCONN_MORE;
1170 ByteCountRead = FileSizeHTTP - ByteRead;
1171 }
1172 f_lseek(&FSFileHTTP, ByteRead);
1173 f_read(&FSFileHTTP, FileHTTP, (UINT)ByteCountRead, (UINT*)&ByteWritten);
1174 netconn_write(conn, FileHTTP, ByteCountRead, TCP_Flag);
1175 ByteRead += ByteCountRead;
1176 if(ByteRead >= FileSizeHTTP)break;
1177 }
1178 vPortFree(FileHTTP);
1179 }
1180 else notFountPage = 1;
1181 }
1182 f_close(&FSFileHTTP);
1183 }
1184 else notFountPage = 1;
1185 //if(dir->statedir == OPEN_DIR)f_closedir(&dirFAT);
1186 //f_dir_path_free(dir);
1187 //}
1188 //else notFountPage = 1;
1189 //}
1190 //else notFountPage = 1;
1191 if(notFountPage){
1192 strcpy(CodeResponse, "404 Not Found");
1193 strcpy(ContentType, "text/html");
1194 sprintf(HeaderHTTP, "HTTP/1.1 %s\r\nContent-Type: %s; charset=utf-8\r\nConnection: close\r\nContent-Length: %d\r\n\r\n", CodeResponse, ContentType, FileSizeHTTP);
1195 netconn_write(conn, HeaderHTTP, strlen(HeaderHTTP), NETCONN_NOCOPY);
1196 }
1197 }
1198 vPortFree(FileNameHTTP);
1199 xSemaphoreGive(MutexAccessFlash);
1200 }
1201 else if(strncmp(TCPdata, "POST /api.c", 11) == 0){ //POST /config
1202 /* èùåì äëèíó êîíòåíòà */
1203 str = strstr(TCPdata, "Content-Length:");
1204 if(str != NULL){
1205 str += 16; // ñäâèãàåì óêàçàòåëü íà 16 ñèìâîëîâ ïåðåä
1206 LenContent = atoi(str);
1207 }
1208 /* ************************ */
1209 str = strstr(TCPdata, "Cookie:"); // ñäâèãàåì óêàçàòåëü íà 8 ñèìâîëîâ ïåðåä
1210 if(str != NULL) {// åñòü êóêè
1211 str += 8;
1212 uint16_t LenCookie = substr_len(str, '\r', '\n');
1213 if(LenCookie > 0){
1214 Cookie = pvPortMalloc(LenCookie);
1215 if(Cookie != NULL){
1216 memcpy(Cookie, str, LenCookie);
1217 cookie_token_typDef cookie_token[8] = {0};
1218 cookie_token_data_typDef cookie_data = {0};
1219 cookie_data.data = Cookie;
1220 cookie_data.len = LenCookie;
1221 cookie_data.tokens = cookie_token;
1222 cookie_parse_tokens(&cookie_data);
1223 request.cookie = &cookie_data;
1224 }
1225 else request.cookie = NULL;
1226 }
1227 else request.cookie = NULL;
1228 }
1229 else request.cookie = NULL;
1230
1231 //if(Cookie == NULL) request.cookie = NULL;
1232
1233 /* ************************ */
1234 if(LenContent > 0){
1235 JSON_Request = pvPortMalloc(LenContent + 1); // âûäåëÿåì ïàìÿòü ïîä ïîëíçíûå äàííûå, + íîëü çàâåðøàþùèé
1236 if(JSON_Request != NULL){
1237 memcpy(JSON_Request, &TCPdata[TCPlenData - LenContent], LenContent);
1238 JSON_Request[LenContent] = 0;
1239 request.json_data = JSON_Request;
1240 request.json_len = LenContent;
1241 request.remote_addr = &remote_addr;
1242 __debug(DEBUG_WEB_SERVER, "\r\nrequest json %s\r\n", JSON_Request);
1243 json_parse(&request, response_json, sizeof(response_json), response_cookie); // âåðíóòü åùå êóêè/ åùå âåðíåì ðåçóëüòàò âûïîëíåíèÿ êîìàíäû
1244 vPortFree(JSON_Request);
1245 __debug(DEBUG_WEB_SERVER, "response json %s\r\n\r\n", response_json); // îòâåò äëÿ îòïðàâêè
1246 strcpy(CodeResponse, "200 OK");
1247 GetContentType(".json", ContentType);
1248 sprintf(HeaderHTTP, "HTTP/1.1 %s\r\nContent-Type: %s; charset=utf-8\r\nConnection: close\r\nContent-Length: %d\r\n%s\r\n", CodeResponse, ContentType, strlen(response_json), response_cookie);
1249 netconn_write(conn, HeaderHTTP, strlen(HeaderHTTP), NETCONN_COPY | NETCONN_MORE);
1250 netconn_write(conn, response_json, strlen(response_json), NETCONN_COPY);
1251 }
1252 }
1253 vPortFree(Cookie);
1254 }
1255 }
1256 else __debug(DEBUG_WEB_SERVER, "Receive timeout\r\n");
1257
1258 while(conn->state & NETCONN_WRITE){
1259 wdt_reset();
1260 if(cnt_timeout++ == 500) {
1261 __debug(DEBUG_WEB_SERVER, "500ms receive timeout\r\n");
1262 break; // ïðèíóäèòåëüíûé òàéìàóò íà 500ms
1263 }
1264 else vTaskDelay(1);
1265 }
1266 cnt_timeout = 0;
1267 __debug(DEBUG_WEB_SERVER, "Connection close\r\n");
1268 netconn_close(conn);
1269 netbuf_delete(nbuf);
1270 netconn_delete(conn);
1271 }
1272 else vTaskDelay(1);
1273 break;
1274 }
1275 }
1276}
1277/* ----------------------------------------------------------------------------------------- */
1278/* ######################################################################################### */
1279/* OTHER FUNCTION -------------------------------------------------------------------------- */
1280void GetContentType(char *FileName, char *ContentType)
1281{
1282 uint8_t i = 0;
1283 for(; FileName[i] != '.'; i++);
1284 if(strncmp(&FileName[i], ".html", 5) == 0) strcpy(ContentType, "text/html");
1285 else if(strncmp(&FileName[i], ".css", 4) == 0) strcpy(ContentType, "text/css");
1286 else if(strncmp(&FileName[i], ".json", 5) == 0) strcpy(ContentType, "application/json");
1287 else if(strncmp(&FileName[i], ".js", 3) == 0) strcpy(ContentType, "text/javascript");
1288 else if(strncmp(&FileName[i], ".gif", 4) == 0) strcpy(ContentType, "image/gif");
1289 else if(strncmp(&FileName[i], ".jpeg", 5) == 0) strcpy(ContentType, "image/jpeg");
1290 else if(strncmp(&FileName[i], ".png", 4) == 0) strcpy(ContentType, "image/png");
1291 else if(strncmp(&FileName[i], ".ico", 4) == 0) strcpy(ContentType, "image/vnd.microsoft.icon");
1292 else strcpy(ContentType, "text/plain");
1293}
1294
1295int32_t substr_len(char *str, char symbol, char addSymbol) // âîçâðàùàåò äëèíó ïîäñòðîêè, 0 åñëè íåò êîíå÷íîãî ñèìâîëà
1296{
1297 if(str == NULL) return -1;
1298 uint16_t len = 0;
1299 uint16_t PosEnd = 0;
1300 uint16_t strLen = strlen(str);
1301 if(strLen == 0) return -1;
1302 if(addSymbol == NULL){
1303 for(; str[PosEnd] != symbol; PosEnd++)
1304 {
1305 len++;
1306 if(strLen == len) return -1;
1307 }
1308 }
1309 else {
1310 for(;; PosEnd++)
1311 {
1312 if((str[PosEnd] == symbol) || (str[PosEnd] == addSymbol)) break;
1313 else len++;
1314 if(strLen == len) return -1;
1315 }
1316 }
1317 return len;
1318}
1319/* ----------------------------------------------------------------------------------------- */
1320/* ######################################################################################### */
1321/* GPIO CALLBACK --------------------------------------------------------------------------- */
1322void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
1323{
1324 if(GPIO_Pin == PHY_INT_Pin) // interrupt PHY
1325 {
1326 portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
1327 xSemaphoreGiveFromISR(SemaphoreIRQ_PHY, &xHigherPriorityTaskWoken);
1328 }
1329}
1330/* USER CODE END Application */
1331
1332/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.