httpserver.c 19 KB

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