httpserver.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. #include "httpserver.h"
  2. #include "lwip/tcp.h"
  3. #include "fsdata.c"
  4. #include "main.h"
  5. #include "flash_if.h"
  6. #include "common_config.h"
  7. #include "settings_api.h"
  8. #include "crc.h"
  9. #include "gpio_io.h"
  10. #include "systick.h"
  11. #include <string.h>
  12. #include "tinystdio.h"
  13. #define FILENAME_MAX_LEN 30
  14. /**
  15. * @brief Общая структура настроек
  16. */
  17. extern SETTINGS_t sSettings;
  18. extern uint8_t fDoneReset;
  19. extern uint8_t fErrorReset;
  20. char debugMsg[40];
  21. static vu32 DataFlag=0;
  22. static vu32 size =0;
  23. static __IO uint32_t FlashWriteAddress;
  24. static u32 TotalReceived=0;
  25. static char LeftBytesTab[4];
  26. static u8 LeftBytes=0;
  27. static __IO u8 resetpage=0;
  28. static uint32_t ContentLengthOffset =0,BrowserFlag=0;
  29. static __IO uint32_t TotalData=0, checklogin=0;
  30. static bool fEraseFlash = true;
  31. static bool hw_validated = false;
  32. static uint32_t ContentOffset = 0;
  33. static uint8_t reqCounter = 0;
  34. static uint8_t reqTimer = 0;
  35. struct http_state
  36. {
  37. char *file;
  38. u32_t left;
  39. };
  40. htmlpageState htmlpage;
  41. static const char http_crnl_2[4] =
  42. /* "\r\n--" */
  43. {0xd, 0xa,0x2d,0x2d};
  44. static const char octet_stream[14] =
  45. /* "octet-stream" */
  46. {0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,0x0d, };
  47. static const char Content_Length[17] =
  48. /* Content Length */
  49. {0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67,0x74, 0x68, 0x3a, 0x20, };
  50. static uint32_t Parse_Content_Length(char *data, uint32_t len);
  51. char* Parce_Boundary(const char* data, uint32_t len, char* dst, uint8_t dstlen);
  52. static void IAP_HTTP_writedata(char* data, uint32_t len);
  53. /* file must be allocated by caller and will be filled in
  54. by the function. */
  55. static int fs_open(char *name, struct fs_file *file);
  56. uint16_t printLen = 0;
  57. char printBuf[1500];
  58. uint32_t oldAdd = USER_FLASH_FIRST_PAGE_ADDRESS;
  59. uint32_t deltaAdd = 0;
  60. /**
  61. * @brief callback function for handling connection errors
  62. * @param arg: pointer to an argument to be passed to callback function
  63. * @param err: LwIP error code
  64. * @retval none
  65. */
  66. static void conn_err(void *arg, err_t err)
  67. {
  68. struct http_state *hs;
  69. hs = arg;
  70. mem_free(hs);
  71. }
  72. /**
  73. * @brief closes tcp connection
  74. * @param pcb: pointer to a tcp_pcb struct
  75. * @param hs: pointer to a http_state struct
  76. * @retval
  77. */
  78. static void close_conn(struct tcp_pcb *pcb, struct http_state *hs)
  79. {
  80. tcp_arg(pcb, NULL);
  81. tcp_sent(pcb, NULL);
  82. tcp_recv(pcb, NULL);
  83. mem_free(hs);
  84. tcp_close(pcb);
  85. reqCounter++;
  86. }
  87. /**
  88. * @brief sends data found in member "file" of a http_state struct
  89. * @param pcb: pointer to a tcp_pcb struct
  90. * @param hs: pointer to a http_state struct
  91. * @retval none
  92. */
  93. static void send_data(struct tcp_pcb *pcb, struct http_state *hs)
  94. {
  95. err_t err;
  96. u16_t len;
  97. /* We cannot send more data than space available in the send
  98. buffer */
  99. if (tcp_sndbuf(pcb) < hs->left)
  100. {
  101. len = tcp_sndbuf(pcb);
  102. }
  103. else
  104. {
  105. len = hs->left;
  106. }
  107. err = tcp_write(pcb, hs->file, len, 0);
  108. if (err == ERR_OK)
  109. {
  110. hs->file += len;
  111. hs->left -= len;
  112. }
  113. }
  114. /**
  115. * @brief tcp poll callback function
  116. * @param arg: pointer to an argument to be passed to callback function
  117. * @param pcb: pointer on tcp_pcb structure
  118. * @retval err_t
  119. */
  120. static err_t http_poll(void *arg, struct tcp_pcb *pcb)
  121. {
  122. if (arg == NULL)
  123. {
  124. tcp_close(pcb);
  125. }
  126. else
  127. {
  128. send_data(pcb, (struct http_state *)arg);
  129. }
  130. return ERR_OK;
  131. }
  132. /**
  133. * @brief callback function called after a successfull TCP data packet transmission
  134. * @param arg: pointer to an argument to be passed to callback function
  135. * @param pcb: pointer on tcp_pcb structure
  136. * @param len
  137. * @retval err : LwIP error code
  138. */
  139. static err_t http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
  140. {
  141. struct http_state *hs;
  142. hs = arg;
  143. if (hs->left > 0){
  144. // printf("send");
  145. send_data(pcb, hs);
  146. }
  147. else
  148. {
  149. printf("close");
  150. close_conn(pcb, hs);
  151. if (htmlpage == UploadDonePage)
  152. fDoneReset = 1;
  153. else if (htmlpage == UploadErrorPage)
  154. fErrorReset = 1;
  155. }
  156. return ERR_OK;
  157. }
  158. /**
  159. * @brief callback function for handling TCP HTTP traffic
  160. * @param arg: pointer to an argument structure to be passed to callback function
  161. * @param pcb: pointer to a tcp_pcb structure
  162. * @param p: pointer to a packet buffer
  163. * @param err: LwIP error code
  164. * @retval err
  165. */
  166. /* goback.cgi - возврат в основную прошивку */
  167. /* upload.cgi - загрузка новой прошивки */
  168. static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
  169. {
  170. int32_t i, len=0;
  171. uint32_t DataOffset, FilenameOffset;
  172. char *data, *ptr, filename[13];
  173. struct fs_file file = {0, 0};
  174. struct http_state *hs;
  175. hs = arg;
  176. if (err == ERR_OK && p != NULL)
  177. {
  178. /* Inform TCP that we have taken the data */
  179. tcp_recved(pcb, p->tot_len);
  180. if (hs->file == NULL)
  181. {
  182. data = p->payload;
  183. len = p->tot_len;
  184. printLen = p->tot_len;
  185. memcpy(printBuf, p->payload , printLen);
  186. //printf(printBuf);
  187. /* process HTTP GET requests */
  188. if (strncmp(data, "GET /", 5) == 0)
  189. {/*
  190. if ((strncmp(data, "GET /resetmcu.cgi", 17) ==0)&&(htmlpage == UploadDonePage))
  191. {
  192. htmlpage = ResetDonePage;
  193. fs_open("/reset.html", &file);
  194. hs->file = file.data;
  195. hs->left = file.len;
  196. pbuf_free(p);
  197. send_data(pcb, hs);
  198. resetpage = 1;
  199. tcp_sent(pcb, http_sent);
  200. }*/
  201. if (strncmp(data, "GET /upload.css", 15) == 0)
  202. {
  203. fs_open("/upload.css", &file);
  204. hs->file = file.data;
  205. hs->left = file.len;
  206. pbuf_free(p);
  207. send_data(pcb, hs);
  208. tcp_sent(pcb, http_sent);
  209. }
  210. else if (strncmp(data, "GET /upload.js", 14) == 0)
  211. {
  212. fs_open("/upload.js", &file);
  213. hs->file = file.data;
  214. hs->left = file.len;
  215. pbuf_free(p);
  216. send_data(pcb, hs);
  217. tcp_sent(pcb, http_sent);
  218. }
  219. /* Возврат в основную прошивку. Сбрасываем флаг loadmode,
  220. сохраняем настройки и перезагружаемся */
  221. else if (strncmp(data, "GET /goback.cgi", 15)==0)
  222. {
  223. RTC_WriteBackupRegister(RTC_BKP_DR1, 0);
  224. /* sSettings.bootParams.loadMode = 0;
  225. SETTINGS_Save();*/
  226. Delay_ms(1010);
  227. NVIC_SystemReset();
  228. }
  229. else if (strncmp(data, "GET /favicon.ico", 16) == 0)
  230. {
  231. fs_open("/favicon.ico", &file);
  232. hs->file = file.data;
  233. hs->left = file.len;
  234. send_data(pcb, hs);
  235. tcp_sent(pcb, http_sent);
  236. }
  237. else
  238. {
  239. /*send the login page (which is the index page) */
  240. htmlpage = LoginPage;
  241. fs_open("/index.html", &file);
  242. hs->file = file.data;
  243. hs->left = file.len;
  244. pbuf_free(p);
  245. send_data(pcb, hs);
  246. tcp_sent(pcb, http_sent);
  247. }
  248. }
  249. #if 1
  250. /* process POST request for file upload and incoming data packets after POST request*/
  251. else if ((strncmp(data, "POST /upload.cgi",16) == 0) || (DataFlag >= 1))
  252. {
  253. /*if (fEraseFlash) {
  254. FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
  255. fEraseFlash = false;
  256. }*/
  257. static char boundary[70];
  258. static char boundary_buf[70];
  259. static char *pbound = NULL;
  260. DataOffset = 0;
  261. /* POST Packet received */
  262. if (DataFlag == 0)
  263. {
  264. BrowserFlag = 0;
  265. TotalReceived = 0;
  266. /* parse packet for Content-length field */
  267. size = Parse_Content_Length(data, p->tot_len);
  268. pbound = Parce_Boundary(data, p->tot_len, boundary, sizeof(boundary));
  269. //printf("boundary: %s\r\n", boundary);
  270. /* parse packet for the octet-stream field */
  271. for (i = 0; i < len; i++)
  272. {
  273. /* TODO remove if tested */
  274. // if (strncmp ((char*)(data+i), octet_stream, 13)==0)
  275. // {
  276. // DataOffset = i + 16;
  277. // break;
  278. // }
  279. if (pbound != NULL) {
  280. if (strncmp ((char*)(data+i), boundary, strlen(boundary))==0)
  281. {
  282. ContentOffset = i;
  283. /* parse packet for "\r\n\r\n" field */
  284. for (int32_t j= 0; j < len; j++) {
  285. if (strncmp ((char*)(data+i+j), "\r\n\r\n", 4)==0)
  286. {
  287. DataOffset = i + j + 4;
  288. break;
  289. }
  290. }
  291. }
  292. }
  293. }
  294. /* case of MSIE8 : we do not receive data in the POST packet*/
  295. if (DataOffset == 0)
  296. {
  297. DataFlag++;
  298. BrowserFlag = 1;
  299. pbuf_free(p);
  300. return ERR_OK;
  301. }
  302. /* case of Mozilla Firefox v3.6 : we receive data in the POST packet*/
  303. else
  304. {
  305. TotalReceived = len - ContentOffset;
  306. }
  307. }
  308. if (((DataFlag ==1)&&(BrowserFlag==1)) || ((DataFlag ==0)&&(BrowserFlag==0)))
  309. {
  310. if ((DataFlag ==0)&&(BrowserFlag==0))
  311. {
  312. DataFlag++;
  313. }
  314. else if ((DataFlag ==1)&&(BrowserFlag==1))
  315. {
  316. /* parse packet for the octet-stream field */
  317. for (i = 0; i < len; i++)
  318. {
  319. if (pbound != NULL) {
  320. if (strncmp ((char*)(data+i), boundary, strlen(boundary))==0)
  321. {
  322. /* parse packet for "\r\n\r\n" field */
  323. for (int32_t j= 0; j < len; j++) {
  324. if (strncmp ((char*)(data+i+j), "\r\n\r\n", 4)==0)
  325. {
  326. DataOffset = i + j + 4;
  327. break;
  328. }
  329. }
  330. }
  331. }
  332. }
  333. TotalReceived += len;
  334. DataFlag++;
  335. }
  336. /* parse packet for the filename field */
  337. FilenameOffset = 0;
  338. for (i = 0; i < len; i++)
  339. {
  340. if (strncmp ((char*)(data+i), "filename=", 9)==0)
  341. {
  342. FilenameOffset = i+10;
  343. break;
  344. }
  345. }
  346. i = 0;
  347. if (FilenameOffset)
  348. {
  349. while((*(data+FilenameOffset + i)!=0x22 )&&(i<FILENAME_MAX_LEN))
  350. {
  351. filename[i] = *(data+FilenameOffset + i);
  352. i++;
  353. }
  354. filename[i] = 0x0;
  355. }
  356. /* Set HW revision validation marker */
  357. hw_validated = false;
  358. if (i==0)
  359. {
  360. htmlpage = FileUploadPage;
  361. /* no filename, in this case reload upload page */
  362. fs_open("/upload.html", &file);
  363. hs->file = file.data;
  364. hs->left = file.len;
  365. pbuf_free(p);
  366. /* send index.html page */
  367. send_data(pcb, hs);
  368. /* Tell TCP that we wish be to informed of data that has been
  369. successfully sent by a call to the http_sent() function. */
  370. tcp_sent(pcb, http_sent);
  371. DataFlag=0;
  372. return ERR_OK;
  373. }
  374. PRINT_USART("\n\r IAP using HTTP \n\r");
  375. sprintf(debugMsg, "File: %s\n\r",filename);
  376. PRINT_USART(debugMsg);
  377. PRINT_USART("State: Erasing...\n\r");
  378. TotalData =0 ;
  379. /* init flash */
  380. /// FLASH_If_Init();
  381. /* erase user flash area */
  382. //FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
  383. // / FlashWriteAddress = USER_FLASH_FIRST_PAGE_ADDRESS;
  384. /*indicate start of flash programming */
  385. PRINT_USART("\n\rState: Programming..\n\r");
  386. }
  387. /* DataFlag >1 => the packet is data only */
  388. else
  389. {
  390. TotalReceived +=len;
  391. }
  392. ptr = (char*)(data + DataOffset);
  393. len-= DataOffset;
  394. /* update Total data received counter */
  395. TotalData +=len;
  396. /* check if last data packet */
  397. if (TotalReceived == size)
  398. {
  399. /* if last packet need to remove the http boundary tag */
  400. /* parse packet for "\r\n--" starting from end of data */
  401. /*
  402. i = 4;
  403. while (strncmp ((char*)(data+ p->tot_len -i),http_crnl_2 , 4))
  404. {
  405. i++;
  406. }
  407. len -= i;
  408. TotalData -= i;
  409. */
  410. /* write data in Flash */
  411. if(hw_validated){
  412. if (len)
  413. IAP_HTTP_writedata(ptr,len);
  414. DataFlag=0;
  415. htmlpage = UploadDonePage;
  416. PRINT_USART("Tot bytes Received:\n\r");
  417. sprintf(debugMsg, "%d bytes \n\r",TotalData);
  418. PRINT_USART(debugMsg);
  419. PRINT_USART("State: Prog Finished \n\r");
  420. }
  421. /* Проверяем CRC */
  422. if (hw_validated && CRC_Read() == CRC_Calcucate()) {
  423. fs_open("/success.html", &file);
  424. hs->file = file.data;
  425. hs->left = file.len;
  426. send_data(pcb, hs);
  427. tcp_sent(pcb, http_sent);
  428. htmlpage = UploadDonePage;
  429. }
  430. else
  431. {
  432. if(hw_validated)
  433. FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
  434. fEraseFlash = false;
  435. fs_open("/error.html", &file);
  436. hs->file = file.data;
  437. hs->left = file.len;
  438. send_data(pcb, hs);
  439. tcp_sent(pcb, http_sent);
  440. htmlpage = UploadErrorPage;
  441. }
  442. /*
  443. sSettings.bootParams.loadMode = 0;
  444. SETTINGS_Save();
  445. IO_KeyBlockOn();
  446. Delay_ms(1010);
  447. NVIC_SystemReset();
  448. */
  449. }
  450. /* not last data packet */
  451. else
  452. {
  453. if ((TotalData >= HW_REV_OFFSET + HW_REV_LEN) && (!hw_validated)) {
  454. char rev[HW_REV_LEN];
  455. strncpy(rev, HW_REV, HW_REV_LEN);
  456. if (strcmp((char *)(ptr + HW_REV_OFFSET), rev) != 0) {
  457. // DataFlag = 0;
  458. pbuf_free(p);
  459. /* fs_open("/error.html", &file);
  460. hs->file = file.data;
  461. hs->left = file.len;*/
  462. /* send_data(pcb, hs);
  463. tcp_sent(pcb, http_sent);*/
  464. // printf("start");
  465. // htmlpage = UploadErrorPage;
  466. // fErrorReset = 1;
  467. // pbuf_free(p);
  468. //close_conn(pcb, hs);
  469. return ERR_OK;
  470. }
  471. else {
  472. hw_validated = true;
  473. // Erase flash
  474. if (fEraseFlash) {
  475. FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
  476. fEraseFlash = false;
  477. }
  478. // Init flash
  479. FLASH_If_Init();
  480. FlashWriteAddress = USER_FLASH_FIRST_PAGE_ADDRESS;
  481. }
  482. }
  483. /* write data in flash */
  484. if(len)
  485. IAP_HTTP_writedata(ptr,len);
  486. }
  487. pbuf_free(p);
  488. }
  489. else
  490. {
  491. /* Bad HTTP requests */
  492. PRINT_USART("Bad HTTP request\n\r");
  493. pbuf_free(p);
  494. close_conn(pcb, hs);
  495. }
  496. #endif
  497. }
  498. else
  499. {
  500. pbuf_free(p);
  501. close_conn(pcb,hs);
  502. }
  503. }
  504. if (err == ERR_OK && p == NULL)
  505. {
  506. /* received empty frame */
  507. PRINT_USART("Received empty frame\n\r");
  508. close_conn(pcb, hs);
  509. }
  510. return ERR_OK;
  511. }
  512. /**
  513. * @brief callback function on TCP connection setup ( on port 80)
  514. * @param arg: pointer to an argument structure to be passed to callback function
  515. * @param pcb: pointer to a tcp_pcb structure
  516. * &param err: Lwip stack error code
  517. * @retval err
  518. */
  519. static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
  520. {
  521. struct http_state *hs;
  522. /* Allocate memory for the structure that holds the state of the connection */
  523. hs = mem_malloc(sizeof(struct http_state));
  524. if (hs == NULL)
  525. {
  526. return ERR_MEM;
  527. }
  528. /* Initialize the structure. */
  529. hs->file = NULL;
  530. hs->left = 0;
  531. /* Tell TCP that this is the structure we wish to be passed for our
  532. callbacks. */
  533. tcp_arg(pcb, hs);
  534. /* Tell TCP that we wish to be informed of incoming data by a call
  535. to the http_recv() function. */
  536. tcp_recv(pcb, http_recv);
  537. tcp_err(pcb, conn_err);
  538. tcp_poll(pcb, http_poll, 10);
  539. return ERR_OK;
  540. }
  541. /**
  542. * @brief intialize HTTP webserver
  543. * @param none
  544. * @retval none
  545. */
  546. void IAP_httpd_init(void)
  547. {
  548. struct tcp_pcb *pcb;
  549. /*create new pcb*/
  550. pcb = tcp_new();
  551. /* bind HTTP traffic to pcb */
  552. tcp_bind(pcb, IP_ADDR_ANY, 80);
  553. /* start listening on port 80 */
  554. pcb = tcp_listen(pcb);
  555. /* define callback function for TCP connection setup */
  556. tcp_accept(pcb, http_accept);
  557. }
  558. /**
  559. * @brief Opens a file defined in fsdata.c ROM filesystem
  560. * @param name : pointer to a file name
  561. * @param file : pointer to a fs_file structure
  562. * @retval 1 if success, 0 if fail
  563. */
  564. static int fs_open(char *name, struct fs_file *file)
  565. {
  566. struct fsdata_file_noconst *f;
  567. for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next)
  568. {
  569. if (!strcmp(name, f->name))
  570. {
  571. file->data = f->data;
  572. file->len = f->len;
  573. return 1;
  574. }
  575. }
  576. return 0;
  577. }
  578. /**
  579. * @brief Extract the Content_Length data from HTML data
  580. * @param data : pointer on receive packet buffer
  581. * @param len : buffer length
  582. * @retval size : Content_length in numeric format
  583. */
  584. static uint32_t Parse_Content_Length(char *data, uint32_t len)
  585. {
  586. uint32_t i=0,size=0, S=1;
  587. int32_t j=0;
  588. char sizestring[6], *ptr;
  589. ContentLengthOffset =0;
  590. /* find Content-Length data in packet buffer */
  591. for (i=0;i<len;i++)
  592. {
  593. if (strncmp ((char*)(data+i), Content_Length, 16)==0)
  594. {
  595. ContentLengthOffset = i+16;
  596. break;
  597. }
  598. }
  599. /* read Content-Length value */
  600. if (ContentLengthOffset)
  601. {
  602. i=0;
  603. ptr = (char*)(data + ContentLengthOffset);
  604. while(*(ptr+i)!=0x0d)
  605. {
  606. sizestring[i] = *(ptr+i);
  607. i++;
  608. ContentLengthOffset++;
  609. }
  610. if (i>0)
  611. {
  612. /* transform string data into numeric format */
  613. for(j=i-1;j>=0;j--)
  614. {
  615. size += (sizestring[j]-0x30)*S;
  616. S=S*10;
  617. }
  618. }
  619. }
  620. return size;
  621. }
  622. char* Parce_Boundary(const char* data, uint32_t len, char* dst, uint8_t dstlen) {
  623. char *ptr = NULL;
  624. char *boundary = NULL;
  625. uint8_t i = 0;
  626. for (uint32_t j = 0; j < len; j++) {
  627. if (strncmp ((char*)(data + j), "boundary=", 9) == 0) {
  628. boundary = (char*)data + j + 9;
  629. break;
  630. }
  631. }
  632. if (!boundary) return NULL;
  633. *dst++ = '-';
  634. *dst++ = '-';
  635. ptr = boundary;
  636. while ((*ptr != 0x0d) && (i < dstlen - 4))
  637. {
  638. *dst++ = *ptr++;
  639. i++;
  640. }
  641. //*dst++ = '-';
  642. //*dst++ = '-';
  643. *dst = '\0';
  644. if (i > 0)
  645. return boundary;
  646. else
  647. return NULL;
  648. }
  649. /**
  650. * @brief writes received data in flash
  651. * @param ptr: data pointer
  652. * @param len: data length
  653. * @retval none
  654. */
  655. void IAP_HTTP_writedata(char * ptr, uint32_t len)
  656. {
  657. uint32_t count, i=0, j=0;
  658. /* check if any left bytes from previous packet transfer*/
  659. /* if it is the case do a concat with new data to create a 32-bit word */
  660. if (LeftBytes)
  661. {
  662. while(LeftBytes<=3)
  663. {
  664. if(len>(j+1))
  665. {
  666. LeftBytesTab[LeftBytes++] = *(ptr+j);
  667. }
  668. else
  669. {
  670. LeftBytesTab[LeftBytes++] = 0xFF;
  671. }
  672. j++;
  673. }
  674. FLASH_If_Write(&FlashWriteAddress, (u32*)(LeftBytesTab),1);
  675. LeftBytes =0;
  676. /* update data pointer */
  677. ptr = (char*)(ptr+j);
  678. len = len -j;
  679. }
  680. /* write received bytes into flash */
  681. count = len/4;
  682. /* check if remaining bytes < 4 */
  683. i= len%4;
  684. if (i>0)
  685. {
  686. if (TotalReceived != size)
  687. {
  688. /* store bytes in LeftBytesTab */
  689. LeftBytes=0;
  690. for(;i>0;i--)
  691. LeftBytesTab[LeftBytes++] = *(char*)(ptr+ len-i);
  692. }
  693. else count++;
  694. }
  695. FLASH_If_Write(&FlashWriteAddress, (u32*)ptr ,count);
  696. }
  697. uint32_t ReturnFlashWriteAddress(void)
  698. {
  699. return FlashWriteAddress;
  700. }
  701. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/