http_server.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354
  1. #include "lwip/opt.h"
  2. #include "lwip/arch.h"
  3. #include "lwip/api.h"
  4. #include "lwip/tcp.h"
  5. #include "http_server.h"
  6. #include "web_params_api.h"
  7. #include "parameters.h"
  8. #include "urlcode.h"
  9. #include "trap_params.h"
  10. #include "fsdata.c"
  11. #include "settings_api.h"
  12. #include "netconf.h"
  13. #include "common_config.h"
  14. //#include "testing.h"
  15. #include "rtc.h"
  16. #include "rng.h"
  17. #ifdef PRINTF_STDLIB
  18. #include <stdio.h>
  19. #endif
  20. #ifdef PRINTF_CUSTOM
  21. #include "tinystdio.h"
  22. #endif
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include "FreeRTOS.h"
  26. #include "task.h"
  27. #include "timers.h"
  28. static int fs_open(char *name, struct fs_file *file);
  29. static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len);
  30. static void send_data(struct tcp_pcb *pcb, struct http_state *hs);
  31. static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len);
  32. static uint32_t Parse_Content_Length(char *data, uint32_t len);
  33. static void HTTP_SetUserCookie(char *str, uint8_t user_id);
  34. static void HTTP_UpdateUserLoginTime(uint8_t user_id);
  35. static void HTTP_ForceUserLogout(uint8_t user_id);
  36. void LogoutTimerCallback(TimerHandle_t pxTimer);
  37. SET_PAGE_t SET_PAGE = SET_PAGE_IDLE;
  38. #define SEND_BUF_MAX_LEN 2000
  39. #define RECIVE_BUF_MAX_LEN 1500
  40. char sendBuf[SEND_BUF_MAX_LEN];
  41. uint16_t sendBufLoadLen = 0;
  42. uint16_t printLen = 0;
  43. //char printBuf[1000];
  44. char receiveBuf[RECIVE_BUF_MAX_LEN];
  45. uint16_t receivedBufLen = 0;
  46. #define MAX_POST_REQ_LEN 256
  47. char post_req_data[MAX_POST_REQ_LEN];
  48. uint32_t post_data_count;
  49. uint32_t log_post_reqn;
  50. /* Logout timeout, 30 minutes */
  51. #define WEB_LOGOUT_TIME configTICK_RATE_HZ*60*30
  52. /* Max user active sessions count */
  53. #define WEB_USER_MAX_SESSION_COUNT 5
  54. typedef struct {
  55. char cookie[MAX_WEB_COOKIE_LEN];
  56. TimerHandle_t LogoutTimer;
  57. } auth_session_t;
  58. struct {
  59. //auth_session_t session[WEB_USER_MAX_SESSION_COUNT];
  60. char cookie[MAX_WEB_COOKIE_LEN];
  61. TimerHandle_t LogoutTimer;
  62. } users[MAX_WEB_USERS];
  63. bool Authenticated = false;
  64. /* Level of currently logged-in user */
  65. uint8_t seclevel = 0xFF;
  66. static uint32_t ContentLengthOffset =0;
  67. static const char Content_Length[17] =
  68. /* Content Length */
  69. {0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67,0x74, 0x68, 0x3a, 0x20, };
  70. /**
  71. * @brief closes tcp connection
  72. * @param pcb: pointer to a tcp_pcb struct
  73. * @param hs: pointer to a http_state struct
  74. * @retval
  75. */
  76. static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
  77. {
  78. tcp_arg(pcb, NULL);
  79. tcp_sent(pcb, NULL);
  80. tcp_recv(pcb, NULL);
  81. mem_free(hs);
  82. tcp_close(pcb);
  83. }
  84. /**
  85. * @brief callback function for handling TCP HTTP traffic
  86. * @param arg: pointer to an argument structure to be passed to callback function
  87. * @param pcb: pointer to a tcp_pcb structure
  88. * @param p: pointer to a packet buffer
  89. * @param err: LwIP error code
  90. * @retval err
  91. */
  92. static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
  93. {
  94. char *data;
  95. struct http_state *hs;
  96. char CookieBuf[50];
  97. char *CookiePtr = NULL;
  98. char name[MAX_WEB_COOKIE_LEN];
  99. char id[MAX_WEB_COOKIE_LEN];
  100. uint8_t nameLen = 0, idLen = 0;
  101. struct fs_file file = {0, 0};
  102. hs = arg;
  103. if (err == ERR_OK && p != NULL)
  104. {
  105. tcp_recved(pcb, p->tot_len);
  106. if (hs->file == NULL)
  107. {
  108. data = p->payload;
  109. /*
  110. printLen = p->tot_len;
  111. memcpy(printBuf, p->payload , printLen);
  112. printf(printBuf);
  113. */
  114. receivedBufLen = p->tot_len;
  115. memcpy(receiveBuf, p->payload , receivedBufLen);
  116. receiveBuf[receivedBufLen] = '\0';
  117. // printf("receive %s \r\n", receiveBuf);
  118. /* Get cookie "uname" value */
  119. CookiePtr = strstr(receiveBuf, "uname=");
  120. strncpy(CookieBuf, CookiePtr, 50);
  121. //printf("********CookieBuf1= %s\r\n", CookieBuf);
  122. memset(name, 0, MAX_WEB_COOKIE_LEN);
  123. GetCookieValue(CookieBuf, "uname=", name, &nameLen);
  124. //printf("********CookieBuf2= %s\r\n", CookieBuf);
  125. //printf("********uname= %s\r\n", name);
  126. /* Get cookie "id" value */
  127. CookiePtr = strstr(receiveBuf, "id=");
  128. strncpy(CookieBuf, CookiePtr, 50);
  129. //printf("********CookieBuf1= %s\r\n", CookieBuf);
  130. memset(id, 0, MAX_WEB_COOKIE_LEN);
  131. GetCookieValue(CookieBuf, "id=", id, &idLen);
  132. //printf("********CookieBuf2= %s\r\n", CookieBuf);
  133. //printf("********id= %s\r\n", id);
  134. /* Id of currently logged-in user */
  135. uint8_t user_id;
  136. /* Level of currently logged-in user */
  137. seclevel = 0xFF;
  138. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  139. HTTP_GetUserCookie(user_id, CookieBuf, &idLen);
  140. if (strncmp(id, CookieBuf, idLen) == 0 ) {
  141. GetUserLevelInt(user_id, &seclevel);
  142. Authenticated = true;
  143. break;
  144. }
  145. Authenticated = false;
  146. seclevel = 0xFF;
  147. }
  148. if ( Authenticated == false )
  149. {
  150. if (strncmp(data, "GET /main.css", 13) == 0) // +
  151. {
  152. fs_open("/main.css", &file);
  153. hs->file = file.data;
  154. hs->left = file.len;
  155. send_data(pcb, hs);
  156. tcp_sent(pcb, http_sent);
  157. }
  158. else if (strncmp(data, "GET /rotek.png", 14) == 0) // +
  159. {
  160. fs_open("/rotek.png", &file);
  161. hs->file = file.data;
  162. hs->left = file.len;
  163. send_data(pcb, hs);
  164. tcp_sent(pcb, http_sent);
  165. }
  166. else if (strncmp(data, "GET /favicon.ico", 16) == 0) // ?
  167. {
  168. fs_open("/favicon.ico", &file);
  169. hs->file = file.data;
  170. hs->left = file.len;
  171. send_data(pcb, hs);
  172. tcp_sent(pcb, http_sent);
  173. }
  174. else if (strncmp(data, "GET /role.js", 12) == 0)
  175. {
  176. fs_open("/role.js", &file);
  177. hs->file = file.data;
  178. hs->left = file.len;
  179. send_data(pcb, hs);
  180. tcp_sent(pcb, http_sent);
  181. }
  182. else if ((strncmp(data, "POST /login.cgi", 15) == 0) || (log_post_reqn > 0))
  183. {
  184. uint32_t i, offset = 0, req_data_received = 0;
  185. //printf("request 1: %d\r\n", receivedBufLen);
  186. /* parse packet for Content-length field */
  187. post_data_count = Parse_Content_Length(data, p->tot_len);
  188. //printf("Content-length: %d\r\n", (int)post_data_count);
  189. if (post_data_count < MAX_POST_REQ_LEN) {
  190. memset(post_req_data, 0, MAX_POST_REQ_LEN);
  191. /* parse packet for "\r\n\r\n" */
  192. for (i = 0; i < receivedBufLen; i++)
  193. {
  194. if (strncmp ((char*)(data+i), "\r\n\r\n", 4) == 0)
  195. {
  196. offset = i+4;
  197. //printf("offset: %d\r\n", (int)offset);
  198. break;
  199. }
  200. }
  201. req_data_received = receivedBufLen - offset;
  202. //printf("req data received: %d\r\n", (int)req_data_received);
  203. /* Check if "\r\n\r\n" was found */
  204. if (offset != 0) {
  205. /* if data was splited in two packets */
  206. if (req_data_received < post_data_count) {
  207. /* Copy request data to buffer */
  208. snprintf(post_req_data, req_data_received, "%s", receiveBuf);
  209. //printf("copied: %d\r\n", (int)req_data_received);
  210. post_data_count -= req_data_received;
  211. }
  212. /* if data received completely */
  213. else {
  214. strncat(post_req_data, (char *)(data + offset), post_data_count);
  215. //printf("post_req_data: %s\r\n", post_req_data);
  216. if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), &sendBufLoadLen) == SEND_REQUIRED_YES) {
  217. hs->file = sendBuf;
  218. hs->left = sendBufLoadLen;
  219. send_data(pcb, hs);
  220. tcp_sent(pcb, http_sent);
  221. }
  222. else {
  223. /* Redirect to login page */
  224. fs_open("/login.html", &file);
  225. hs->file = file.data;
  226. hs->left = file.len;
  227. send_data(pcb, hs);
  228. tcp_sent(pcb, http_sent);
  229. }
  230. /* End reqest */
  231. post_data_count = 0;
  232. log_post_reqn = 0;
  233. }
  234. }
  235. /* request was fragmented before "\r\n\r\n" */
  236. else {
  237. //printf("no data found!\r\n");
  238. /* wait next packet */
  239. log_post_reqn++;
  240. /* wait max 2 requests */
  241. if (log_post_reqn > 1) {
  242. /* Redirect to login page */
  243. fs_open("/login.html", &file);
  244. hs->file = file.data;
  245. hs->left = file.len;
  246. send_data(pcb, hs);
  247. tcp_sent(pcb, http_sent);
  248. /* End reqest */
  249. post_data_count = 0;
  250. log_post_reqn = 0;
  251. }
  252. }
  253. }
  254. else {
  255. printf("Too long POST request!\r\n");
  256. /* Ignore request */
  257. post_data_count = 0;
  258. log_post_reqn = 0;
  259. /* Redirect to login page */
  260. fs_open("/login.html", &file);
  261. hs->file = file.data;
  262. hs->left = file.len;
  263. send_data(pcb, hs);
  264. tcp_sent(pcb, http_sent);
  265. }
  266. }
  267. else if (post_data_count > 0)
  268. {
  269. strncat(post_req_data, data, post_data_count);
  270. //printf("copied: %d\r\n", (int)post_data_count);
  271. //printf("post_req_data: %s\r\n", post_req_data);
  272. if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), &sendBufLoadLen) == SEND_REQUIRED_YES) {
  273. hs->file = sendBuf;
  274. hs->left = sendBufLoadLen;
  275. send_data(pcb, hs);
  276. tcp_sent(pcb, http_sent);
  277. }
  278. else {
  279. /* Redirect to login page */
  280. fs_open("/login.html", &file);
  281. hs->file = file.data;
  282. hs->left = file.len;
  283. send_data(pcb, hs);
  284. tcp_sent(pcb, http_sent);
  285. }
  286. /* End reqest */
  287. post_data_count = 0;
  288. log_post_reqn = 0;
  289. }
  290. else
  291. {
  292. fs_open("/login.html", &file);
  293. hs->file = file.data;
  294. hs->left = file.len;
  295. send_data(pcb, hs);
  296. tcp_sent(pcb, http_sent);
  297. }
  298. }
  299. else if ( Authenticated == true ) {
  300. if (strncmp(data, "GET /main.css", 13) == 0) // +
  301. {
  302. fs_open("/main.css", &file);
  303. hs->file = file.data;
  304. hs->left = file.len;
  305. send_data(pcb, hs);
  306. tcp_sent(pcb, http_sent);
  307. }
  308. else if (strncmp(data, "GET /rotek.png", 14) == 0) // +
  309. {
  310. fs_open("/rotek.png", &file);
  311. hs->file = file.data;
  312. hs->left = file.len;
  313. send_data(pcb, hs);
  314. tcp_sent(pcb, http_sent);
  315. }
  316. else if (strncmp(data, "GET /favicon.ico", 16) == 0) // ?
  317. {
  318. fs_open("/favicon.ico", &file);
  319. hs->file = file.data;
  320. hs->left = file.len;
  321. send_data(pcb, hs);
  322. tcp_sent(pcb, http_sent);
  323. }
  324. else if (strncmp(data, "GET /main.js", 12) == 0) // +
  325. {
  326. fs_open("/main.js", &file);
  327. hs->file = file.data;
  328. hs->left = file.len;
  329. send_data(pcb, hs);
  330. tcp_sent(pcb, http_sent);
  331. }
  332. else if (strncmp(data, "GET /role.js", 12) == 0)
  333. {
  334. fs_open("/role.js", &file);
  335. hs->file = file.data;
  336. hs->left = file.len;
  337. send_data(pcb, hs);
  338. tcp_sent(pcb, http_sent);
  339. }
  340. else if (strncmp(data, "GET /settings.html", 18) == 0) // +
  341. {
  342. HTTP_UpdateUserLoginTime(user_id);
  343. fs_open("/settings.html", &file);
  344. hs->file = file.data;
  345. hs->left = file.len;
  346. send_data(pcb, hs);
  347. tcp_sent(pcb, http_sent);
  348. }
  349. else if (strncmp(data, "GET /info.html", 14) == 0) // +
  350. {
  351. HTTP_UpdateUserLoginTime(user_id);
  352. fs_open("/info.html", &file);
  353. hs->file = file.data;
  354. hs->left = file.len;
  355. send_data(pcb, hs);
  356. tcp_sent(pcb, http_sent);
  357. }
  358. else if (strncmp(data, "GET /getJson.cgi", 16) == 0) // +
  359. {
  360. HTTP_GetParamsPage1(sendBuf);
  361. hs->file = sendBuf;
  362. hs->left = strlen(sendBuf);
  363. send_data(pcb, hs);
  364. tcp_sent(pcb, http_sent);
  365. }
  366. else if (strncmp(data, "GET /settings.cgi", 17) == 0) // +
  367. {
  368. SET_PAGE = SET_PAGE_PAGE2;
  369. if (HTTP_SettingsPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES)
  370. {
  371. hs->file = sendBuf;
  372. hs->left = sendBufLoadLen;
  373. send_data(pcb, hs);
  374. tcp_sent(pcb, http_sent);
  375. }
  376. else
  377. {
  378. fs_open("/settings.html", &file);
  379. hs->file = file.data;
  380. hs->left = file.len;
  381. send_data(pcb, hs);
  382. tcp_sent(pcb, http_sent);
  383. }
  384. }
  385. else if (strncmp(data, "GET /info.cgi", 13) == 0) // +
  386. {
  387. if (HTTP_InfoPage(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen) == SEND_REQUIRED_YES)
  388. {
  389. hs->file = sendBuf;
  390. hs->left = sendBufLoadLen;
  391. send_data(pcb, hs);
  392. tcp_sent(pcb, http_sent);
  393. }
  394. else
  395. {
  396. fs_open("/info.html", &file);
  397. hs->file = file.data;
  398. hs->left = file.len;
  399. send_data(pcb, hs);
  400. tcp_sent(pcb, http_sent);
  401. }
  402. }
  403. /* Сброс настроек и сохранине */
  404. else if (strncmp(data, "GET /reset.cgi", 14) == 0)
  405. {
  406. HTTP_ResetSettings();
  407. HTTP_SaveSettings();
  408. fs_open("/settings.html", &file);
  409. hs->file = file.data;
  410. hs->left = file.len;
  411. send_data(pcb, hs);
  412. tcp_sent(pcb, http_sent);
  413. }
  414. /* Перезагрузка контроллера */
  415. else if (strncmp(data, "GET /reboot.cgi", 15) == 0)
  416. {
  417. HTTP_Reboot();
  418. }
  419. /* Подтверждение новых сетевых настроек */
  420. else if (strncmp(data, "GET /confirm.cgi", 16) == 0)
  421. {
  422. SetWebReinitFlag(false);
  423. SetConfirmWebParamsFlag();
  424. fs_open("/index.html", &file);
  425. hs->file = file.data;
  426. hs->left = file.len;
  427. send_data(pcb, hs);
  428. tcp_sent(pcb, http_sent);
  429. }
  430. /* Проверка пароля, переход в bootloader */
  431. else if (strncmp(data, "POST /checkpwd.cgi", 18) == 0)
  432. {
  433. HTTP_ConfirmBootPwd(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  434. hs->file = sendBuf;
  435. hs->left = sendBufLoadLen;
  436. send_data(pcb, hs);
  437. tcp_sent(pcb, http_sent);
  438. }
  439. // На производстве
  440. else if (strncmp(data, "GET /setProdate.cgi", 19) == 0)
  441. {
  442. HTTP_Prodate(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  443. hs->file = sendBuf;
  444. hs->left = sendBufLoadLen;
  445. send_data(pcb, hs);
  446. tcp_sent(pcb, http_sent);
  447. }
  448. // На производстве
  449. else if (strncmp(data, "GET /progon.cgi", 15) == 0)
  450. {
  451. HTTP_Progon(receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  452. hs->file = sendBuf;
  453. hs->left = sendBufLoadLen;
  454. send_data(pcb, hs);
  455. tcp_sent(pcb, http_sent);
  456. }
  457. else
  458. {
  459. HTTP_UpdateUserLoginTime(user_id);
  460. fs_open("/index.html", &file); // +
  461. hs->file = file.data;
  462. hs->left = file.len;
  463. send_data(pcb, hs);
  464. tcp_sent(pcb, http_sent);
  465. }
  466. }
  467. }
  468. pbuf_free(p);
  469. close_conn(pcb,hs);
  470. }
  471. if (err == ERR_OK && p == NULL)
  472. {
  473. close_conn(pcb, hs);
  474. }
  475. return ERR_OK;
  476. }
  477. /**
  478. * @brief callback function for handling connection errors
  479. * @param arg: pointer to an argument to be passed to callback function
  480. * @param err: LwIP error code
  481. * @retval none
  482. */
  483. static void conn_err(void *arg, err_t err)
  484. {
  485. struct http_state *hs;
  486. hs = arg;
  487. mem_free(hs);
  488. }
  489. /**
  490. * @brief callback function called after a successfull TCP data packet transmission
  491. * @param arg: pointer to an argument to be passed to callback function
  492. * @param pcb: pointer on tcp_pcb structure
  493. * @param len
  494. * @retval err : LwIP error code
  495. */
  496. static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
  497. {
  498. struct http_state *hs;
  499. hs = arg;
  500. if (hs->left > 0)
  501. {
  502. send_data(pcb, hs);
  503. }
  504. else
  505. {
  506. close_conn(pcb, hs);
  507. }
  508. return ERR_OK;
  509. }
  510. /**
  511. * @brief sends data found in member "file" of a http_state struct
  512. * @param pcb: pointer to a tcp_pcb struct
  513. * @param hs: pointer to a http_state struct
  514. * @retval none
  515. */
  516. static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
  517. {
  518. err_t err;
  519. u16_t len;
  520. /* We cannot send more data than space available in the send
  521. buffer */
  522. if (tcp_sndbuf(pcb) < hs->left)
  523. {
  524. len = tcp_sndbuf(pcb);
  525. }
  526. else
  527. {
  528. len = hs->left;
  529. }
  530. err = tcp_write(pcb, hs->file, len, 0);
  531. if (err == ERR_OK)
  532. {
  533. hs->file += len;
  534. hs->left -= len;
  535. }
  536. }
  537. /**
  538. * @brief tcp poll callback function
  539. * @param arg: pointer to an argument to be passed to callback function
  540. * @param pcb: pointer on tcp_pcb structure
  541. * @retval err_t
  542. */
  543. static err_t http_poll(void *arg, struct tcp_pcb *pcb)
  544. {
  545. if (arg == NULL)
  546. {
  547. tcp_close(pcb);
  548. }
  549. else
  550. {
  551. send_data(pcb, (struct http_state *)arg);
  552. }
  553. return ERR_OK;
  554. }
  555. /**
  556. * @brief callback function on TCP connection setup ( on port 80)
  557. * @param arg: pointer to an argument structure to be passed to callback function
  558. * @param pcb: pointer to a tcp_pcb structure
  559. * &param err: Lwip stack error code
  560. * @retval err
  561. */
  562. static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
  563. {
  564. struct http_state *hs;
  565. /* Allocate memory for the structure that holds the state of the connection */
  566. hs = mem_malloc(sizeof(struct http_state));
  567. if (hs == NULL)
  568. {
  569. return ERR_MEM;
  570. }
  571. /* Initialize the structure. */
  572. hs->file = NULL;
  573. hs->left = 0;
  574. /* Tell TCP that this is the structure we wish to be passed for our
  575. callbacks. */
  576. tcp_arg(pcb, hs);
  577. /* Tell TCP that we wish to be informed of incoming data by a call
  578. to the http_recv() function. */
  579. tcp_recv(pcb, http_recv);
  580. tcp_err(pcb, conn_err);
  581. tcp_poll(pcb, http_poll, 10);
  582. return ERR_OK;
  583. }
  584. /**
  585. * @brief Opens a file defined in fsdata.c ROM filesystem
  586. * @param name : pointer to a file name
  587. * @param file : pointer to a fs_file structure
  588. * @retval 1 if success, 0 if fail
  589. */
  590. static int fs_open(char *name, struct fs_file *file)
  591. {
  592. struct fsdata_file_noconst *f;
  593. for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next)
  594. {
  595. if (!strcmp(name, f->name))
  596. {
  597. file->data = f->data;
  598. file->len = f->len;
  599. return 1;
  600. }
  601. }
  602. return 0;
  603. }
  604. /**
  605. * @brief Initialize the HTTP server (start its thread)
  606. * @param none
  607. * @retval None
  608. */
  609. void HTTP_Init()
  610. {
  611. char buf[MAX_WEB_COOKIE_LEN];
  612. uint8_t user_id;
  613. //sys_thread_new("HTTP", http_server_netconn_thread, NULL, 3000, 2);
  614. struct tcp_pcb *pcb;
  615. /*create new pcb*/
  616. pcb = tcp_new();
  617. /* bind HTTP traffic to pcb */
  618. tcp_bind(pcb, IP_ADDR_ANY, 80);
  619. /* start listening on port 80 */
  620. pcb = tcp_listen(pcb);
  621. /* define callback function for TCP connection setup */
  622. tcp_accept(pcb, http_accept);
  623. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  624. /* Flush user cookie by random value */
  625. sprintf(buf, "%X", (unsigned int)GetRandomNumber());
  626. HTTP_SetUserCookie(buf, user_id);
  627. /* Create user logout timers */
  628. users[user_id].LogoutTimer =
  629. xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback);
  630. }
  631. }
  632. /**
  633. * @brief
  634. * @retval None
  635. */
  636. int HTTP_SettingsPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  637. {
  638. char tempStr[30];
  639. strncpy(tempStr, bufIn, 30);
  640. /* В запросе нет параметров, нужно формировать JSON ответ */
  641. if (strpbrk(tempStr,"?") == 0)
  642. {
  643. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  644. HTTP_GetSettings(bufOut);
  645. //printf(bufOut);
  646. *lenBufOut = strlen(bufOut);
  647. return SEND_REQUIRED_YES;
  648. }
  649. /* В запросе есть параметры, нужно парсить и сохранять настройки */
  650. else
  651. {
  652. HTTP_SetSettings(bufIn, lenBufIn);
  653. return SEND_REQUIRED_NO;
  654. }
  655. }
  656. /**
  657. * @brief
  658. * @retval None
  659. */
  660. int HTTP_InfoPage(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  661. {
  662. char tempStr[30];
  663. strncpy(tempStr, bufIn, 30);
  664. /* В запросе нет параметров, нужно формировать JSON ответ */
  665. if (strpbrk(tempStr,"?") == 0)
  666. {
  667. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  668. HTTP_GetInfo(bufOut);
  669. *lenBufOut = strlen(bufOut);
  670. return SEND_REQUIRED_YES;
  671. }
  672. /* В запросе есть параметры, нужно парсить и сохранять настройки */
  673. else
  674. {
  675. HTTP_SetInfo(bufIn, lenBufIn);
  676. return SEND_REQUIRED_NO;
  677. /*
  678. HTTP_SetSettings(bufIn, lenBufIn);
  679. return SEND_REQUIRED_NO;
  680. */
  681. }
  682. }
  683. /**
  684. * @brief Установка даты производства
  685. */
  686. // TODO Убрать заглушку!
  687. void HTTP_Prodate(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  688. {
  689. uint8_t valueLen = 0;
  690. char value[20];
  691. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  692. ClearParamString(bufIn);
  693. memset(value, 0, 20);
  694. GetParamValue(bufIn, "prodate=", value, &valueLen);
  695. /*
  696. printf("Prodate: ");
  697. printf(value);
  698. printf("\r\n");
  699. */
  700. /* Устанавливаем дату производства */
  701. SETTINGS_SetProDate(value, valueLen);
  702. /* Устанавливаем дату следующей профилактики +1 год */
  703. RTC_SetProfTime(value);
  704. /* Пока отправляем true */
  705. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\nTrue");
  706. *lenBufOut = strlen(bufOut);
  707. // TEST_SetServerFlag();
  708. }
  709. /**
  710. * @brief Возвращает uptime, freq, dutycicle
  711. */
  712. void HTTP_Progon(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  713. {
  714. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  715. HTTP_GetProgonParams(bufOut);
  716. *lenBufOut = strlen(bufOut);
  717. }
  718. /**
  719. * @brief
  720. * @retval None
  721. */
  722. void HTTP_SetSettings(char *buf, uint16_t lenBuf)
  723. {
  724. uint8_t valueLen = 0;
  725. const uint8_t len = MAX_WEB_PARAM_LEN;
  726. char value[MAX_WEB_PARAM_LEN];
  727. char str[MAX_WEB_PARAM_LEN];
  728. //printf(buf);
  729. ClearParamString(buf);
  730. memset(value, 0, len);
  731. memset(str, 0, MAX_WEB_PARAM_LEN);
  732. /* SNMP */
  733. GetParamValue(buf, "read_community=", value, &valueLen);
  734. SetReadCommunity(value);
  735. memset(value, 0, len);
  736. GetParamValue(buf, "write_community=", value, &valueLen);
  737. SetWriteCommunity(value);
  738. memset(value, 0, len);
  739. GetParamValue(buf, "managerIP=", value, &valueLen);
  740. SetManagerIp(value);
  741. memset(value, 0, len);
  742. GetParamValue(buf, "managerIP2=", value, &valueLen);
  743. SetManagerIp2(value);
  744. memset(value, 0, len);
  745. GetParamValue(buf, "managerIP3=", value, &valueLen);
  746. SetManagerIp3(value);
  747. memset(value, 0, len);
  748. GetParamValue(buf, "managerIP4=", value, &valueLen);
  749. SetManagerIp4(value);
  750. memset(value, 0, len);
  751. GetParamValue(buf, "managerIP5=", value, &valueLen);
  752. SetManagerIp5(value);
  753. memset(value, 0, len);
  754. /* Сетевые параметры */
  755. GetParamValue(buf, "dhcp=", value, &valueLen);
  756. SetDhcpStateStr(value);
  757. if (strncmp(value, "on", 2) != 0) // Если dhcp off устанавливаем параметры
  758. {
  759. memset(value, 0, len);
  760. GetParamValue(buf, "ipaddr=", value, &valueLen);
  761. SetIPStr(value);
  762. memset(value, 0, len);
  763. GetParamValue(buf, "gw=", value, &valueLen);
  764. SetGatewayStr(value);
  765. memset(value, 0, len);
  766. GetParamValue(buf, "mask=", value, &valueLen);
  767. SetMaskStr(value);
  768. memset(value, 0, len);
  769. }
  770. memset(value, 0, len);
  771. /* параметры RADIUS*/
  772. GetParamValue(buf, "rs_enabled=", value, &valueLen);
  773. SetRDSEnableStateStr(value);
  774. memset(value, 0, len);
  775. GetParamValue(buf, "rs_server=", value, &valueLen);
  776. SetRDSIpStr(value);
  777. memset(value, 0, len);
  778. GetParamValue(buf, "rs_port=", value, &valueLen);
  779. SetRDSPortStr(value);
  780. memset(value, 0, len);
  781. GetParamValue(buf, "rs_pwd=", value, &valueLen);
  782. SetRDSPasswordkStr(value);
  783. memset(value, 0, len);
  784. GetParamValue(buf, "rs_key=", value, &valueLen);
  785. SetRDSKeyAccesstStr(value);
  786. memset(value, 0, len);
  787. // Параметры реле и сухих контактов
  788. GetParamValue(buf, "di1=", value, &valueLen);
  789. SetDINTypeActStr(value, 0);
  790. memset(value, 0, len);
  791. GetParamValue(buf, "ro1=", value, &valueLen);
  792. SetROTypeActStr(value, 0);
  793. memset(value, 0, len);
  794. GetParamValue(buf, "ro2=", value, &valueLen);
  795. SetROTypeActStr(value, 1);
  796. memset(value, 0, len);
  797. // Параметры даты и времени
  798. GetParamValue(buf, "ntp=", value, &valueLen);
  799. SetSntpStateStr(value);
  800. if (strncmp(value, "1", 1) == 0) // Если ntp on устанавливаем параметры
  801. {
  802. memset(value, 0, len);
  803. GetParamValue(buf, "ntpservip=", value, &valueLen);
  804. SetSntpServerIpStr(value);
  805. memset(value, 0, len);
  806. }
  807. else if (strncmp(value, "0", 1) == 0){
  808. GetParamValue(buf, "date=", value, &valueLen);
  809. SetDateStr(value);
  810. memset(value, 0, len);
  811. GetParamValue(buf, "time=", value, &valueLen);
  812. url_decode(str, sizeof(str), value);
  813. SetTimeStr(str);
  814. memset(value, 0, len);
  815. }
  816. GetParamValue(buf, "utc=", value, &valueLen);
  817. SetSntpTimeZoneStr(value);
  818. memset(value, 0, len);
  819. /* Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся */
  820. if (GetStateWebReinit() == true)
  821. {
  822. SetWebReinitFlag(true);
  823. HTTP_SaveSettings();
  824. /* Блокируем управление ключем на тау секунд*/
  825. //IO_KeyBlockOn();
  826. vTaskDelay(1010);
  827. NVIC_SystemReset();
  828. }
  829. HTTP_SaveSettings();
  830. }
  831. /**
  832. * @brief
  833. * @retval None
  834. */
  835. void HTTP_SetInfo(char *buf, uint16_t lenBuf)
  836. {
  837. uint8_t valueLen = 0;
  838. const uint8_t len = 110;
  839. char value[110];
  840. ClearParamString(buf);
  841. memset(value, 0, len);
  842. /* Владелец */
  843. GetParamValue(buf, "owner=", value, &valueLen);
  844. HTTP_ReplaceSimbol(value, '+', ' ');
  845. SetOwner(value);
  846. memset(value, 0, len);
  847. /* Владелец */
  848. GetParamValue(buf, "sysLocation=", value, &valueLen);
  849. HTTP_ReplaceSimbol(value, '+', ' ');
  850. SetLocation(value);
  851. memset(value, 0, len);
  852. /* Комментарий */
  853. GetParamValue(buf, "comment=", value, &valueLen);
  854. HTTP_ReplaceSimbol(value, '+', ' ');
  855. SetComment(value);
  856. memset(value, 0, len);
  857. HTTP_SaveSettings();
  858. }
  859. /**
  860. * @brief Проверка пароля для перехода в режим bootloader
  861. * @retval None
  862. */
  863. void HTTP_ConfirmBootPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  864. {
  865. char tempStr[50];
  866. strncpy(tempStr, bufIn, 50);
  867. char value[20];
  868. uint8_t valueLen;
  869. memset(value, 0, 20);
  870. if (GetParamValue(tempStr, "password=", value, &valueLen))
  871. {
  872. if (strcmp(BOOTLOADER_PASWORD, value) == 0)
  873. {
  874. *bufOut = '1';
  875. /* Запускаем задачу отложенной перезагрузки. Контроллер должен успеть
  876. отправить ответ серверу о статусе пароля */
  877. HTTP_StartResetTask(true);
  878. }
  879. else
  880. *bufOut = '0';
  881. *lenBufOut = 1;
  882. }
  883. }
  884. /**
  885. * @brief Проверка пароля для входа в Web
  886. * @retval None
  887. */
  888. int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  889. {
  890. char tempStr[50];
  891. char login[20];
  892. char password[20];
  893. uint8_t valueLen, user_id;
  894. char *strPtr = 0;
  895. char WebPassword[MAX_WEB_PASSWD_LEN];
  896. char WebLogin[MAX_WEB_LOGIN_LEN];
  897. char buf[40];
  898. memset(login, 0, 20);
  899. memset(password, 0, 20);
  900. memset(tempStr, 0, 50);
  901. /* Get first 50 bytes of string */
  902. strncpy(tempStr, bufIn, 49);
  903. /* Add " " to the string in order GetParamValue() can be able to parse the param */
  904. strcat(tempStr, " ");
  905. if (GetParamValue(tempStr, "login=", login, &valueLen) &&
  906. GetParamValue(tempStr, "password=", password, &valueLen))
  907. {
  908. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  909. GetUserLogin(user_id, WebLogin, &valueLen);
  910. GetUserPassword(user_id, WebPassword, &valueLen);
  911. /* Check login and password */
  912. if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
  913. (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
  914. /* Login and pass are valid */
  915. /* Check user's login session */
  916. /* If "user" has logged in */
  917. if (user_id >= 1) {
  918. }
  919. /* TODO replace global flag with user-pass-cookie */
  920. Authenticated = true;
  921. /* Generate cookie */
  922. sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
  923. /* Set users cookie */
  924. HTTP_SetUserCookie(tempStr, user_id);
  925. HTTP_UpdateUserLoginTime(user_id);
  926. /* Send login and cookie back */
  927. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
  928. strcat(bufOut, WebLogin);
  929. strcat(bufOut, "\r\nSet-Cookie: id=");
  930. strcat(bufOut, tempStr);
  931. sprintf(tempStr, "%d", user_id);
  932. strcat(bufOut, "\r\nSet-Cookie: role=");
  933. strcat(bufOut, tempStr);
  934. strcat(bufOut, "\r\n\r\n");
  935. strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
  936. *lenBufOut = strlen(bufOut);
  937. switch (user_id) {
  938. case 0:
  939. snprintf(buf, sizeof(buf), "Администратор");
  940. break;
  941. case 1:
  942. snprintf(buf, sizeof(buf), "Пользователь");
  943. break;
  944. default:
  945. snprintf(buf, sizeof(buf), "", login);
  946. break;
  947. }
  948. /* Запускаем задачу-таймер логаута. */
  949. /* TODO отправить ответ серверу о статусе пароля */
  950. return SEND_REQUIRED_YES;
  951. }
  952. /*
  953. else {
  954. continue;
  955. }
  956. */
  957. }
  958. }
  959. /* No valid login and pass found */
  960. /* TODO replace global flag with user-pass-cookie*/
  961. Authenticated = false;
  962. /* Wrong login or pass, return */
  963. return SEND_REQUIRED_NO;
  964. }
  965. /**
  966. * @brief
  967. * @retval None
  968. */
  969. uint8_t GetParamValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  970. {
  971. char *beginValue = 0;
  972. char *endValue = 0;
  973. int len = 0;
  974. char *strPtr = 0;
  975. strPtr = strstr(inStr, paramName);
  976. if (strPtr != 0)
  977. {
  978. beginValue = strpbrk(strPtr,"=");
  979. endValue = strpbrk(strPtr,"&");
  980. if (endValue == 0)
  981. endValue = strpbrk(strPtr," ");
  982. len = endValue - beginValue - 1;
  983. strncpy(paramValue, beginValue + 1, len);
  984. *endValue = '0';
  985. *beginValue = '0';
  986. *paramLen = len;
  987. return 1;
  988. }
  989. else
  990. {
  991. *paramLen = 0;
  992. return 0;
  993. }
  994. }
  995. /**
  996. * @brief
  997. * @retval None
  998. */
  999. uint8_t GetCookieValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  1000. {
  1001. char *beginValue = 0;
  1002. char *endValue = 0;
  1003. int len = 0;
  1004. char *strPtr = 0;
  1005. strPtr = strstr(inStr, paramName);
  1006. if (strPtr != 0)
  1007. {
  1008. beginValue = strpbrk(strPtr,"=");
  1009. endValue = strpbrk(strPtr,";");
  1010. if (endValue == 0)
  1011. endValue = strpbrk(strPtr,"\n");
  1012. len = endValue - beginValue - 1;
  1013. strncpy(paramValue, beginValue + 1, len);
  1014. *endValue = '0';
  1015. *beginValue = '0';
  1016. *paramLen = len;
  1017. return 1;
  1018. }
  1019. else
  1020. {
  1021. *paramLen = 0;
  1022. return 0;
  1023. }
  1024. }
  1025. /**
  1026. * @brief
  1027. * @retval None
  1028. */
  1029. /*
  1030. uint8_t GetParamValueInEnd(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  1031. {
  1032. char *beginValue = 0;
  1033. char *endValue = 0;
  1034. int len = 0;
  1035. char *strPtr = 0;
  1036. strPtr = strstr(inStr, paramName);
  1037. if (strPtr != 0)
  1038. {
  1039. beginValue = strpbrk(strPtr,"=");
  1040. endValue = strpbrk(strPtr," ");
  1041. len = endValue - beginValue - 1;
  1042. strncpy(paramValue, beginValue + 1, len);
  1043. *endValue = '0';
  1044. *beginValue = '0';
  1045. *paramLen = len;
  1046. return 1;
  1047. }
  1048. else
  1049. {
  1050. *paramLen = 0;
  1051. return 0;
  1052. }
  1053. }
  1054. */
  1055. void ClearParamString(char *inBuf)
  1056. {
  1057. uint16_t len;
  1058. char *str;
  1059. str = strstr(inBuf, "HTTP");
  1060. if (str != 0)
  1061. {
  1062. len = str - inBuf;
  1063. memset(str, 0, RECIVE_BUF_MAX_LEN - len - 1);
  1064. }
  1065. }
  1066. /**
  1067. * @brief Замена символа в строке
  1068. * @param *str - входная строка
  1069. * @param sim1 - символ который надо заменить
  1070. * @param sim2 - символ на который надо заменить
  1071. */
  1072. void HTTP_ReplaceSimbol(char *str, char sim1, char sim2)
  1073. {
  1074. uint16_t len = strlen(str);
  1075. for (uint16_t i = 0; i < len; i++)
  1076. {
  1077. if (*str == sim1)
  1078. *str = sim2;
  1079. str++;
  1080. }
  1081. }
  1082. /**
  1083. * @brief Чтение Cookie пользователя
  1084. */
  1085. static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len)
  1086. {
  1087. sprintf(str, "%s", users[user_id].cookie);
  1088. *len = strlen(str);
  1089. }
  1090. /**
  1091. * @brief Установка Cookie пользователя
  1092. */
  1093. static void HTTP_SetUserCookie(char *str, uint8_t user_id)
  1094. {
  1095. strcpy(users[user_id].cookie, str);
  1096. }
  1097. /**
  1098. * @brief Обновление времени последней активности пользователя
  1099. */
  1100. static void HTTP_UpdateUserLoginTime(uint8_t user_id)
  1101. {
  1102. xTimerStart(users[user_id].LogoutTimer, 0);
  1103. }
  1104. /**
  1105. * @brief Extract the Content_Length data from HTML data
  1106. * @param data : pointer on receive packet buffer
  1107. * @param len : buffer length
  1108. * @retval size : Content_length in numeric format
  1109. */
  1110. static uint32_t Parse_Content_Length(char *data, uint32_t len)
  1111. {
  1112. uint32_t i=0,size=0, S=1;
  1113. int32_t j=0;
  1114. char sizestring[6], *ptr;
  1115. ContentLengthOffset =0;
  1116. /* find Content-Length data in packet buffer */
  1117. for (i=0;i<len;i++)
  1118. {
  1119. if (strncmp ((char*)(data+i), Content_Length, 16)==0)
  1120. {
  1121. ContentLengthOffset = i+16;
  1122. break;
  1123. }
  1124. }
  1125. /* read Content-Length value */
  1126. if (ContentLengthOffset)
  1127. {
  1128. i=0;
  1129. ptr = (char*)(data + ContentLengthOffset);
  1130. while(*(ptr+i)!=0x0d)
  1131. {
  1132. sizestring[i] = *(ptr+i);
  1133. i++;
  1134. ContentLengthOffset++;
  1135. }
  1136. if (i>0)
  1137. {
  1138. /* transform string data into numeric format */
  1139. for(j=i-1;j>=0;j--)
  1140. {
  1141. size += (sizestring[j]-0x30)*S;
  1142. S=S*10;
  1143. }
  1144. }
  1145. }
  1146. return size;
  1147. }
  1148. /**
  1149. * @brief Принудительный логаут пользователя
  1150. */
  1151. static void HTTP_ForceUserLogout(uint8_t user_id)
  1152. {
  1153. char cookie[MAX_WEB_COOKIE_LEN];
  1154. /* Flush user cookie by random value */
  1155. sprintf(cookie, "%X", (unsigned int)GetRandomNumber());
  1156. HTTP_SetUserCookie(cookie, user_id);
  1157. }
  1158. /**
  1159. * @brief >Callback таймера логаута пользователя
  1160. */
  1161. void LogoutTimerCallback(TimerHandle_t pxTimer) {
  1162. uint8_t user_id = (uint8_t)pvTimerGetTimerID( pxTimer );
  1163. HTTP_ForceUserLogout(user_id);
  1164. }