http_server.c 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391
  1. #include "lwip/arch.h"
  2. #include "lwip/api.h"
  3. #include "lwip/tcp.h"
  4. #include "common_config.h"
  5. #ifdef HTTP_SERVER_ENABLE
  6. #include "http_server.h"
  7. #include "web_params_api.h"
  8. #include "parameters.h"
  9. #include "urlcode.h"
  10. #ifdef HARDWARE_BT6707
  11. #include "bt6707_fs/fsdata.c"
  12. #elif HARDWARE_BT6709
  13. #include "bt6709_fs/fsdata.c"
  14. #elif HARDWARE_BT6709_MTS
  15. #include "bt6709_mts_fs/fsdata.c"
  16. #elif HARDWARE_BT6710
  17. #include "bt6710_fs/fsdata.c"
  18. #elif HARDWARE_BT6711 || HARDWARE_BT6711_V1
  19. #include "bt6711_fs/fsdata.c"
  20. #elif HARDWARE_BT6721
  21. #include "bt6721_fs/fsdata.c"
  22. #endif
  23. #ifdef FTP_ENABLE
  24. #include "ftp.h"
  25. #endif // FTP_ENABLE
  26. #include "settings_api.h"
  27. #include "netconf.h"
  28. #include "testing.h"
  29. #include "rtc.h"
  30. #include "rng.h"
  31. #include "megatec.h"
  32. #include "log.h"
  33. #include "hal.h"
  34. #include "sntp_api.h"
  35. #ifdef RADIUS_SERVER_ENABLE
  36. #include "radius_user.h"
  37. #endif
  38. #ifdef PRINTF_STDLIB
  39. #include <stdio.h>
  40. #endif
  41. #ifdef PRINTF_CUSTOM
  42. #include "tinystdio.h"
  43. #endif
  44. #include <string.h>
  45. #include <stdlib.h>
  46. #include "FreeRTOS.h"
  47. #include "task.h"
  48. #include "fr_timers.h"
  49. static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err);
  50. static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
  51. static int fs_open(char *name, struct fs_file *file);
  52. static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len);
  53. static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len);
  54. static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len);
  55. static void http_err(void *arg, err_t err);
  56. static void http_sent_log_err(void *arg, err_t err);
  57. static void send_data(struct tcp_pcb *pcb, struct http_state *hs);
  58. #ifdef HTTP_AUTH_ENABLE
  59. static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len);
  60. static void HTTP_SetUserCookie(char *str, uint8_t user_id);
  61. static void HTTP_UpdateUserLoginTime(uint8_t user_id);
  62. static void HTTP_ForceUserLogout(uint8_t user_id);
  63. void LogoutTimerCallback(TimerHandle_t pxTimer);
  64. void LoginTimerCallback(TimerHandle_t pxTimer);
  65. static void getAuthenticatedState(void);
  66. #endif
  67. static uint32_t Parse_Content_Length(char *data, uint32_t len);
  68. char *send_file(char *filename, char *pnonmatch, struct fs_file *file, uint16_t *Len);
  69. static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value);
  70. bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen);
  71. static char *HTTP_FTPFWUpdate(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
  72. static char *HTTP_FTPFWState(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
  73. #define NUM_LOCKS 3
  74. static void *locks[NUM_LOCKS];
  75. char sendBuf[SEND_BUF_MAX_LEN];
  76. uint16_t sendBufLoadLen = 0;
  77. uint16_t printLen = 0;
  78. char receiveBuf[RECIVE_BUF_MAX_LEN];
  79. uint16_t receivedBufLen = 0;
  80. #ifdef HTTP_AUTH_ENABLE
  81. #define MAX_POST_REQ_LEN 256
  82. char post_req_data[MAX_POST_REQ_LEN];
  83. uint32_t post_data_count = 0;
  84. uint32_t log_post_reqn;
  85. /* Logout timeout, 30 minutes */
  86. #define WEB_LOGOUT_TIME configTICK_RATE_HZ*60*30
  87. /* Max user active sessions count */
  88. #define WEB_USER_MAX_SESSION_COUNT 5
  89. struct {
  90. //auth_session_t session[WEB_USER_MAX_SESSION_COUNT];
  91. char cookie[MAX_WEB_COOKIE_LEN];
  92. TimerHandle_t LogoutTimer;
  93. } users[MAX_WEB_USERS];
  94. TimerHandle_t RepeatLoginTimer;
  95. /* Repeat Login timeout, 1 minutes */
  96. #define REPEAT_LOGIN_TIME configTICK_RATE_HZ*60*1
  97. uint8_t cnt_err_psw = 0;
  98. bool Authenticated = false;
  99. uint8_t user_id = 0; // Id of currently logged-in user
  100. /* Level of currently logged-in user */
  101. uint8_t seclevel = 0xFF;
  102. #endif
  103. /* Max HTTP file name length including "/" */
  104. #define MAX_FILENAME_LEN 32
  105. /* Max HTTP Etag field length */
  106. #define MAX_ETAG_LEN 48
  107. static const char If_None_Match[] = "If-None-Match: ";
  108. static const char Etag[] = "ETag: ";
  109. static volatile uint32_t DataFlag2 = 0;
  110. static volatile uint32_t DataFlag = 0;
  111. static volatile uint32_t size = 0;
  112. static uint32_t TotalReceived = 0;
  113. static volatile uint32_t TotalData = 0;
  114. static uint32_t ContentLengthOffset = 0;
  115. static const char Content_Length[17] =
  116. /* Content Length */
  117. {0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, };
  118. const char HTTP_304_NOT_MODIFIED[] = "HTTP/1.1 304 Not Modified\r\n\r\n";
  119. const char HTTP_401_NO_AUTH[] = "HTTP/1.1 401 No authorization\r\n\r\n";
  120. const char HTTP_403_NOT_WHITE_LIST[] = "HTTP/1.1 403 Forbidden\r\n\r\n";
  121. const char HTTP_500_SERVER_ERROR[] = "HTTP/1.1 500 Internal Server Error\r\n\r\n";
  122. const char HTTP_200_OK[] = "HTTP/1.1 200 OK\r\n\r\n";
  123. /* utf-8 marker to support MS Excel */
  124. const char UTF8_BOM[] = {0xEF, 0xBB, 0xBF, 0x00};
  125. const char REFRESH_LOGIN_PAGE[] = "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/login.html\"/></head></html>\r\n";
  126. const char REFRESH_RS_LOGIN_PAGE[] = "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/rslogin.html\"/></head></html>\r\n";
  127. unsigned long log_ptr = 0;
  128. unsigned long log_size = 0;
  129. bool fLogTransInprog = false;
  130. #ifdef RADIUS_SERVER_ENABLE
  131. void auth_task(void *pvParameters);
  132. static bool fl_raddius_net_err = false;
  133. typedef enum
  134. {
  135. RS_AUTH_READY = 0,
  136. RS_AUTH_PROCESS,
  137. RS_AUTH_FINISH,
  138. MAX_RS_AUTH_STATE
  139. } rs_auth_state_t;
  140. static uint8_t auth_flag = RS_AUTH_READY;
  141. static char sendAuthBuf[500];
  142. #endif
  143. /**
  144. * @brief Общая структура настроек
  145. */
  146. extern SETTINGS_t sSettings;
  147. struct fs_file file = {0, 0};
  148. typedef struct {
  149. char client_req[30];
  150. uint8_t len;
  151. REQ_TYPE_SEND_t req_type_send;
  152. ACCESS_TYPE_t accsess;
  153. char *(*handler)(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut);
  154. } web_func_handler_t;
  155. #define X(x) (x), sizeof(x) - 1
  156. // TODO Xify all the list like ftp_fw_update!
  157. web_func_handler_t process_web_funcs[] = {
  158. #ifdef HTTP_AUTH_ENABLE
  159. { "POST /login.cgi", 15, COMMON_ANSWER, ALL_ACCESS, HTTP_LoginPage },
  160. { "GET /logout.cgi", 15, COMMON_ANSWER, TIME_ACCESS, HTTP_LogoutPage },
  161. { "GET /changepwd.cgi", 18, COMMON_ANSWER, TIME_ACCESS, HTTP_ChangeUserPwd },
  162. #endif
  163. { "GET /getJson.cgi", 16, COMMON_ANSWER, TIME_ACCESS, HTTP_GetParamsPage },
  164. { "GET /settings.cgi", 17, COMMON_ANSWER, TIME_ACCESS, HTTP_GetSettingsPage },
  165. { "POST /settings.cgi", 18, COMMON_ANSWER, TIME_ACCESS, HTTP_SetSettingsPage },
  166. #ifdef NOTIFICATION_CONTROL_ENABLE
  167. { "GET /snmp.cgi", 13, COMMON_ANSWER, TIME_ACCESS, HTTP_SnmpParam },
  168. #endif
  169. { "GET /info.cgi", 13, COMMON_ANSWER, TIME_ACCESS, HTTP_GetInfo },
  170. { "POST /info.cgi", 14, COMMON_ANSWER, TIME_ACCESS, HTTP_SetInfoPage },
  171. { "GET /history.cgi?page=all", 25, HISTORY_ANSWER, TIME_ACCESS, HTTP_HistoryPage },
  172. { "GET /history.cgi", 16, COMMON_ANSWER, TIME_ACCESS, HTTP_HistoryPage },
  173. { "GET /ups_history.cgi?page=all", 29, UPS_HISTORY_ANSWER, TIME_ACCESS, HTTP_UpsHistoryPage },
  174. { "GET /ups_history.cgi", 20, COMMON_ANSWER, TIME_ACCESS, HTTP_UpsHistoryPage },
  175. { "GET /reset.cgi", 14, COMMON_ANSWER, TIME_ACCESS, HTTP_Reset },
  176. { "GET /bat_test.cgi", 17, COMMON_ANSWER, TIME_ACCESS, HTTP_UPSTest },
  177. { "GET /ups_power.cgi", 18, COMMON_ANSWER, TIME_ACCESS, HTTP_UPSshutdown },
  178. { "GET /reboot.cgi", 15, COMMON_ANSWER, TIME_ACCESS, HTTP_Reboot },
  179. { "GET /confirm.cgi", 16, COMMON_ANSWER, TIME_ACCESS, HTTP_Confirm },
  180. { "GET /fw_update.cgi", 18, COMMON_ANSWER, TIME_ACCESS, HTTP_ConfirmBootPwd },
  181. #ifdef FTP_ENABLE
  182. { X("POST /ftp_fw_update.cgi"), COMMON_ANSWER, TIME_ACCESS, HTTP_FTPFWUpdate },
  183. { X("GET /fw_dl_state.cgi"), COMMON_ANSWER, TIME_ACCESS, HTTP_FTPFWState },
  184. #endif // FTP_ENABLE
  185. { "GET", 3, COMMON_ANSWER, ALL_ACCESS, HTTP_GetRequest },
  186. { "", 0, COMMON_ANSWER, ALL_ACCESS, HTTP_NoFound },
  187. { "", 0, 0, 0, NULL }
  188. };
  189. #undef X
  190. static bool lock_buf(struct http_state *hs, void *buf)
  191. {
  192. /* Check if already locked */
  193. for (uint8_t i = 0; i < NUM_LOCKS; i++) {
  194. if (locks[i] == buf) {
  195. DBG printf("[%p lock error]\r\n", buf);
  196. return false;
  197. }
  198. }
  199. /* Lock */
  200. for (uint8_t i = 0; i < NUM_LOCKS; i++) {
  201. if (locks[i] == NULL) {
  202. locks[i] = buf;
  203. hs->locked = buf;
  204. DBG printf("[%p locked]\r\n", buf);
  205. return true;
  206. }
  207. }
  208. DBG printf("no free locks\r\n");
  209. return false;
  210. }
  211. static bool unlock_buf(void *buf)
  212. {
  213. for (uint8_t i = 0; i < NUM_LOCKS; i++) {
  214. if (locks[i] == buf) {
  215. DBG printf("[%p unlocked]\r\n", buf);
  216. locks[i] = NULL;
  217. }
  218. }
  219. return true;
  220. }
  221. /**
  222. * @brief closes tcp connection
  223. * @param pcb: pointer to a tcp_pcb struct
  224. * @param hs: pointer to a http_state struct
  225. * @retval
  226. */
  227. static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
  228. {
  229. tcp_arg(pcb, NULL);
  230. tcp_sent(pcb, NULL);
  231. tcp_recv(pcb, NULL);
  232. tcp_poll(pcb, NULL, 0);
  233. if (hs->locked != 0) {
  234. unlock_buf(hs->locked);
  235. }
  236. mem_free(hs);
  237. err_t err = tcp_close(pcb);
  238. DBG printf("%p close = %d (pcb: %d, pbuf_pool: %d)\r\n", pcb, err,
  239. lwip_stats.memp[MEMP_TCP_PCB]->used,
  240. lwip_stats.memp[MEMP_PBUF_POOL]->used);
  241. }
  242. /**
  243. * @brief callback function for handling TCP HTTP traffic
  244. * @param arg: pointer to an argument structure to be passed to callback function
  245. * @param pcb: pointer to a tcp_pcb structure
  246. * @param p: pointer to a packet buffer
  247. * @param err: LwIP error code
  248. * @retval err
  249. */
  250. static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
  251. {
  252. char *data;
  253. struct http_state *hs;
  254. web_func_handler_t *h;
  255. hs = arg;
  256. if (GetRebootStatus() == true) {;
  257. Reboot(WEB_ACT);
  258. }
  259. if (err == ERR_OK && p != NULL) {
  260. tcp_recved(pcb, p->tot_len);
  261. if (hs->file == NULL) {
  262. data = p->payload;
  263. receivedBufLen = p->tot_len;
  264. memcpy(receiveBuf, p->payload, receivedBufLen);
  265. /* Cut received string */
  266. receiveBuf[receivedBufLen] = '\0';
  267. if (strncmp(data, "GET /setProdate.cgi", 19) == 0 && strncmp(sSettings.sFlags.testState, "T2OK", 4)) {
  268. HTTP_Prodate(hs->reqnum, receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  269. hs->file = sendBuf;
  270. hs->left = sendBufLoadLen;
  271. send_data(pcb, hs);
  272. tcp_sent(pcb, http_sent);
  273. } else {
  274. if (DataFlag2 >= 1) {
  275. hs->file = HTTP_SetSettingsPage(hs->reqnum, receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  276. hs->left = sendBufLoadLen;
  277. send_data(pcb, hs);
  278. tcp_sent(pcb, http_sent);
  279. } else if (DataFlag >= 1) {
  280. hs->file = HTTP_SetInfoPage(hs->reqnum, receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  281. hs->left = sendBufLoadLen;
  282. send_data(pcb, hs);
  283. tcp_sent(pcb, http_sent);
  284. }
  285. #ifdef HTTP_AUTH_ENABLE
  286. else if (log_post_reqn > 0 || post_data_count > 0) {
  287. hs->file = HTTP_LoginPage(hs->reqnum, receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  288. hs->left = sendBufLoadLen;
  289. send_data(pcb, hs);
  290. tcp_sent(pcb, http_sent);
  291. }
  292. #endif
  293. else {
  294. #ifdef HTTP_AUTH_ENABLE
  295. getAuthenticatedState();
  296. #endif
  297. for (h = &process_web_funcs[0]; h->handler; h++) {
  298. if (strncmp(data, h->client_req, h->len) == 0) {
  299. /* Skip common GET request (static files) - RAM buffers not used */
  300. if (h->handler != HTTP_GetRequest) {
  301. if (!lock_buf(hs, sendBuf)) {
  302. DBG printf("Server is busy!\r\n");
  303. /* TODO: Close connection or send error? */
  304. #if 0
  305. pbuf_free(p);
  306. close_conn(pcb, hs);
  307. return ERR_OK;
  308. #endif
  309. hs->file = (char *)HTTP_500_SERVER_ERROR;
  310. hs->left = strlen(HTTP_500_SERVER_ERROR);
  311. send_data(pcb, hs);
  312. tcp_sent(pcb, http_sent);
  313. pbuf_free(p);
  314. return ERR_OK;
  315. }
  316. }
  317. #ifdef HTTP_LOCK_ENABLE
  318. if (h->accsess == TIME_ACCESS) {
  319. uint32_t locked = 0;
  320. GetLockStateInt(&locked);
  321. if (locked) {
  322. hs->file = (char *)HTTP_403_FORBIDDEN;
  323. hs->left = strlen(HTTP_403_FORBIDDEN);
  324. send_data(pcb, hs);
  325. tcp_sent(pcb, http_sent);
  326. tcp_err(pcb, http_err);
  327. pbuf_free(p);
  328. return ERR_OK;
  329. }
  330. }
  331. #endif
  332. #ifdef HTTP_AUTH_ENABLE
  333. if (h->accsess == TIME_ACCESS && !Authenticated) {
  334. strcpy(sendBuf, HTTP_401_NO_AUTH);
  335. #ifdef RADIUS_SERVER_ENABLE
  336. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  337. strcat(sendBuf, REFRESH_RS_LOGIN_PAGE);
  338. else
  339. #endif
  340. strcat(sendBuf, REFRESH_LOGIN_PAGE);
  341. sendBufLoadLen = strlen(sendBuf);
  342. hs->file = sendBuf;
  343. hs->left = sendBufLoadLen;
  344. send_data(pcb, hs);
  345. tcp_sent(pcb, http_sent);
  346. tcp_err(pcb, http_err);
  347. pbuf_free(p);
  348. return ERR_OK;
  349. }
  350. #endif
  351. hs->file = h->handler(hs->reqnum, receiveBuf, sendBuf, receivedBufLen, &sendBufLoadLen);
  352. hs->left = sendBufLoadLen;
  353. if (hs->file == 0) {
  354. unlock_buf(sendBuf);
  355. }
  356. if (hs->file != 0) {
  357. send_data(pcb, hs);
  358. switch (h->req_type_send) {
  359. case PARAMETER_ANSWER:
  360. //tcp_sent(pcb, http_sent_param_page);
  361. tcp_err(pcb, http_err);
  362. break;
  363. case HISTORY_ANSWER:
  364. tcp_sent(pcb, http_sent_history);
  365. tcp_err(pcb, http_sent_history);
  366. break;
  367. case UPS_HISTORY_ANSWER:
  368. tcp_sent(pcb, http_sent_log);
  369. tcp_err(pcb, http_sent_log_err);
  370. break;
  371. default:
  372. tcp_sent(pcb, http_sent);
  373. tcp_err(pcb, http_err);
  374. break;
  375. }
  376. } else if (DataFlag > 0 || DataFlag2 > 0
  377. || log_post_reqn > 0 || post_data_count > 0) {
  378. /* Skip request without data (headers only were received) */
  379. break;
  380. } else {
  381. close_conn(pcb, hs);
  382. }
  383. break;
  384. }
  385. }
  386. }
  387. }
  388. }
  389. pbuf_free(p);
  390. }
  391. return ERR_OK;
  392. }
  393. /**
  394. * @brief Sent callback for log file transfer (messages as is, not ordered)
  395. */
  396. static err_t http_sent_history(void *arg, struct tcp_pcb *pcb, u16_t len)
  397. {
  398. struct http_state *hs;
  399. uint32_t nbytes = 0;
  400. static bool start = true;
  401. (void)len;
  402. hs = arg;
  403. if (hs->left > 0) {
  404. send_data(pcb, hs);
  405. } else {
  406. /* Release previously used send buffer to use
  407. * separate file transfer buffer (logFileBuf) */
  408. if (hs->locked != 0) {
  409. unlock_buf(hs->locked);
  410. }
  411. memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
  412. if (log_ptr + FILE_BUF_MAX_LEN <= log_size) {
  413. nbytes = History_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN, start);
  414. } else if (log_ptr < log_size) {
  415. nbytes = History_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
  416. } else {
  417. nbytes = 0;
  418. }
  419. log_ptr += nbytes;
  420. start = false;
  421. if (nbytes == 0) {
  422. /* File transfer finished. */
  423. start = true;
  424. close_conn(pcb, hs);
  425. /* Clear file transfer in progress flag */
  426. fLogTransInprog = false;
  427. return ERR_OK;
  428. }
  429. hs->file = logFileBuf;
  430. hs->left = nbytes;
  431. send_data(pcb, hs);
  432. tcp_sent(pcb, http_sent_history);
  433. }
  434. return ERR_OK;
  435. }
  436. /**
  437. * @brief Sent callback for log file transfer (messages as is, not ordered)
  438. */
  439. static err_t http_sent_log(void *arg, struct tcp_pcb *pcb, u16_t len)
  440. {
  441. struct http_state *hs;
  442. uint32_t nbytes = 0;
  443. static bool start = true;
  444. (void)len;
  445. hs = arg;
  446. if (hs->left > 0) {
  447. send_data(pcb, hs);
  448. } else {
  449. /* Release previously used send buffer to use
  450. * separate file transfer buffer (logFileBuf) */
  451. if (hs->locked != 0) {
  452. unlock_buf(hs->locked);
  453. }
  454. memset(logFileBuf, 0, FILE_BUF_MAX_LEN);
  455. if (log_ptr + FILE_BUF_MAX_LEN_LOG <= log_size) {
  456. nbytes = LOG_GetData(log_ptr, logFileBuf, FILE_BUF_MAX_LEN_LOG, start);
  457. } else if (log_ptr < log_size) {
  458. nbytes = LOG_GetData(log_ptr, logFileBuf, (log_size - log_ptr), start);
  459. } else {
  460. nbytes = 0;
  461. }
  462. log_ptr += nbytes;
  463. start = false;
  464. if (nbytes == 0) {
  465. /* File transfer finished. */
  466. start = true;
  467. close_conn(pcb, hs);
  468. /* Clear file transfer in progress flag */
  469. fLogTransInprog = false;
  470. return ERR_OK;
  471. }
  472. hs->file = logFileBuf;
  473. hs->left = nbytes;
  474. send_data(pcb, hs);
  475. tcp_sent(pcb, http_sent_log);
  476. }
  477. return ERR_OK;
  478. }
  479. /**
  480. * @brief Error callback for log file transfer
  481. */
  482. static void http_sent_log_err(void *arg, err_t err)
  483. {
  484. (void)err;
  485. (void)arg;
  486. /* Clear file transfer in progress flag */
  487. fLogTransInprog = false;
  488. }
  489. /**
  490. * @brief callback function for handling connection errors
  491. * @param arg: pointer to an argument to be passed to callback function
  492. * @param err: LwIP error code
  493. * @retval none
  494. */
  495. static void conn_err(void *arg, err_t err)
  496. {
  497. struct http_state *hs;
  498. (void)err;
  499. hs = arg;
  500. mem_free(hs);
  501. }
  502. /**
  503. * @brief callback function called after a successfull TCP data packet transmission
  504. * @param arg: pointer to an argument to be passed to callback function
  505. * @param pcb: pointer on tcp_pcb structure
  506. * @param len
  507. * @retval err : LwIP error code
  508. */
  509. static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
  510. {
  511. struct http_state *hs;
  512. (void)len;
  513. hs = arg;
  514. if (hs->left > 0) {
  515. send_data(pcb, hs);
  516. } else {
  517. close_conn(pcb, hs);
  518. }
  519. return ERR_OK;
  520. }
  521. /**
  522. * @brief Error callback for common http transfer
  523. */
  524. static void http_err(void *arg, err_t err)
  525. {
  526. struct http_state *hs;
  527. (void)err;
  528. (void)arg;
  529. hs = arg;
  530. DBG printf("http_err (%d): hs: %p\r\n", err, hs);
  531. if (hs->locked != 0) {
  532. unlock_buf(hs->locked);
  533. }
  534. mem_free(hs);
  535. }
  536. /**
  537. * @brief sends data found in member "file" of a http_state struct
  538. * @param pcb: pointer to a tcp_pcb struct
  539. * @param hs: pointer to a http_state struct
  540. * @retval none
  541. */
  542. static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
  543. {
  544. err_t err;
  545. u16_t len;
  546. /* We cannot send more data than space available in the send
  547. buffer */
  548. if (tcp_sndbuf(pcb) < hs->left) {
  549. len = tcp_sndbuf(pcb);
  550. } else {
  551. len = hs->left;
  552. }
  553. err = tcp_write(pcb, hs->file, len, 0);
  554. if (err == ERR_OK) {
  555. hs->file += len;
  556. hs->left -= len;
  557. }
  558. }
  559. /**
  560. * @brief tcp poll callback function
  561. * @param arg: pointer to an argument to be passed to callback function
  562. * @param pcb: pointer on tcp_pcb structure
  563. * @retval err_t
  564. */
  565. static err_t http_poll(void *arg, struct tcp_pcb *pcb)
  566. {
  567. if (arg == NULL) {
  568. tcp_close(pcb);
  569. } else {
  570. send_data(pcb, (struct http_state *)arg);
  571. }
  572. return ERR_OK;
  573. }
  574. /**
  575. * @brief callback function on TCP connection setup ( on port 80)
  576. * @param arg: pointer to an argument structure to be passed to callback function
  577. * @param pcb: pointer to a tcp_pcb structure
  578. * &param err: Lwip stack error code
  579. * @retval err
  580. */
  581. static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
  582. {
  583. struct http_state *hs;
  584. (void)arg;
  585. (void)err;
  586. /* set priority for the newly accepted tcp connection newpcb */
  587. tcp_setprio(pcb, TCP_PRIO_MIN);
  588. /* Allocate memory for the structure that holds the state of the connection */
  589. hs = mem_malloc(sizeof(struct http_state));
  590. if (hs == NULL) {
  591. return ERR_MEM;
  592. }
  593. /* Initialize the structure. */
  594. hs->file = NULL;
  595. hs->left = 0;
  596. hs->reqnum = 0;
  597. hs->locked = NULL;
  598. /* Tell TCP that this is the structure we wish to be passed for our
  599. callbacks. */
  600. tcp_arg(pcb, hs);
  601. /* Tell TCP that we wish to be informed of incoming data by a call
  602. to the http_recv() function. */
  603. tcp_recv(pcb, http_recv);
  604. tcp_err(pcb, conn_err);
  605. tcp_poll(pcb, http_poll, 10);
  606. return ERR_OK;
  607. }
  608. /**
  609. * @brief Opens a file defined in fsdata.c ROM filesystem
  610. * @param name : pointer to a file name
  611. * @param file : pointer to a fs_file structure
  612. * @retval 1 if success, 0 if fail
  613. */
  614. static int fs_open(char *name, struct fs_file *file)
  615. {
  616. struct fsdata_file_noconst *f;
  617. for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next) {
  618. if (!strcmp(name, f->name)) {
  619. file->data = f->data;
  620. file->len = f->len;
  621. return 1;
  622. }
  623. }
  624. return 0;
  625. }
  626. /**
  627. * @brief Initialize the HTTP server (start its thread)
  628. * @param none
  629. * @retval None
  630. */
  631. void HTTP_Init()
  632. {
  633. err_t err;
  634. struct tcp_pcb *pcb;
  635. #ifdef RADIUS_SERVER_ENABLE
  636. xTaskCreate(auth_task, "auth_task", 4 * configMINIMAL_STACK_SIZE, NULL, ( configMAX_PRIORITIES - 3), NULL);
  637. #endif
  638. /*create new pcb*/
  639. pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
  640. LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL);
  641. /* set lowest prio to HTTP connections */
  642. //tcp_setprio(pcb, TCP_PRIO_MIN);
  643. /* bind HTTP traffic to pcb */
  644. err = tcp_bind(pcb, IP_ANY_TYPE, 80);
  645. LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */
  646. LWIP_ASSERT("httpd_init: tcp_bind failed", err == ERR_OK);
  647. /* start listening on port 80 */
  648. pcb = tcp_listen(pcb);
  649. /* define callback function for TCP connection setup */
  650. tcp_accept(pcb, http_accept);
  651. #ifdef HTTP_AUTH_ENABLE
  652. char buf[MAX_WEB_COOKIE_LEN];
  653. uint8_t user_id;
  654. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  655. /* Flush user cookie by random value */
  656. sprintf(buf, "%X", (unsigned int)GetRandomNumber());
  657. HTTP_SetUserCookie(buf, user_id);
  658. /* Create user logout timers */
  659. users[user_id].LogoutTimer =
  660. xTimerCreate("LogoutTmr", WEB_LOGOUT_TIME, pdFALSE, ( void * ) user_id, LogoutTimerCallback);
  661. }
  662. RepeatLoginTimer = xTimerCreate("LoginTmr", REPEAT_LOGIN_TIME, pdFALSE, ( void * ) 0, LoginTimerCallback);
  663. #endif
  664. }
  665. char *HTTP_HistoryPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  666. {
  667. uint8_t i, valueLen = 0;
  668. char value[20];
  669. (void)lenBufIn;
  670. (void)reqNum;
  671. memset(bufOut, 0, FILE_BUF_MAX_LEN);
  672. ClearParamString(bufIn);
  673. memset(value, 0, 20);
  674. GetParamValue(bufIn, "page", value, &valueLen);
  675. if (strcmp(value, "all") == 0) {
  676. if (!LOG_IsInit()) {
  677. return 0;
  678. }
  679. if (fLogTransInprog == false) {
  680. // Send log as raw data
  681. log_ptr = 0;
  682. log_size = History_GetTotalSTRCount() * STRING_SIZE_HISTORY + sizeof(UTF8_BOM) - 1;
  683. sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM);
  684. *lenBufOut = strlen(bufOut);
  685. // Set file transfer in progress flag
  686. fLogTransInprog = true;
  687. return bufOut;
  688. } else {
  689. // We send nothing if file transfer already in progress
  690. return 0;
  691. }
  692. } else {
  693. if (!LOG_IsInit()) {
  694. return 0;
  695. } else {
  696. HTTP_GetHistoryPage(bufOut, atoi(value));
  697. *lenBufOut = strlen(bufOut);
  698. return bufOut;
  699. }
  700. }
  701. }
  702. char *HTTP_UpsHistoryPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  703. {
  704. uint8_t i, valueLen = 0;
  705. char value[20];
  706. (void)lenBufIn;
  707. (void)reqNum;
  708. memset(bufOut, 0, FILE_BUF_MAX_LEN);
  709. ClearParamString(bufIn);
  710. memset(value, 0, 20);
  711. GetParamValue(bufIn, "page", value, &valueLen);
  712. if (strcmp(value, "all") == 0) {
  713. if (!LOG_IsInit()) {
  714. return 0;
  715. }
  716. if (fLogTransInprog == false) {
  717. // Send log as raw data
  718. log_ptr = 0;
  719. log_size = LOG_GetTotalSTRCount() * STRING_SIZE + sizeof(UTF8_BOM) - 1;
  720. sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Length:%lu\r\n\r\n%s", log_size, UTF8_BOM);
  721. *lenBufOut = strlen(bufOut);
  722. // Set file transfer in progress flag
  723. fLogTransInprog = true;
  724. return bufOut;
  725. } else {
  726. // We send nothing if file transfer already in progress
  727. return 0;
  728. }
  729. } else {
  730. if (!LOG_IsInit()) {
  731. return 0;
  732. } else {
  733. HTTP_GetUpsHistoryPage(bufOut, atoi(value));
  734. *lenBufOut = strlen(bufOut);
  735. return bufOut;
  736. }
  737. }
  738. }
  739. /**
  740. * @brief Установка даты производства
  741. */
  742. // TODO Убрать заглушку!
  743. void HTTP_Prodate(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  744. {
  745. uint8_t valueLen = 0;
  746. char value[20];
  747. (void)lenBufIn;
  748. (void)reqNum;
  749. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  750. ClearParamString(bufIn);
  751. memset(value, 0, 20);
  752. GetParamValue(bufIn, "prodate", value, &valueLen);
  753. /*
  754. printf("Prodate: ");
  755. printf(value);
  756. printf("\r\n");
  757. */
  758. /* Устанавливаем дату производства */
  759. SETTINGS_SetProDate(value, valueLen);
  760. /* Пока отправляем true */
  761. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\nTrue");
  762. *lenBufOut = strlen(bufOut);
  763. TEST_SetServerFlag();
  764. }
  765. /**
  766. * @brief
  767. * @retval None
  768. */
  769. char *HTTP_SetSettingsPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  770. {
  771. char *DataOffset;
  772. (void)reqNum;
  773. if (seclevel == USER) {
  774. return 0;
  775. }
  776. DataOffset = 0;
  777. // POST Packet received
  778. if (DataFlag2 == 0) {
  779. TotalReceived = 0;
  780. memset(bufOut, 0, strlen(bufOut));
  781. bufOut[0] = '0';
  782. // parse packet for Content-length field
  783. size = Parse_Content_Length(bufIn, lenBufIn);
  784. DataOffset = strstr(bufIn, "managerIP");
  785. // case of MSIE8 : we do not receive data in the POST packet
  786. if (DataOffset == 0) {
  787. DataFlag2++;
  788. return 0;
  789. } else {
  790. TotalReceived = lenBufIn - (DataOffset - bufIn);
  791. strncat(bufOut, DataOffset, TotalReceived);
  792. }
  793. }
  794. if (DataFlag2 == 0) {
  795. DataFlag2++;
  796. } else if (DataFlag2 == 1 && TotalReceived == 0) {
  797. /* parse packet for the octet-stream field */
  798. DataOffset = strstr(bufIn, "managerIP");
  799. TotalReceived += lenBufIn;
  800. strncat(bufOut, DataOffset, TotalReceived);
  801. DataFlag2++;
  802. }
  803. /* DataFlag >1 => the packet is data only */
  804. else {
  805. TotalReceived += lenBufIn;
  806. strncat(bufOut, bufIn, lenBufIn);
  807. }
  808. // check if last data packet
  809. if (TotalReceived == size) {
  810. DBG printf("State: Received %u bytes\r\n", (unsigned int)TotalReceived);
  811. // printf("receive %s \r\n", sendBuf);
  812. strncat(bufOut, " ", 1);
  813. HTTP_SetSettings(bufOut, strlen(sendBuf));
  814. memset(sendBuf, 0, size);
  815. DataFlag2 = 0;
  816. strcpy(bufOut, HTTP_200_OK);
  817. strcat(bufOut,
  818. "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/settings.html\"/></head></html>\r\n");
  819. *lenBufOut = strlen(bufOut);
  820. return bufOut;
  821. }
  822. return 0;
  823. }
  824. /**
  825. * @brief
  826. * @retval None
  827. */
  828. void HTTP_SetSettings(char *buf, uint16_t lenBuf)
  829. {
  830. uint8_t valueLen = 0;
  831. const uint8_t len = MAX_WEB_PARAM_LEN;
  832. char value[MAX_WEB_PARAM_LEN];
  833. char str[MAX_WEB_PARAM_LEN];
  834. (void)lenBuf;
  835. //printf(buf);
  836. //ClearParamString(buf);
  837. #define XJSON_SETTINGS_TAG(tag, get_param, set_param) JSON_SET_PARAM(tag, set_param, buf);
  838. WEB_SETTINGS_TAGS_TABLE
  839. #undef XJSON_SETTINGS_CREATE
  840. /* Если параметры WEB изменились выставляем флаг, сохраняем настройки и перезагружаемся */
  841. if (GetStateWebReinit() == true) {
  842. SetWebReinitFlag(true);
  843. HTTP_SaveSettings();
  844. /* Блокируем управление ключем на тау секунд*/
  845. //IO_KeyBlockOn();
  846. vTaskDelay(1010);
  847. Reboot(WEB_ACT);
  848. }
  849. HTTP_SaveSettings();
  850. }
  851. #ifdef NOTIFICATION_CONTROL_ENABLE
  852. /**
  853. * @brief
  854. * @retval None
  855. */
  856. char *HTTP_SnmpParam(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  857. {
  858. char value[8];
  859. uint8_t valueLen;
  860. char tempStr[50];
  861. strncpy(tempStr, bufIn, 50);
  862. (void)reqNum;
  863. /* В запросе нет параметров, нужно формировать JSON ответ */
  864. if (strstr(tempStr, "?_") == NULL) {
  865. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  866. if (seclevel == USER) {
  867. return 0;
  868. }
  869. HTTP_SetNotification(bufIn, lenBufIn);
  870. }
  871. return HTTP_GetTrapAccess(bufIn, lenBufIn, bufOut, lenBufOut);
  872. }
  873. /**
  874. * @brief
  875. * @retval None
  876. */
  877. void HTTP_SetNotification(char *buf, uint16_t lenBuf)
  878. {
  879. uint8_t num_notification, value_notification;
  880. const uint8_t len = 20;
  881. uint16_t len2 = 0, len3 = 0, total_len = 0;
  882. char str[20], value[20];
  883. ClearParamString(buf);
  884. total_len = strcspn(buf, "?") + 1;
  885. lenBuf = strlen(buf);
  886. const uint16_t strend = strcspn(buf, "_");
  887. while (total_len < (strend)) {
  888. memset(value, 0, len);
  889. len2 = strcspn(&buf[total_len], "&");
  890. strncat(value, &buf[total_len], len2);
  891. memset(str, 0, len);
  892. len3 = strcspn(&value[0], "=");
  893. strncat(str, &value[0], (len3));
  894. num_notification = atoi(str);
  895. memset(str, 0, len);
  896. strncat(str, &value[len3 + 1], (len2 - len3 - 1));
  897. value_notification = atoi(str);
  898. SetNotificationFlagsStr(&value_notification, num_notification);
  899. total_len = total_len + strlen(value) + 1;
  900. }
  901. HTTP_SaveSettings();
  902. }
  903. #endif
  904. /**
  905. * @brief
  906. * @retval None
  907. */
  908. char *HTTP_SetInfoPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  909. {
  910. char *DataOffset;
  911. (void)reqNum;
  912. if (seclevel == USER) {
  913. return 0;
  914. }
  915. DataOffset = 0;
  916. // POST Packet received
  917. if (DataFlag == 0) {
  918. TotalReceived = 0;
  919. memset(bufOut, 0, strlen(bufOut));
  920. bufOut[0] = '0';
  921. // parse packet for Content-length field
  922. size = Parse_Content_Length(bufIn, lenBufIn);
  923. DataOffset = strstr(bufIn, "sysname");
  924. // case of MSIE8 : we do not receive data in the POST packet
  925. if (DataOffset == 0) {
  926. DataFlag++;
  927. return 0;
  928. } else {
  929. TotalReceived = lenBufIn - (DataOffset - bufIn);
  930. strncat(bufOut, DataOffset, TotalReceived);
  931. }
  932. }
  933. if (DataFlag == 0) {
  934. DataFlag++;
  935. } else if (DataFlag == 1 && TotalReceived == 0) {
  936. /* parse packet for the octet-stream field */
  937. DataOffset = strstr(bufIn, "sysname");
  938. TotalReceived += lenBufIn;
  939. strncat(bufOut, DataOffset, TotalReceived);
  940. DataFlag++;
  941. }
  942. /* DataFlag >1 => the packet is data only */
  943. else {
  944. TotalReceived += lenBufIn;
  945. strncat(bufOut, bufIn, lenBufIn);
  946. }
  947. // check if last data packet
  948. if (TotalReceived == size) {
  949. strncat(bufOut, " ", 1);
  950. HTTP_SetInfo(bufOut, strlen(bufOut));
  951. DataFlag = 0;
  952. memset(bufOut, 0, size);
  953. strcpy(bufOut, HTTP_200_OK);
  954. strcat(bufOut,
  955. "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/info.html\"/></head></html>\r\n\r\n");
  956. *lenBufOut = strlen(bufOut);
  957. return bufOut;
  958. }
  959. return 0;
  960. }
  961. /**
  962. * @brief
  963. * @retval None
  964. */
  965. void HTTP_SetInfo(char *buf, uint16_t lenBuf)
  966. {
  967. uint8_t valueLen = 0;
  968. const uint8_t len = 110;
  969. char value[330];
  970. char str[110];
  971. (void)lenBuf;
  972. // ClearParamString(buf);
  973. memset(value, 0, len);
  974. /* Название устройства */
  975. GetParamValue(buf, "sysname", value, &valueLen);
  976. url_decode(str, sizeof(str), value);
  977. SetNameDeviceStr(str);
  978. memset(value, 0, len);
  979. /* Владелец */
  980. GetParamValue(buf, "owner", value, &valueLen);
  981. url_decode(str, sizeof(str), value);
  982. SetOwner(str);
  983. memset(value, 0, len);
  984. /* Владелец */
  985. GetParamValue(buf, "sysLocation", value, &valueLen);
  986. url_decode(str, sizeof(str), value);
  987. SetLocation(str);
  988. memset(value, 0, len);
  989. /* Комментарий */
  990. GetParamValue(buf, "comment", value, &valueLen);
  991. url_decode(str, sizeof(str), value);
  992. SetComment(str);
  993. memset(value, 0, len);
  994. HTTP_SaveSettings();
  995. }
  996. char *HTTP_Reset(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  997. {
  998. (void)bufIn;
  999. (void)bufOut;
  1000. (void)lenBufIn;
  1001. (void)reqNum;
  1002. if (seclevel == USER) {
  1003. return 0;
  1004. }
  1005. HTTP_ResetSettings();
  1006. HTTP_SaveSettings();
  1007. fs_open("/settings.html", &file);
  1008. *lenBufOut = file.len;
  1009. return file.data;
  1010. }
  1011. char *HTTP_Confirm(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1012. {
  1013. (void)bufIn;
  1014. (void)bufOut;
  1015. (void)lenBufIn;
  1016. (void)reqNum;
  1017. SetWebReinitFlag(false);
  1018. SetConfirmWebParamsFlag();
  1019. fs_open("/index.html", &file);
  1020. *lenBufOut = file.len;
  1021. return file.data;
  1022. }
  1023. char *HTTP_GetRequest(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1024. {
  1025. (void)bufOut;
  1026. (void)reqNum;
  1027. #ifdef HTTP_AUTH_ENABLE
  1028. const char *html_page_name[] = {
  1029. "/main.css",
  1030. "/rotek.png",
  1031. "/favicon.ico",
  1032. "/role.js"
  1033. };
  1034. #endif
  1035. char filename[MAX_FILENAME_LEN];
  1036. char nonmatch[MAX_ETAG_LEN];
  1037. char *pnonmatch = NULL;
  1038. uint8_t len;
  1039. memset(filename, 0, MAX_FILENAME_LEN);
  1040. if (GetFileName(bufIn, filename, &len)) {
  1041. /* Parce If-Non_Match value */
  1042. #ifdef HTTP_AUTH_ENABLE
  1043. if (!Authenticated) {
  1044. for (uint8_t i = 0; i < 4; i ++) {
  1045. if (strcmp(filename, html_page_name[i]) == 0) {
  1046. break;
  1047. }
  1048. #ifdef RADIUS_SERVER_ENABLE
  1049. if (strcmp(filename, "/check_auth.html") == 0 && auth_flag != RS_AUTH_READY ) {
  1050. if (auth_flag == RS_AUTH_FINISH){
  1051. auth_flag = RS_AUTH_READY;
  1052. } else {
  1053. strcpy(sendAuthBuf, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
  1054. strcat(sendAuthBuf,
  1055. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>Ожидание соединения с RADIUS сервером</h2></center></html>");
  1056. }
  1057. sendBufLoadLen = strlen(sendAuthBuf);
  1058. return sendAuthBuf;
  1059. }
  1060. #endif
  1061. if (i == 3) {
  1062. #ifdef RADIUS_SERVER_ENABLE
  1063. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  1064. strcpy(filename, "/rslogin.html");
  1065. else
  1066. #endif
  1067. strcpy(filename, "/login.html");
  1068. }
  1069. }
  1070. } else {
  1071. HTTP_UpdateUserLoginTime(user_id);
  1072. }
  1073. #endif
  1074. uint8_t nonmatch_len = Parse_Header(bufIn, lenBufIn, lenBufIn, 15, nonmatch);
  1075. if (nonmatch_len < MAX_ETAG_LEN && nonmatch_len > 0) {
  1076. //DBG printf("If_None_Match: %s\r\n", nonmatch);
  1077. pnonmatch = nonmatch;
  1078. }
  1079. return send_file(filename, pnonmatch, &file, lenBufOut);
  1080. }
  1081. return 0;
  1082. }
  1083. char *HTTP_NoFound(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1084. {
  1085. (void)bufIn;
  1086. (void)lenBufIn;
  1087. (void)reqNum;
  1088. if (Authenticated) {
  1089. #ifdef HTTP_AUTH_ENABLE
  1090. HTTP_UpdateUserLoginTime(user_id);
  1091. #endif
  1092. fs_open("/index.html", &file); // +
  1093. *lenBufOut = file.len;
  1094. return file.data;
  1095. } else {
  1096. strcpy(bufOut, HTTP_401_NO_AUTH);
  1097. #ifdef RADIUS_SERVER_ENABLE
  1098. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  1099. strcat(bufOut, REFRESH_RS_LOGIN_PAGE);
  1100. else
  1101. #endif
  1102. strcat(bufOut, REFRESH_LOGIN_PAGE);
  1103. *lenBufOut = strlen(bufOut);
  1104. return bufOut;
  1105. }
  1106. }
  1107. /**
  1108. * @brief Запуск/останов теста UPS
  1109. */
  1110. char *HTTP_UPSTest(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1111. {
  1112. uint8_t valueLen = 0;
  1113. char tempValue[20];
  1114. char tempValue2[20];
  1115. int8_t res = 0;
  1116. char log_string[50];
  1117. (void)lenBufIn;
  1118. (void)reqNum;
  1119. if (seclevel == USER) {
  1120. return 0;
  1121. }
  1122. memset(tempValue, 0, 20);
  1123. memset(tempValue2, 0, 20);
  1124. memset(log_string, 0, 50);
  1125. strcpy(bufOut, HTTP_200_OK);
  1126. GetParamValue(bufIn, "func", tempValue, &valueLen);
  1127. if (strcmp(tempValue, "stop") == 0) {
  1128. res = ups_metac_service_pdu(ups_cancel_test);
  1129. if (res == 1 || res == 0) {
  1130. strcat(bufOut, "Команда \"Останов теста\" принята ИБП!");
  1131. strcpy(log_string, name_login);
  1132. strcat(log_string, " (Останов)");
  1133. log_event_data(LOG_TEST_UPS, log_string);
  1134. }
  1135. if (res == -1) {
  1136. strcat(bufOut, "Команда \"Останов теста\" отклонена ИБП!");
  1137. }
  1138. } else if (strcmp(tempValue, "discharge") == 0) {
  1139. res = ups_metac_service_pdu(ups_test_low_bat);
  1140. set_act_source(WEB_ACT);
  1141. if (res == 1 || res == 0) {
  1142. strcat(bufOut, "Команда \"Запуск теста\" принята ИБП!");
  1143. }
  1144. if (res == -1) {
  1145. strcat(bufOut, "Команда \"Запуск теста\" отклонена ИБП!");
  1146. }
  1147. } else if (strncmp(tempValue, "time", 6) == 0) {
  1148. GetParamValue(bufIn, "time", tempValue2, &valueLen);
  1149. TimeParam = atoi(tempValue2);
  1150. res = ups_metac_service_pdu(ups_test_time);
  1151. if (res == 1 || res == 0) {
  1152. strcat(bufOut, "Команда \"Запуск теста\" принята ИБП!");
  1153. }
  1154. if (res == -1) {
  1155. strcat(bufOut, "Команда \"Запуск теста\" отклонена ИБП!");
  1156. }
  1157. }
  1158. *lenBufOut = strlen(bufOut);
  1159. return bufOut;
  1160. }
  1161. /**
  1162. * @brief Выклюение UPS
  1163. */
  1164. char *HTTP_UPSshutdown(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1165. {
  1166. uint8_t valueLen = 0;
  1167. char *valueLenEnd = 0;
  1168. char tempValue[50];
  1169. char tempValue2[50];
  1170. int8_t res = 0;
  1171. char log_string[50];
  1172. (void)lenBufIn;
  1173. (void)reqNum;
  1174. if (seclevel == USER) {
  1175. return 0;
  1176. }
  1177. memset(tempValue, 0, 50);
  1178. memset(log_string, 0, 50);
  1179. strcpy(bufOut, HTTP_200_OK);
  1180. GetParamValue(bufIn, "func", tempValue, &valueLen);
  1181. if (strcmp(tempValue, "reboot") == 0) {
  1182. res = ups_metac_service_pdu(ups_cancel_shut_down);
  1183. if (res == 1) {
  1184. strcpy(log_string, name_login);
  1185. strcat(log_string, " (Останов)");
  1186. log_event_data(LOG_SHUTDOWN_UPS, log_string);
  1187. strcat(bufOut, "Команда \"Отмена выключения нагрузки\" принята ИБП!");
  1188. } else {
  1189. strcat(bufOut, "Команда \"Отмена выключения нагрузки\" отклонена ИБП!");
  1190. }
  1191. } else if (strncmp(tempValue, "off", 5) == 0) {
  1192. memset(tempValue2, 0, 50);
  1193. GetParamValue(bufIn, "after", tempValue2, &valueLen);
  1194. TimeParamFloat = atof(tempValue2);
  1195. res = ups_metac_service_pdu(ups_shutdown);
  1196. if (res == 1) {
  1197. strcat(bufOut, "Команда \"Отключения нагрузки\" принята ИБП!");
  1198. log_event_data(LOG_SHUTDOWN_UPS, name_login);
  1199. } else {
  1200. strcat(bufOut, "Команда \"Отключения нагрузки\" отклонена ИБП!");
  1201. }
  1202. }
  1203. *lenBufOut = strlen(bufOut);
  1204. return bufOut;
  1205. }
  1206. /**
  1207. * @brief Проверка пароля для перехода в режим bootloader
  1208. * @retval None
  1209. */
  1210. char *HTTP_ConfirmBootPwd(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1211. {
  1212. (void)bufIn;
  1213. (void)lenBufIn;
  1214. (void)reqNum;
  1215. if (seclevel == USER) {
  1216. return 0;
  1217. }
  1218. strcpy(bufOut, HTTP_200_OK);
  1219. *lenBufOut = strlen(bufOut);
  1220. /* Запускаем задачу отложенной перезагрузки. Контроллер должен успеть
  1221. отправить ответ серверу о статусе пароля */
  1222. set_act_source(WEB_ACT);
  1223. HTTP_StartResetTask(true);
  1224. return bufOut;
  1225. }
  1226. #ifdef FTP_ENABLE
  1227. // Download the firmware via FTP, put it on the SPI flash, verify it and reboot the controller
  1228. static char *HTTP_FTPFWUpdate(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1229. {
  1230. (void)bufIn;
  1231. (void)lenBufIn;
  1232. (void)reqNum;
  1233. // check the logged user's permission level
  1234. if (seclevel == USER) {
  1235. return 0;
  1236. }
  1237. FTP_Update_t *settings = &sSettings.sFTPUpdate;
  1238. ftpcfg.settings = settings;
  1239. char value[30];
  1240. // FIXME GetParamValue doesn't check for buffer overflow
  1241. // ebalbekova told we don't need any verification against malicious actors
  1242. GetParamValue0(bufIn, "ftp_server", value, NULL);
  1243. if (!ipaddr_aton(value, &settings->server_ip)) {
  1244. IP4_ADDR(&settings->server_ip, 192,168,0,253);
  1245. }
  1246. GetParamValue0(bufIn, "ftp_port", value, NULL);
  1247. settings->server_port = atoi(value);
  1248. settings->server_port = settings->server_port == 0 ? 21 : settings->server_port;
  1249. GetParamValue0(bufIn, "ftp_path", settings->remote_path, NULL);
  1250. GetParamValue0(bufIn, "ftp_login", settings->user, NULL);
  1251. if (settings->user[0] == 0) {
  1252. strcpy(settings->user, "anonymous");
  1253. }
  1254. GetParamValue0(bufIn, "ftp_password", settings->pass, NULL);
  1255. if (settings->pass[0] == 0) {
  1256. strcpy(settings->pass, "guest");
  1257. }
  1258. HTTP_SaveSettings();
  1259. start_ftp_client(&ftpcfg);
  1260. strcpy(bufOut, HTTP_200_OK);
  1261. *lenBufOut = strlen(bufOut);
  1262. return bufOut;
  1263. }
  1264. static char *HTTP_FTPFWState(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1265. {
  1266. (void)bufIn;
  1267. (void)lenBufIn;
  1268. (void)reqNum;
  1269. char *progress = get_ftp_progress();
  1270. *lenBufOut = sprintf(bufOut, "HTTP/1.1 200 OK\r\nContent-Type:text/plain\r\n\r\n%s", progress);
  1271. return bufOut;
  1272. }
  1273. #endif // FTP_ENABLE
  1274. #ifdef HTTP_AUTH_ENABLE
  1275. void LoginTimerCallback(TimerHandle_t pxTimer)
  1276. {
  1277. cnt_err_psw = 0;
  1278. DBG printf("cnt_err_psw %d", cnt_err_psw);
  1279. xTimerStop(RepeatLoginTimer, 0);
  1280. }
  1281. #ifdef RADIUS_SERVER_ENABLE
  1282. void auth_task(void *pvParameters)
  1283. {
  1284. for(;;){
  1285. if(auth_flag == RS_AUTH_PROCESS) {
  1286. HTTP_RADIUSAuthConfirmWebPwd(post_req_data, sendAuthBuf, strlen(post_req_data), &sendBufLoadLen);
  1287. auth_flag = RS_AUTH_FINISH;
  1288. }
  1289. vTaskDelay(40);
  1290. }
  1291. }
  1292. /**
  1293. * @brief Проверка пароля для входа в Web
  1294. * @retval None
  1295. */
  1296. int HTTP_RADIUSAuthConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1297. {
  1298. char tempStr[52];
  1299. char login[20];
  1300. char password[20];
  1301. char tmp_password[33];
  1302. uint8_t valueLen, user_id;
  1303. char *strPtr = 0;
  1304. char WebPassword[MAX_WEB_PASSWD_LEN];
  1305. char WebLogin[MAX_WEB_LOGIN_LEN];
  1306. memset(login, 0, 20);
  1307. memset(password, 0, 20);
  1308. memset(tmp_password, 0, 33);
  1309. memset(tempStr, 0, 52);
  1310. memset(name_login, 0, 50);
  1311. tempStr[0] = '0';
  1312. /* Get first 50 bytes of string */
  1313. strncat(tempStr, bufIn, 49);
  1314. /* Add " " to the string in order GetParamValue() can be able to parse the param */
  1315. strcat(tempStr, " ");
  1316. GetParamValue(tempStr, "login", login, &valueLen);
  1317. GetParamValue(tempStr, "password", tmp_password, &valueLen);
  1318. url_decode(password, sizeof(password), tmp_password);
  1319. valueLen = strlen(password);
  1320. switch (RC_Login(login, password)) {
  1321. case RC_ERROR:
  1322. Authenticated = false;
  1323. break;
  1324. case RC_LOGIN_ADMIN_OK:
  1325. Authenticated = true;
  1326. user_id = 0;
  1327. break;
  1328. case RC_LOGIN_USER_OK:
  1329. Authenticated = true;
  1330. user_id = 1;
  1331. break;
  1332. case RC_NET_ERR:
  1333. Authenticated = false;
  1334. fl_raddius_net_err = true;
  1335. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
  1336. strcat(bufOut,
  1337. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Ошибка соединения с RADIUS сервером</h2></center></html>");
  1338. *lenBufOut = strlen(bufOut);
  1339. return SEND_REQUIRED_NO;
  1340. break;
  1341. case RC_ACC_DENIED:
  1342. Authenticated = false;
  1343. break;
  1344. default:
  1345. break;
  1346. }
  1347. snprintf(name_login, (strlen(login) + 1), login);
  1348. if (Authenticated) {
  1349. /* Generate cookie */
  1350. sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
  1351. /* Set users cookie */
  1352. HTTP_SetUserCookie(tempStr, user_id);
  1353. HTTP_UpdateUserLoginTime(user_id);
  1354. /* Send login and cookie back */
  1355. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
  1356. strcat(bufOut, login);
  1357. strcat(bufOut, "\r\nSet-Cookie: id=");
  1358. strcat(bufOut, tempStr);
  1359. sprintf(tempStr, "%d", (user_id + 1));
  1360. strcat(bufOut, "\r\nSet-Cookie: role=");
  1361. strcat(bufOut, tempStr);
  1362. strcat(bufOut, "\r\nSet-Cookie: auth=1");
  1363. strcat(bufOut, "\r\n\r\n");
  1364. strcat(bufOut,
  1365. "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
  1366. *lenBufOut = strlen(bufOut);
  1367. fl_raddius_net_err = false;
  1368. log_event_data(LOG_LOGIN, name_login);
  1369. /* Запускаем задачу-таймер логаута. */
  1370. /* TODO отправить ответ серверу о статусе пароля */
  1371. return SEND_REQUIRED_YES;
  1372. } else {
  1373. if (cnt_err_psw <= 4) {
  1374. cnt_err_psw ++;
  1375. }
  1376. DBG printf("cnt_err_psw %d", cnt_err_psw);
  1377. if (cnt_err_psw == 4) {
  1378. xTimerStart(RepeatLoginTimer, 0);
  1379. }
  1380. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
  1381. if (cnt_err_psw < 4) {
  1382. strcat(bufOut,
  1383. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
  1384. } else {
  1385. strcat(bufOut,
  1386. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Вход заблокирован!</h2></center></head><center><h2>Повторите попытку через 1 минуту</h2></center></html>");
  1387. }
  1388. *lenBufOut = strlen(bufOut);
  1389. return SEND_REQUIRED_NO;
  1390. }
  1391. }
  1392. #endif
  1393. /**
  1394. * @brief Проверка пароля для входа в Web
  1395. * @retval None
  1396. */
  1397. int HTTP_LocalAuthConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1398. {
  1399. char tempStr[52];
  1400. char login[20];
  1401. char password[20];
  1402. char tmp_password[33];
  1403. uint8_t valueLen, user_id;
  1404. char *strPtr = 0;
  1405. char WebPassword[MAX_WEB_PASSWD_LEN];
  1406. char WebLogin[MAX_WEB_LOGIN_LEN];
  1407. memset(login, 0, 20);
  1408. memset(password, 0, 20);
  1409. memset(tmp_password, 0, 33);
  1410. memset(tempStr, 0, 52);
  1411. memset(name_login, 0, 50);
  1412. tempStr[0] = '0';
  1413. /* Get first 50 bytes of string */
  1414. strncat(tempStr, bufIn, 49);
  1415. /* Add " " to the string in order GetParamValue() can be able to parse the param */
  1416. strcat(tempStr, " ");
  1417. GetParamValue(tempStr, "login", login, &valueLen);
  1418. GetParamValue(tempStr, "password", tmp_password, &valueLen);
  1419. url_decode(password, sizeof(password), tmp_password);
  1420. valueLen = strlen(password);
  1421. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  1422. GetUserLogin(user_id, WebLogin, &valueLen);
  1423. GetUserPassword(user_id, WebPassword, &valueLen);
  1424. /* Check login and password */
  1425. if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
  1426. (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
  1427. /* Login and pass are valid */
  1428. /* TODO replace global flag with user-pass-cookie */
  1429. if (cnt_err_psw < 4) {
  1430. cnt_err_psw = 0;
  1431. Authenticated = true;
  1432. switch (user_id) {
  1433. case 0:
  1434. snprintf(name_login, sizeof(name_login), "Администратор");
  1435. break;
  1436. case 1:
  1437. snprintf(name_login, sizeof(name_login), "Пользователь");
  1438. break;
  1439. default:
  1440. break;
  1441. }
  1442. } else {
  1443. Authenticated = false;
  1444. }
  1445. break;
  1446. } else {
  1447. Authenticated = false;
  1448. }
  1449. }
  1450. if (Authenticated) {
  1451. /* Generate cookie */
  1452. sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
  1453. /* Set users cookie */
  1454. HTTP_SetUserCookie(tempStr, user_id);
  1455. HTTP_UpdateUserLoginTime(user_id);
  1456. /* Send login and cookie back */
  1457. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
  1458. strcat(bufOut, login);
  1459. strcat(bufOut, "\r\nSet-Cookie: id=");
  1460. strcat(bufOut, tempStr);
  1461. sprintf(tempStr, "%d", (user_id + 1));
  1462. strcat(bufOut, "\r\nSet-Cookie: role=");
  1463. strcat(bufOut, tempStr);
  1464. strcat(bufOut, "\r\nSet-Cookie: auth=1");
  1465. strcat(bufOut, "\r\n\r\n");
  1466. strcat(bufOut,
  1467. "<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
  1468. *lenBufOut = strlen(bufOut);
  1469. #ifdef RADIUS_SERVER_ENABLE
  1470. fl_raddius_net_err = false;
  1471. #endif
  1472. log_event_data(LOG_LOGIN, name_login);
  1473. /* Запускаем задачу-таймер логаута. */
  1474. /* TODO отправить ответ серверу о статусе пароля */
  1475. return SEND_REQUIRED_YES;
  1476. } else {
  1477. if (cnt_err_psw <= 4) {
  1478. cnt_err_psw ++;
  1479. }
  1480. DBG printf("cnt_err_psw %d", cnt_err_psw);
  1481. if (cnt_err_psw == 4) {
  1482. xTimerStart(RepeatLoginTimer, 0);
  1483. }
  1484. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
  1485. if (cnt_err_psw < 4) {
  1486. strcat(bufOut,
  1487. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
  1488. } else {
  1489. strcat(bufOut,
  1490. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Вход заблокирован!</h2></center></head><center><h2>Повторите попытку через 1 минуту</h2></center></html>");
  1491. }
  1492. *lenBufOut = strlen(bufOut);
  1493. return SEND_REQUIRED_NO;
  1494. }
  1495. }
  1496. /**
  1497. * @brief Чтение Cookie пользователя
  1498. */
  1499. static void HTTP_GetUserCookie(uint8_t user_id, char *str, uint8_t *len)
  1500. {
  1501. sprintf(str, "%s", users[user_id].cookie);
  1502. *len = strlen(str);
  1503. }
  1504. /**
  1505. * @brief Установка Cookie пользователя
  1506. */
  1507. static void HTTP_SetUserCookie(char *str, uint8_t user_id)
  1508. {
  1509. strcpy(users[user_id].cookie, str);
  1510. }
  1511. /**
  1512. * @brief Обновление времени последней активности пользователя
  1513. */
  1514. static void HTTP_UpdateUserLoginTime(uint8_t user_id)
  1515. {
  1516. xTimerStart(users[user_id].LogoutTimer, 0);
  1517. }
  1518. /**
  1519. * @brief Принудительный логаут пользователя
  1520. */
  1521. static void HTTP_ForceUserLogout(uint8_t user_id)
  1522. {
  1523. char cookie[MAX_WEB_COOKIE_LEN];
  1524. /* Flush user cookie by random value */
  1525. sprintf(cookie, "%X", (unsigned int)GetRandomNumber());
  1526. HTTP_SetUserCookie(cookie, user_id);
  1527. }
  1528. /**
  1529. * @brief >Callback таймера логаута пользователя
  1530. */
  1531. void LogoutTimerCallback(TimerHandle_t pxTimer)
  1532. {
  1533. uint8_t user_id = (uint8_t)pvTimerGetTimerID( pxTimer );
  1534. HTTP_ForceUserLogout(user_id);
  1535. }
  1536. /**
  1537. * @brief Смена пароля пользователя
  1538. * @retval None
  1539. */
  1540. char *HTTP_ChangeUserPwd(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1541. {
  1542. char tempStr[110];
  1543. char value[20];
  1544. char login[20];
  1545. char password[20];
  1546. char tmp[75];
  1547. uint8_t valueLen, valueLen2, user_id;
  1548. char WebLogin[MAX_WEB_LOGIN_LEN];
  1549. (void)reqNum;
  1550. (void)lenBufIn;
  1551. if (seclevel == USER) {
  1552. return 0;
  1553. }
  1554. memset(login, 0, sizeof(login));
  1555. memset(password, 0, sizeof(password));
  1556. memset(tempStr, 0, sizeof(tempStr));
  1557. memset(value, 0, sizeof(value));
  1558. memset(tmp, 0, sizeof(tmp));
  1559. ClearParamString(bufIn);
  1560. strncpy(tempStr, bufIn, 110);
  1561. strcpy(bufOut, HTTP_200_OK);
  1562. if (GetParamValue(tempStr, "username", login, &valueLen) &&
  1563. GetParamValue(tempStr, "oldpass", tmp, &valueLen)) {
  1564. url_decode(password, sizeof(password), tmp);
  1565. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  1566. memset(value, 0, 20);
  1567. memset(WebLogin, 0, MAX_WEB_LOGIN_LEN);
  1568. GetUserLogin(user_id, WebLogin, &valueLen);
  1569. GetUserPassword(user_id, value, &valueLen2);
  1570. /* Check login and password */
  1571. if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
  1572. (memcmp(password, value, 11) == 0)) {
  1573. memset(tmp, 0, sizeof(tmp));
  1574. memset(password, 0, 20);
  1575. if (GetParamValue(tempStr, "newpass", tmp, &valueLen)) {
  1576. url_decode(password, sizeof(password), tmp);
  1577. valueLen = strlen(password);
  1578. memcpy(sSettings.sAuth[user_id].password, password, sizeof(sSettings.sAuth[user_id].password));
  1579. HTTP_SaveSettings();
  1580. log_event_data(LOG_PSW_CHANGE, name_login);
  1581. strcat(bufOut, "Пароль успешно изменён");
  1582. *lenBufOut = strlen(bufOut);
  1583. return bufOut;
  1584. } else {
  1585. strcat(bufOut, "Введены некорректные данные!");
  1586. *lenBufOut = strlen(bufOut);
  1587. return bufOut;
  1588. }
  1589. }
  1590. }
  1591. strcat(bufOut, "Введён неверный пароль!");
  1592. } else {
  1593. strcat(bufOut, "Введены некорректные данные!");
  1594. }
  1595. *lenBufOut = strlen(bufOut);
  1596. return bufOut;
  1597. }
  1598. static void getAuthenticatedState(void)
  1599. {
  1600. char CookieBuf[51];
  1601. char *CookiePtr = NULL;
  1602. char name[MAX_WEB_COOKIE_LEN];
  1603. char id[MAX_WEB_COOKIE_LEN];
  1604. uint8_t nameLen = 0, idLen = 0;
  1605. receiveBuf[receivedBufLen] = '\0';
  1606. //printf("receive %s \r\n", receiveBuf);
  1607. // Get cookie "uname" value
  1608. memset(CookieBuf, 0, sizeof(CookieBuf));
  1609. CookiePtr = strstr(receiveBuf, "uname=");
  1610. strncpy(CookieBuf, CookiePtr, 50);
  1611. //printf("********CookieBuf1= %s\r\n", CookieBuf);
  1612. memset(name, 0, MAX_WEB_COOKIE_LEN);
  1613. GetCookieValue(CookieBuf, "uname=", name, &nameLen);
  1614. //printf("********CookieBuf2= %s\r\n", CookieBuf);
  1615. //printf("********uname= %s\r\n", name);
  1616. memset(CookieBuf, 0, sizeof(CookieBuf));
  1617. // Get cookie "id" value
  1618. CookiePtr = strstr(receiveBuf, " id=");
  1619. strncpy(CookieBuf, CookiePtr, 50);
  1620. //printf("********CookieBuf1= %s\r\n", CookieBuf);
  1621. memset(id, 0, MAX_WEB_COOKIE_LEN);
  1622. GetCookieValue(CookieBuf, "id=", id, &idLen);
  1623. // printf("********ID= %s\r\n", id);
  1624. seclevel = 0xFF;
  1625. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  1626. HTTP_GetUserCookie(user_id, CookieBuf, &idLen);
  1627. if (strncmp(id, CookieBuf, idLen) == 0 ) {
  1628. GetUserLevelInt(user_id, &seclevel);
  1629. Authenticated = true;
  1630. break;
  1631. }
  1632. Authenticated = false;
  1633. seclevel = 0xFF;
  1634. }
  1635. }
  1636. void HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, char *postBuf, uint16_t lenBufIn, uint16_t *lenBufOut)
  1637. {
  1638. #ifdef RADIUS_SERVER_ENABLE
  1639. static char rs_id[16];
  1640. if (auth_flag != RS_AUTH_READY) {
  1641. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
  1642. char CookieBuf[51];
  1643. char *CookiePtr = NULL;
  1644. char rs_id_check[MAX_WEB_COOKIE_LEN];
  1645. uint8_t rs_idLen = 0;
  1646. CookiePtr = strstr(bufIn, "rs_id=");
  1647. strncpy(CookieBuf, CookiePtr, 50);
  1648. GetCookieValue(CookieBuf, "rs_id=", rs_id_check, &rs_idLen);
  1649. if (strncmp(rs_id, rs_id_check, strlen(rs_id)) == 0 && rs_idLen != 0) {
  1650. strcat(bufOut,
  1651. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>RADIUS сервер занят. Повторите попытку позже</h2></center></html>");
  1652. } else {
  1653. strcat(bufOut,
  1654. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>RADIUS сервер занят. Повторите попытку позже</h2></center></html>");
  1655. }
  1656. return;
  1657. }
  1658. if ((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)) {
  1659. auth_flag = RS_AUTH_PROCESS;
  1660. /* Generate cookie */
  1661. sprintf(rs_id, "%X", (unsigned int)GetRandomNumber());
  1662. strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: rs_id=");
  1663. strcat(bufOut, rs_id);
  1664. strcat(bufOut, "\r\n\r\n");
  1665. strcat(bufOut,
  1666. "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/check_auth.html\" /></head><center><h2>Ожидание соединения с RADIUS сервером</h2></center></html>");
  1667. } else
  1668. #endif
  1669. {
  1670. HTTP_LocalAuthConfirmWebPwd(postBuf, bufOut, strlen(postBuf), lenBufOut);
  1671. }
  1672. }
  1673. char *HTTP_LoginPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1674. {
  1675. (void)reqNum;
  1676. uint32_t req_data_received = 0;
  1677. char *offset = 0;
  1678. memset(bufOut, 0, SEND_BUF_MAX_LEN);
  1679. //printf("request 1: %d\r\n", lenBufIn);
  1680. if (post_data_count == 0) {
  1681. /* parse packet for Content-length field */
  1682. post_data_count = Parse_Content_Length(bufIn, lenBufIn);
  1683. //printf("Content-length: %d\r\n", (int)post_data_count);
  1684. if (post_data_count < MAX_POST_REQ_LEN) {
  1685. memset(post_req_data, 0, MAX_POST_REQ_LEN);
  1686. /* parse packet for "\r\n\r\n" */
  1687. offset = (strstr(bufIn, "\r\n\r\n")) + 4;
  1688. req_data_received = lenBufIn - (offset - bufIn);
  1689. //printf("req data received: %d\r\n", (int)req_data_received);
  1690. /* Check if "\r\n\r\n" was found */
  1691. if (offset != 0) {
  1692. /* if data was splited in two packets */
  1693. if (req_data_received < post_data_count) {
  1694. /* Copy request data to buffer */
  1695. snprintf(post_req_data, req_data_received, "%s", bufIn);
  1696. //printf("copied: %d\r\n", (int)req_data_received);
  1697. post_data_count -= req_data_received;
  1698. // log_post_reqn++;
  1699. }
  1700. /* if data received completely */
  1701. else {
  1702. strncat(post_req_data, &bufIn[offset - bufIn], post_data_count);
  1703. //printf("post_req_data: %s\r\n", post_req_data);
  1704. /* End reqest */
  1705. post_data_count = 0;
  1706. log_post_reqn = 0;
  1707. HTTP_ConfirmWebPwd(bufIn, bufOut, post_req_data, lenBufIn, lenBufOut);
  1708. *lenBufOut = strlen(bufOut);
  1709. return bufOut;
  1710. }
  1711. }
  1712. /* request was fragmented before "\r\n\r\n" */
  1713. else {
  1714. log_post_reqn++;
  1715. /* wait max 2 requests */
  1716. if (log_post_reqn > 1) {
  1717. post_data_count = 0;
  1718. log_post_reqn = 0;
  1719. /* Redirect to login page */
  1720. #ifdef RADIUS_SERVER_ENABLE
  1721. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  1722. fs_open("/rslogin.html", &file);
  1723. else
  1724. #endif
  1725. fs_open("/login.html", &file);
  1726. *lenBufOut = file.len;
  1727. return file.data;
  1728. }
  1729. }
  1730. } else {
  1731. DBG printf("Too long POST request!\r\n");
  1732. /* Ignore request */
  1733. post_data_count = 0;
  1734. log_post_reqn = 0;
  1735. /* Redirect to login page */
  1736. #ifdef RADIUS_SERVER_ENABLE
  1737. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  1738. fs_open("/rslogin.html", &file);
  1739. else
  1740. #endif
  1741. fs_open("/login.html", &file);
  1742. *lenBufOut = file.len;
  1743. return file.data;
  1744. }
  1745. } else if (post_data_count > 0) {
  1746. strncat(post_req_data, receiveBuf, post_data_count);
  1747. post_data_count = 0;
  1748. log_post_reqn = 0;
  1749. HTTP_ConfirmWebPwd(bufIn, bufOut, post_req_data, lenBufIn, lenBufOut);
  1750. *lenBufOut = strlen(bufOut);
  1751. return bufOut;
  1752. } else {
  1753. /* Redirect to login page */
  1754. #ifdef RADIUS_SERVER_ENABLE
  1755. if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
  1756. fs_open("/rslogin.html", &file);
  1757. else
  1758. #endif
  1759. fs_open("/login.html", &file);
  1760. *lenBufOut = file.len;
  1761. return file.data;
  1762. }
  1763. return 0;
  1764. }
  1765. char *HTTP_LogoutPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut)
  1766. {
  1767. (void)bufIn;
  1768. (void)bufOut;
  1769. (void)lenBufIn;
  1770. (void)reqNum;
  1771. Authenticated = false;
  1772. seclevel = 0xFF;
  1773. HTTP_ForceUserLogout(user_id);
  1774. fs_open("/settings.html", &file);
  1775. *lenBufOut = file.len;
  1776. return file.data;
  1777. }
  1778. #endif
  1779. /**
  1780. * @brief sends file from flash FS
  1781. * @param filename: pointer to the file name to send
  1782. * @param pnonmatch: pointer to the If-Non_Match value
  1783. * @param pcb: pointer to a tcp_pcb struct
  1784. * @param hs: pointer to a http_state struct
  1785. * @param file: pointer to a fs_file struct
  1786. * @retval
  1787. */
  1788. char *send_file(char *filename, char *pnonmatch, struct fs_file *file, uint16_t *Len)
  1789. {
  1790. int res = 0;
  1791. char etag[MAX_ETAG_LEN];
  1792. char *petag = NULL;
  1793. res = fs_open(filename, file);
  1794. if (res == 0) {
  1795. printf("Not found: %s\r\n", filename);
  1796. sprintf(filename, "/index.html");
  1797. fs_open(filename, file);
  1798. }
  1799. /* Find Etag value */
  1800. uint8_t etag_len = Parse_Header(file->data, file->len, Etag, 6, etag);
  1801. if (etag_len < MAX_ETAG_LEN && etag_len > 0) {
  1802. DBG printf("Etag: %s\r\n", etag);
  1803. petag = etag;
  1804. }
  1805. /* Compare Etag and If-Non-Match fields */
  1806. if (pnonmatch && petag && (strcmp(pnonmatch, petag) == 0)) {
  1807. /* Send 304 code */
  1808. sprintf(sendBuf, HTTP_304_NOT_MODIFIED);
  1809. DBG printf(sendBuf);
  1810. *Len = strlen(sendBuf);
  1811. return sendBuf;
  1812. } else {
  1813. /* Send file */
  1814. //DBG printf("%s\r\n\r\n", filename);
  1815. *Len = file->len;
  1816. return file->data;
  1817. }
  1818. }
  1819. /**
  1820. * @brief Extract the custom field data from HTML data
  1821. * @param data : pointer on receive packet buffer
  1822. * @param len : buffer length
  1823. * @param field : field name
  1824. * @param flen : field name length
  1825. * @retval value : pointer for field data
  1826. */
  1827. static uint32_t Parse_Header(char *data, uint32_t len, const char *field, uint32_t flen, char *value)
  1828. {
  1829. uint32_t i = 0, size = 0;
  1830. char *ptr;
  1831. uint32_t Offset = 0;
  1832. /* Find field name in data buffer */
  1833. for (i = 0; i < len; i++) {
  1834. if (strncmp ((char *)(data + i), field, flen) == 0) {
  1835. Offset = i + flen;
  1836. break;
  1837. }
  1838. }
  1839. /* Copy Field value */
  1840. if (Offset) {
  1841. i = 0;
  1842. ptr = (char *)(data + Offset);
  1843. while (*(ptr + i) != 0x0d) {
  1844. value[i] = *(ptr + i);
  1845. i++;
  1846. }
  1847. value[i] = '\0';
  1848. size = i;
  1849. }
  1850. return size;
  1851. }
  1852. /**
  1853. * @brief
  1854. * @retval None
  1855. */
  1856. bool GetFileName(char *inStr, char *fileName, uint8_t *fileNameLen)
  1857. {
  1858. char *beginValue = NULL;
  1859. char *endValue = NULL;
  1860. int len = 0;
  1861. char *strPtr = NULL;
  1862. strPtr = strstr(inStr, "GET");
  1863. if (strPtr == NULL) {
  1864. strPtr = strstr(inStr, "POST");
  1865. }
  1866. if (strPtr == NULL) {
  1867. *fileNameLen = 0;
  1868. return false;
  1869. } else {
  1870. beginValue = strpbrk(strPtr, "/");
  1871. endValue = strpbrk(beginValue, " ");
  1872. if (endValue == NULL) {
  1873. *fileNameLen = 0;
  1874. return false;
  1875. }
  1876. len = endValue - beginValue;
  1877. if (len < MAX_FILENAME_LEN) {
  1878. strncpy(fileName, beginValue, len);
  1879. *fileNameLen = len;
  1880. fileName[len] = '\0';
  1881. return true;
  1882. } else {
  1883. return false;
  1884. }
  1885. }
  1886. }
  1887. /**
  1888. * @brief Extract the Content_Length data from HTML data
  1889. * @param data : pointer on receive packet buffer
  1890. * @param len : buffer length
  1891. * @retval size : Content_length in numeric format
  1892. */
  1893. static uint32_t Parse_Content_Length(char *data, uint32_t len)
  1894. {
  1895. uint32_t i = 0, size = 0, S = 1;
  1896. int32_t j = 0;
  1897. char sizestring[6], *ptr;
  1898. ContentLengthOffset = 0;
  1899. /* find Content-Length data in packet buffer */
  1900. for (i = 0; i < len; i++) {
  1901. if (strncmp ((char *)(data + i), Content_Length, 16) == 0) {
  1902. ContentLengthOffset = i + 16;
  1903. break;
  1904. }
  1905. }
  1906. /* read Content-Length value */
  1907. if (ContentLengthOffset) {
  1908. i = 0;
  1909. ptr = (char *)(data + ContentLengthOffset);
  1910. while (*(ptr + i) != 0x0d) {
  1911. sizestring[i] = *(ptr + i);
  1912. i++;
  1913. ContentLengthOffset++;
  1914. }
  1915. if (i > 0) {
  1916. /* transform string data into numeric format */
  1917. for (j = i - 1; j >= 0; j--) {
  1918. size += (sizestring[j] - 0x30) * S;
  1919. S = S * 10;
  1920. }
  1921. }
  1922. }
  1923. return size;
  1924. }
  1925. /**
  1926. * @brief get the value of an URL parameter supplied in a HTTP request, zero-terminated
  1927. */
  1928. uint8_t GetParamValue0(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  1929. {
  1930. uint8_t tmplen;
  1931. uint8_t *len = paramLen ? paramLen : &tmplen;
  1932. uint8_t rv = GetParamValue(inStr, paramName, paramValue, len);
  1933. paramValue[*len] = 0;
  1934. return rv;
  1935. }
  1936. /**
  1937. * @brief get the value of an URL parameter supplied in a HTTP request
  1938. * @retval None
  1939. */
  1940. uint8_t GetParamValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  1941. {
  1942. char *beginValue = 0;
  1943. char *endValue = 0;
  1944. int len = 0;
  1945. char *strPtr = 0;
  1946. char paramName_tmp[50];
  1947. memset(paramName_tmp, 0, sizeof(paramName_tmp));
  1948. paramName_tmp[0] = '&';
  1949. strncat(paramName_tmp, paramName, strlen(paramName));
  1950. strcat(paramName_tmp, "=");
  1951. strPtr = strstr(inStr, paramName_tmp);
  1952. if (strPtr == 0) {
  1953. paramName_tmp[0] = '0';
  1954. strPtr = strstr(inStr, paramName_tmp);
  1955. if (strPtr == 0) {
  1956. paramName_tmp[0] = '\n';
  1957. strPtr = strstr(inStr, paramName_tmp);
  1958. }
  1959. if (strPtr == 0) {
  1960. paramName_tmp[0] = '?';
  1961. strPtr = strstr(inStr, paramName_tmp);
  1962. }
  1963. }
  1964. if (strPtr != 0) {
  1965. beginValue = strpbrk(strPtr, "=");
  1966. endValue = strpbrk(&strPtr[1], "&");
  1967. if (endValue == 0) {
  1968. endValue = strpbrk(strPtr, " ");
  1969. }
  1970. if (endValue == 0) {
  1971. endValue = strPtr + strlen(strPtr);
  1972. }
  1973. len = endValue - beginValue - 1;
  1974. strncpy(paramValue, beginValue + 1, len);
  1975. *endValue = '0';
  1976. *beginValue = '0';
  1977. if (paramLen) {
  1978. *paramLen = len;
  1979. }
  1980. return 1;
  1981. } else {
  1982. if (paramLen) {
  1983. *paramLen = 0;
  1984. }
  1985. return 0;
  1986. }
  1987. }
  1988. /**
  1989. * @brief
  1990. * @retval None
  1991. */
  1992. uint8_t GetCookieValue(char *inStr, char *paramName, char *paramValue, uint8_t *paramLen)
  1993. {
  1994. char *beginValue = 0;
  1995. char *endValue = 0;
  1996. char *endValueTemp = 0;
  1997. int len = 0;
  1998. char *strPtr = 0;
  1999. strPtr = strstr(inStr, paramName);
  2000. if (strPtr != 0) {
  2001. beginValue = strpbrk(strPtr, "=");
  2002. endValue = strpbrk(strPtr, ";");
  2003. endValueTemp = strpbrk(strPtr, "\r");
  2004. if (endValueTemp != 0 && endValueTemp < endValue) {
  2005. endValue = endValueTemp;
  2006. }
  2007. if (endValue == 0) {
  2008. endValue = strpbrk(strPtr, "\n");
  2009. }
  2010. len = endValue - beginValue - 1;
  2011. strncpy(paramValue, beginValue + 1, len);
  2012. *endValue = '0';
  2013. *beginValue = '0';
  2014. *paramLen = len;
  2015. return 1;
  2016. } else {
  2017. *paramLen = 0;
  2018. return 0;
  2019. }
  2020. }
  2021. char *Parce_Boundary(const char *data, uint32_t len, char *dst, uint8_t dstlen)
  2022. {
  2023. char *ptr = NULL;
  2024. char *boundary = NULL;
  2025. uint8_t i = 0;
  2026. for (uint32_t j = 0; j < len; j++) {
  2027. if (strncmp ((char *)(data + j), "boundary=", 9) == 0) {
  2028. boundary = (char *)data + j + 9;
  2029. break;
  2030. }
  2031. }
  2032. if (!boundary) { return NULL; }
  2033. *dst++ = '-';
  2034. *dst++ = '-';
  2035. ptr = boundary;
  2036. while ((*ptr != 0x0d) && (i < dstlen - 4)) {
  2037. *dst++ = *ptr++;
  2038. i++;
  2039. }
  2040. //*dst++ = '-';
  2041. //*dst++ = '-';
  2042. *dst = '\0';
  2043. if (i > 0) {
  2044. return boundary;
  2045. } else {
  2046. return NULL;
  2047. }
  2048. }
  2049. void ClearParamString(char *inBuf)
  2050. {
  2051. uint16_t len;
  2052. char *str;
  2053. str = strstr(inBuf, "HTTP");
  2054. if (str != 0) {
  2055. len = str - inBuf;
  2056. memset(str, 0, RECIVE_BUF_MAX_LEN - len - 1);
  2057. }
  2058. }
  2059. #endif