Advertisement
Guest User

Untitled

a guest
Jan 17th, 2019
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.74 KB | None | 0 0
  1. /*
  2. * Netconn server example is based on single "user" thread
  3. * which listens for new connections and accepts them.
  4. *
  5. * When a new client is accepted by server,
  6. * separate thread for client is created where
  7. * data is read, processed and send back to user
  8. */
  9. #include "netconn_server.h"
  10. #include "esp/esp.h"
  11. #include "fsdata.c"
  12. #include "lfs.h"
  13. #include "esp/esp_mem.h"
  14. #include "esp/esp_conn.h"
  15.  
  16. extern lfs_t lfs;
  17. static lfs_file_t file_upload;
  18. static size_t DataOffset=0;
  19.  
  20. static uint8_t conn_closed=0;
  21. htmlpageState htmlpage;
  22. static char transfer_filename[80];
  23. static uint32_t DataFlag=0;
  24. static uint32_t size=0;
  25. static uint32_t ContentLengthOffset =0,BrowserFlag=0;
  26. static uint32_t TotalData=0;
  27. static uint32_t TotalReceived=0;
  28.  
  29. /* file must be allocated by caller and will be filled in by the function. */
  30. static int fs_open(char *name, struct fs_file *file);
  31.  
  32.  
  33. //static void netconn_server_processing_thread(void* const arg);
  34. static void netconn_server_process_get_requests(esp_netconn_p client, esp_pbuf_p pbuf);
  35. static void netconn_server_process_post_requests(esp_netconn_p client, esp_pbuf_p pbuf, size_t len);
  36. static void netconn_server_process_data_packets(esp_netconn_p client, esp_pbuf_p pbuf, size_t len);
  37.  
  38.  
  39. static const char http_crnl_2[4] =
  40. /* "\r\n--" */
  41. {0xd, 0xa,0x2d,0x2d};
  42.  
  43. /**
  44. * \brief           Main page response file
  45. */
  46. //static const uint8_t
  47. //resp_data_mainpage_top[] = ""
  48. //"HTTP/1.1 200 OK\r\n"
  49. //"Content-Type: text/html\r\n"
  50. //"\r\n"
  51. //"<html>"
  52. //"   <head>"
  53. //"       <link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\" />"
  54. //"       <meta http-equiv=\"refresh\" content=\"1\" />"
  55. //"   </head>"
  56. //"   <body>"
  57. //"       <p>Netconn driven website!</p>"
  58. //"       <p>Total system up time: <b>";
  59.  
  60. /**
  61. * \brief           Bottom part of main page
  62. */
  63. //static const uint8_t
  64. //resp_data_mainpage_bottom[] = ""
  65. //"       </b></p>"
  66. //"   </body>"
  67. //"</html>";
  68.  
  69. /**
  70. * \brief           Style file response
  71. */
  72. //static const uint8_t
  73. //resp_data_style[] = ""
  74. //"HTTP/1.1 200 OK\r\n"
  75. //"Content-Type: text/css\r\n"
  76. //"\r\n"
  77. //"body { color: red; font-family: Tahoma, Arial; };";
  78.  
  79. const char *netconn_get_string_error(espr_t res)
  80. {
  81.   switch(res){
  82.   case espCLOSED:
  83.     return "Connection closed by client\r\n";
  84.   case espTIMEOUT:
  85.     return "Connection receive timeout occurs\r\n";
  86.   case espPARERR:
  87.     return "Wrong parameters on function call\r\n";
  88.   case espERRMEM:
  89.     return "Memory error occurred\r\n";
  90.   case espCONT:
  91.     return "There is still some command to be processed in current command\r\n";
  92.   case espINPROG:
  93.     return "Operation is in progress\r\n";
  94.   case espERRNOIP:
  95.     return "Station does not have IP address\r\n";
  96.   case espERRNOFREECONN:
  97.     return "There is no free connection available to start\r\n";
  98.   case espERRCONNTIMEOUT:
  99.     return "Timeout received when connection to access point\r\n";
  100.   case espERRPASS:
  101.     return "Invalid password for access point\r\n";
  102.   case espERRNOAP:
  103.     return "No access point found with specific SSID and MAC address\r\n";
  104.   case espERRCONNFAIL:
  105.     return "Connection failed to access point\r\n";
  106.   case espERRWIFINOTCONNECTED:
  107.     return "Wifi not connected to access point\r\n";
  108.   case espERRNODEVICE:
  109.     return "Device is not present\r\n";
  110.   case espERRBLOCKING:
  111.     return "Blocking mode command is not allowed\r\n";
  112.   case espERR:
  113.     return "Undocumented error\r\n";
  114.   }
  115.   return "";
  116. }
  117.  
  118. /**
  119. * @brief  Opens a file defined in fsdata.c ROM filesystem
  120. * @param  name : pointer to a file name
  121. * @param  file : pointer to a fs_file structure  
  122. * @retval  1 if success, 0 if fail
  123. */
  124. static int fs_open(char *name, struct fs_file *file)
  125. {
  126.   struct fsdata_file_noconst *f;
  127.  
  128.   for (f = (struct fsdata_file_noconst *)FS_ROOT; f != NULL; f = (struct fsdata_file_noconst *)f->next)
  129.   {
  130.     if (!strcmp(name, (const char*)f->name))
  131.     {
  132.       file->data = f->data;
  133.       file->len = f->len;
  134.       return 1;
  135.     }
  136.   }
  137.   return 0;
  138. }
  139.  
  140.  
  141. /**
  142. * \brief           Netconn server thread implementation
  143. * \param[in]       arg: User argument
  144. */
  145. void
  146. netconn_server_thread(void const* arg) {
  147.  
  148.   esp_netconn_p server, client;
  149.   esp_pbuf_p pbuf;
  150.   espr_t res;
  151.   size_t len;
  152.  
  153.   /*
  154.   * First create a new instance of netconn
  155.   * connection and initialize system message boxes
  156.   * to accept clients and packet buffers
  157.   */
  158.   server = esp_netconn_new(ESP_NETCONN_TYPE_TCP);
  159.   if (server != NULL) {
  160.     printf("Server netconn created\r\n");
  161.     /*
  162.     * Bind network connection to port 80
  163.     */
  164.     res = esp_netconn_bind(server, 80);
  165.     if (res == espOK) {
  166.       printf("Webserver listens on port 80\r\n");
  167.       /* Start listening for incoming connections with maximal 1 client  */
  168.       res = esp_netconn_listen_with_max_conn(server, 1);
  169.      
  170.       while (1) {
  171.         /*
  172.         * Wait and accept new client connection.
  173.         * Function will block thread until new client is connected to server
  174.         */
  175.         res = esp_netconn_accept(server, &client);
  176.         if (res == espOK) {
  177.           printf("Netconn new client connected.\r\n");
  178.           /*
  179.           * Client was accepted,
  180.           * We are now  expecting client will send to us some data.
  181.           * Wait for data and block thread for that time
  182.           */
  183.           conn_closed = 0;
  184.           while (!conn_closed) {
  185.             res = esp_netconn_receive(client, &pbuf);
  186.             if (res == espOK) {
  187.               len = esp_pbuf_length(pbuf, 1);
  188.               printf("Netconn data received, %d bytes\r\n", (int)len);
  189.              
  190.               /* dump data for debug purposes */
  191.               uint8_t *dump_buf = (uint8_t *)esp_mem_alloc(len);
  192.               if (dump_buf != NULL){
  193.                 esp_pbuf_copy(pbuf, dump_buf, len, 0);
  194.                 Dump(dump_buf,len);
  195.                 esp_mem_free(dump_buf);
  196.               }
  197.               /* process HTTP GET requests */
  198.               if (esp_pbuf_strfind(pbuf, "GET /", 0) == 0) {
  199.                 netconn_server_process_get_requests(client, pbuf);
  200.               }
  201.               /* process HTTP POST requests */
  202.               else if (esp_pbuf_strfind(pbuf, "POST /", 0) == 0) {
  203.                 netconn_server_process_post_requests(client, pbuf, len);
  204.               }
  205.               else if ((DataFlag >=1) && (htmlpage == FileUploadPage)) {
  206.                 netconn_server_process_data_packets(client, pbuf, len);
  207.               }
  208.               /* free memory after usage! */
  209.               esp_pbuf_free(pbuf);              
  210.             }
  211.             else {
  212.               printf("[HTTP] %s", netconn_get_string_error(res));
  213.               if (res == espCLOSED) {
  214.                 break;
  215.               }              
  216.               esp_netconn_close(client);
  217.               conn_closed=1;
  218.             }          
  219.           } // END while (!conn_closed);
  220.         } // END if (res == espOK)
  221.         if (client != NULL){
  222.           esp_netconn_delete(client);
  223.           client = NULL;
  224.         }
  225.       } // END while (1)
  226.     } else {
  227.       printf("Netconn server cannot bind to port\r\n");
  228.     }
  229.   } else {
  230.     printf("Cannot create server netconn\r\n");
  231.   }
  232.   esp_netconn_delete(server);                 /* Delete netconn structure */
  233.   esp_sys_thread_terminate(NULL);             /* Terminate current thread */
  234. }
  235.  
  236. /**
  237. * \brief           Thread to process single active connection
  238. * \param[in]       arg: Thread argument
  239. */
  240. //static void
  241. //netconn_server_processing_thread(void* const arg) {
  242. //  esp_netconn_p client;
  243. //  esp_pbuf_p pbuf, p = NULL;
  244. //  espr_t res;
  245. //  size_t len;
  246. //  
  247. //  client = arg;                               /* Client handle is passed to argument */
  248. //  
  249. //  printf("A new connection accepted!\r\n");   /* Print simple message */
  250. //  
  251. //  do {
  252. //    /*
  253. //    * Client was accepted, we are now
  254. //    * expecting client will send to us some data
  255. //    *
  256. //    * Wait for data and block thread for that time
  257. //    */
  258. //    res = esp_netconn_receive(client, &pbuf);
  259. //    
  260. //    if (res == espOK) {
  261. //      len = esp_pbuf_length(pbuf, 1);
  262. //      printf("Netconn data received, %d bytes\r\n", (int)len);
  263. //
  264. //      uint8_t *dump_buf = (uint8_t *)esp_mem_alloc(len);
  265. //      if (dump_buf != NULL){
  266. //        esp_pbuf_copy(pbuf, dump_buf, len, 0);
  267. //        Dump(dump_buf,len);
  268. //        esp_mem_free(dump_buf);
  269. //      }
  270. //      
  271. //      /*
  272. //      * Check if all headers were received
  273. //      */
  274. //      if (p == NULL) {
  275. //        p = pbuf;                       /* Set as first buffer */
  276. //      } else {
  277. //        esp_pbuf_cat(p, pbuf);          /* Concatenate buffers together */
  278. //      }
  279. //      if (esp_pbuf_strfind(pbuf, "\r\n\r\n", 0) != ESP_SIZET_MAX) {
  280. //        
  281. //        /* process HTTP GET requests */
  282. //        if (esp_pbuf_strfind(pbuf, "GET /", 0) != ESP_SIZET_MAX) {
  283. //          netconn_server_process_get_requests(client, pbuf);
  284. //        }
  285. //        /* process HTTP POST requests */
  286. //        else if (esp_pbuf_strfind(pbuf, "POST /", 0) != ESP_SIZET_MAX) {
  287. //          netconn_server_process_post_requests(client, pbuf);
  288. //        }
  289. //        esp_netconn_close(client);      /* Close netconn connection */
  290. //        esp_pbuf_free(p);               /* Do not forget to free memory after usage! */
  291. //        p = NULL;
  292. //        break;
  293. //      }
  294. //    }
  295. //  } while (res == espOK);
  296. //  
  297. //  if (p != NULL) {                            /* Free received data */
  298. //    esp_pbuf_free(p);
  299. //    p = NULL;
  300. //  }
  301. //  esp_netconn_delete(client);                 /* Destroy client memory */
  302. //  esp_sys_thread_terminate(NULL);             /* Terminate this thread */
  303. //}
  304.  
  305. /**
  306. * \brief           process http get requests
  307. * \param[in]       client: client conection
  308. * \param[in]       pbuf: request information
  309. */
  310. static void
  311. netconn_server_process_get_requests(esp_netconn_p client, esp_pbuf_p pbuf){
  312.  
  313.   struct fs_file file = {0, 0};
  314.  
  315.   if (esp_pbuf_strfind(pbuf, "GET /resetmcu.cgi", 0) == 0){
  316.     if (htmlpage == UploadDonePage){
  317.       htmlpage = ResetDonePage;
  318.       /* send reset.html page */
  319.       if (fs_open("/reset.html", &file)){
  320.         esp_netconn_write(client, file.data, file.len);
  321.         esp_netconn_flush(client);
  322.       }
  323.       /* Close netconn connection */
  324.       esp_netconn_close(client);
  325.       conn_closed = 1;
  326.       printf("Server netconn closed 1\r\n");
  327.      
  328.       /* Generate a software reset */
  329.       NVIC_SystemReset();
  330.       while(1);
  331.     }
  332.     else {
  333.       /* Bad HTTP requests */
  334.       printf ("[HTTP] Bad HTTP request\n");
  335.       htmlpage = LoginPage;
  336.       DataFlag = 0;
  337.       BrowserFlag = 0;
  338.     }
  339.   }
  340.   else if (esp_pbuf_strfind(pbuf, "GET /images/MRG.png", 0) == 0){
  341.     if (htmlpage == LoginPage){
  342.       /* send image MRG.png page */
  343.       if (fs_open("/images/MRG.png", &file)){
  344.         esp_netconn_write(client, file.data, file.len);
  345.         esp_netconn_flush(client);
  346.       }
  347.       /* Close netconn connection */
  348.       esp_netconn_close(client);      
  349.       conn_closed = 1;
  350.       printf("Server netconn closed 2\r\n");
  351.     }
  352.     else {
  353.       /* Bad HTTP requests */
  354.       printf ("[HTTP] Bad HTTP request\n");
  355.       htmlpage = LoginPage;
  356.       DataFlag = 0;
  357.       BrowserFlag = 0;
  358.     }
  359.   }
  360.   else if (esp_pbuf_strfind(pbuf, "GET / HTTP", 0) == 0){
  361.     htmlpage = LoginPage;
  362.     DataFlag = 0;
  363.     BrowserFlag = 0;
  364.     /* send index.html page */
  365.     if (fs_open("/index.html", &file)){
  366.       esp_netconn_write(client, file.data, file.len);
  367.       esp_netconn_flush(client);
  368.     }
  369.     /* Close netconn connection */
  370.     esp_netconn_close(client);      
  371.     conn_closed = 1;
  372.     printf("Server netconn closed 3\r\n");
  373.   }
  374.  
  375. }
  376.  
  377. /**
  378. * \brief           process http get requests
  379. * \param[in]       client: client conection
  380. * \param[in]       pbuf: request information
  381. */
  382. static void
  383. netconn_server_process_post_requests(esp_netconn_p client, esp_pbuf_p pbuf, size_t len){
  384.  
  385.   struct fs_file file = {0, 0};
  386.   size_t offset;
  387.   char *filename;
  388.  
  389.   /* process POST request for checking login */
  390.   if (esp_pbuf_strfind(pbuf, "POST /checklogin.cgi", 0) == 0){
  391.     if (htmlpage == LoginPage){
  392.       /* parse packet for the username & password */
  393.       char login[LOGIN_SIZE];
  394.       sprintf((char *)login,"username=%s&password=%s",USERID,PASSWORD);
  395.       offset = esp_pbuf_strfind(pbuf, login, 0);
  396.       if (offset != ESP_SIZET_MAX) {
  397.         /* correct user and password */
  398.         htmlpage = FileUploadPage;
  399.         filename = "/upload.html";
  400.       } else {
  401.         /* incorrect user and/or password -> reload index page */
  402.         htmlpage = LoginPage;
  403.         filename = "/index.html";
  404.       }
  405.       /* send requested page */
  406.       if (fs_open(filename, &file)){
  407.         esp_netconn_write(client, file.data, file.len);
  408.         esp_netconn_flush(client);
  409.       }
  410.       /* Close netconn connection */
  411.       esp_netconn_close(client);      
  412.       conn_closed = 1;
  413.       printf("Server netconn closed 4\r\n");
  414.     }
  415.     else {
  416.       /* Bad HTTP requests */
  417.       printf ("[HTTP] Bad HTTP request\n");
  418.       htmlpage = LoginPage;
  419.       DataFlag = 0;
  420.       BrowserFlag = 0;
  421.     }
  422.   }
  423.   else
  424.   /* process POST request for file upload and incoming data packets after POST request*/
  425.   if ((esp_pbuf_strfind(pbuf, "POST /upload.cgi",0) == 0) && (htmlpage == FileUploadPage)) {
  426.     /* POST Packet received */
  427.     DataOffset = 0;
  428.     BrowserFlag=0;
  429.     TotalReceived =0;
  430.     /* parse packet for Content-length field */
  431.     offset = esp_pbuf_memfind(pbuf, "Content-Length: ", 16, 0);
  432.     if (offset != ESP_SIZET_MAX){
  433.       char sizestring[8];
  434.       ContentLengthOffset = offset;
  435.       TotalReceived = len - offset;
  436.       esp_pbuf_copy(pbuf, sizestring, sizeof(sizestring), ContentLengthOffset+16);
  437.       size = atoi(sizestring);
  438.     }
  439.     /* parse packet for the application/json field */
  440.     offset = esp_pbuf_memfind(pbuf, "Content-Type: application/json", 30, 0);
  441.     if (offset != ESP_SIZET_MAX){
  442.       /* case of Mozilla Firefox : we receive data in the POST packet */
  443.       DataOffset = offset + 34;
  444.     }
  445.     else {
  446.         /* IE doenst send type as json. Instead it send as plain text */
  447.         offset = esp_pbuf_memfind(pbuf, "Content-Type: text/plain", 24, 0);
  448.         if (offset != ESP_SIZET_MAX){
  449.           DataOffset = offset + 28;
  450.         }
  451.     }
  452.     /* case of MSIE8 : we do not receive data in the POST packet */
  453.     if (DataOffset==0){
  454.       DataFlag++;
  455.       BrowserFlag++;
  456.       return;
  457.     }
  458.     netconn_server_process_data_packets(client, pbuf, len);
  459.   }
  460. }
  461.  
  462. /**
  463. * \brief           process http get requests
  464. * \param[in]       client: client conection
  465. * \param[in]       pbuf: request information
  466. */
  467. static void
  468. netconn_server_process_data_packets(esp_netconn_p client, esp_pbuf_p pbuf, size_t len){
  469.    
  470.   struct fs_file file = {0, 0};
  471.   size_t offset;
  472.  
  473.   if (((DataFlag ==1)&&(BrowserFlag==1)) || ((DataFlag ==0)&&(BrowserFlag==0))) {
  474.     if ((DataFlag ==0)&&(BrowserFlag==0)) {
  475.       DataFlag+=2;
  476.     }
  477.     else if ((DataFlag ==1)&&(BrowserFlag==1)) {
  478.       /* parse packet for the application/json field */
  479.       offset = esp_pbuf_memfind(pbuf, "Content-Type: application/json", 30, 0);
  480.       if (offset != ESP_SIZET_MAX){
  481.         DataOffset = offset + 34;
  482.         TotalReceived += len;
  483.         DataFlag++;
  484.       }
  485.       else {
  486.         /* IE doenst send type as json. Instead it send as plain text */
  487.         offset = esp_pbuf_memfind(pbuf, "Content-Type: text/plain", 24, 0);
  488.         if (offset != ESP_SIZET_MAX){
  489.           DataOffset = offset + 28;
  490.           TotalReceived += len;
  491.           DataFlag++;
  492.         }
  493.       }
  494.     }
  495.     /* parse packet for the filename field */
  496.     offset =  esp_pbuf_memfind(pbuf, "filename=\"", 10, 0);
  497.     if (offset != ESP_SIZET_MAX){
  498.       size_t end_offset =  esp_pbuf_memfind(pbuf, "\"\r\n", 3, offset+10);
  499.       esp_pbuf_copy(pbuf, transfer_filename, end_offset-offset, offset+10);
  500.       char *p = NULL;
  501.       /* look for name terminator */
  502.       p = strrchr(transfer_filename, '"');
  503.       if (p != NULL)
  504.         *p = 0;
  505.       /* remove any path (IE), taking only filename itself */
  506.       p = strrchr(transfer_filename, '\\');
  507.       if (p == NULL)
  508.         p = strrchr(transfer_filename, '/');
  509.       if (p != NULL)
  510.         strcpy(transfer_filename, p+1);
  511.     }  
  512.     else {
  513.       htmlpage = FileUploadPage;
  514.       /* send requested page */
  515.       if (fs_open("/upload.html", &file)){
  516.         esp_netconn_write(client, file.data, file.len);
  517.         esp_netconn_flush(client);
  518.       }
  519.       /* Close netconn connection */
  520.       esp_netconn_close(client);      
  521.       conn_closed = 1;
  522.       printf("Server netconn closed 7\r\n");
  523.       DataFlag=0;
  524.       return;
  525.     }
  526.     printf("[HTTP] Recebendo arquivo: %s\tSize=%d\r\n", transfer_filename, size);
  527.     TotalData = 0;
  528.     lfs_file_open(&lfs, &file_upload, "config.json", LFS_O_RDWR | LFS_O_CREAT);
  529.   }
  530.   /* DataFlag >1 => the packet is data only  */
  531.   else {
  532.     TotalReceived +=len;
  533.     DataOffset = 0;
  534.   }
  535.  
  536.   //ptr  = (char*)(data + DataOffset);
  537.   len -= DataOffset;
  538.  
  539.   uint8_t *buffer = esp_mem_alloc(len);
  540.   if (buffer == NULL){
  541.     printf("Can't allocate memory.!!!!");
  542.     return;
  543.   }
  544.   esp_pbuf_copy(pbuf, buffer, len, DataOffset);
  545.  
  546.   /* check if last data packet */
  547.   if (TotalReceived >= size)
  548.   {
  549.     /* if last packet need to remove the http boundary tag */
  550.     /* parse packet for "\r\n--" starting from end of data */
  551.     offset =  esp_pbuf_memfind(pbuf, http_crnl_2, 4, 0);
  552.     if (offset != ESP_SIZET_MAX){      
  553.       len = offset;
  554.     }
  555.    
  556.     /* write data in Flash */
  557.     if (len){
  558.       printf("[HTTP] Gravando no arquivo: %s\tsplit=%d\r\n", transfer_filename, len);
  559.       lfs_file_write(&lfs, &file_upload, buffer, len);
  560.       printf("[HTTP] Fechando arquivo: %s\r\n", transfer_filename);
  561.       lfs_file_close(&lfs, &file_upload);
  562.       /* update Total data received counter */
  563.       TotalData +=len;
  564.     }
  565.  
  566.     DataFlag=0;
  567.     printf("[HTTP] Arquivo %s recebido com sucesso! [Size=%d]\r\n", transfer_filename, TotalData);
  568.     htmlpage = UploadDonePage;
  569.     /* send uploaddone.html page */
  570.     if (fs_open("/uploaddone.html", &file)){
  571.       esp_netconn_write(client, file.data, file.len);
  572.       esp_netconn_flush(client);
  573.     }
  574.     /* Close netconn connection */
  575.     esp_netconn_close(client);      
  576.     conn_closed = 1;
  577.     printf("Server netconn closed 8\r\n");
  578.   }
  579.   /* not last data packet */
  580.   else {
  581.     /* write data in flash */
  582.     if(len){
  583.       printf("[HTTP] Gravando no arquivo: %s\tsplit=%d\r\n", transfer_filename, len);
  584.       lfs_file_write(&lfs, &file_upload, buffer, len);
  585.       /* update Total data received counter */
  586.       TotalData +=len;
  587.     }
  588.   }
  589.   printf("TotalReceived: %d \tTotalData: %d\r\n",TotalReceived, TotalData);
  590.   esp_mem_free(buffer);
  591. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement