I want to store a html file in flash and use that file for webserver.
I just want to hit whole html file not like reading it and use that variable in netconn_write(); function to hit that page.
please the the code as follows. is there any api to hit that file directly from flash?
Code: Select all
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "freertos/portmacro.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "tcpip_adapter.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "esp_vfs.h"
#include "esp_vfs_fat.h"
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
static char* TAG = "webserver-file";
#include "lwip/err.h"
#include "string.h"
// Handle of the wear levelling library instance
static wl_handle_t s_wl_handle = WL_INVALID_HANDLE;
// Mount path for the partition
const char *base_path = "/spiflash";
const static char http_html_hdr[] =
"HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
const static char http_index_hml[] ="<!DOCTYPE html>"
"<html>"
"<body>"
"<form action=\"/action_page.php\">"
"Select a file: <input type=\"file\" name=\"myFile\"><br><br>"
"<input type=\"submit\">"
"</form>"
"</body>"
"</html>";
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/api.h"
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
printf("got ip\n");
printf("ip: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.ip));
printf("netmask: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.netmask));
printf("gw: " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.gw));
printf("\n");
fflush(stdout);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}
static void initialise_wifi(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
wifi_config_t sta_config = {
.sta = {
.ssid = "niruha",
.password = "1234567890",
.bssid_set = false
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
}
static void
http_server_netconn_serve(struct netconn *conn)
{
struct netbuf *inbuf;
char *buf;
u16_t buflen;
err_t err;
/* Read the data from the port, blocking if nothing yet there.
We assume the request (the part we care about) is in one netbuf */
err = netconn_recv(conn, &inbuf);
if (err == ERR_OK) {
netbuf_data(inbuf, (void**)&buf, &buflen);
// strncpy(_mBuffer, buf, buflen);
/* Is this an HTTP GET command? (only check the first 5 chars, since
there are other formats for GET, and we're keeping it very simple )*/
printf("buffer = %s \n", buf);
if (buflen>=5 &&
buf[0]=='G' &&
buf[1]=='E' &&
buf[2]=='T' &&
buf[3]==' ' &&
buf[4]=='/' ) {
printf("buf[5] = %c\n", buf[5]);
/* Send the HTML header
* subtract 1 from the size, since we dont send the \0 in the string
* NETCONN_NOCOPY: our data is const static, so no need to copy it
*/
// Open file for reading
ESP_LOGI(TAG, "Reading file");
FILE* f = fopen("/spiflash/hello.txt", "rb");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[500];
fgets(line, sizeof(line), f);
fclose(f);
// strip newline
char *pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
netconn_write(conn, http_html_hdr, sizeof(http_html_hdr)-1, NETCONN_NOCOPY); // Open renamed file for reading
netconn_write(conn, line, strlen(line)-1, NETCONN_NOCOPY);
}
}
/* Close the connection (server closes in HTTP) */
netconn_close(conn);
/* Delete the buffer (netconn_recv gives us ownership,
so we have to make sure to deallocate the buffer) */
netbuf_delete(inbuf);
}
static void http_server(void *pvParameters)
{
struct netconn *conn, *newconn;
err_t err;
conn = netconn_new(NETCONN_TCP);
netconn_bind(conn, NULL, 80);
netconn_listen(conn);
do {
err = netconn_accept(conn, &newconn);
if (err == ERR_OK) {
http_server_netconn_serve(newconn);
netconn_delete(newconn);
}
} while(err == ERR_OK);
netconn_close(conn);
netconn_delete(conn);
}
int app_main(void)
{
nvs_flash_init();
ESP_LOGI(TAG, "Mounting FAT filesystem");
// To mount device we need name of device partition, define base_path
// and allow format partition in case if it is new one and was not formated before
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true,
.allocation_unit_size = CONFIG_WL_SECTOR_SIZE
};
esp_err_t err = esp_vfs_fat_spiflash_mount(base_path, "storage", &mount_config, &s_wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
return;
}
ESP_LOGI(TAG, "Opening file");
FILE *f = fopen("/spiflash/hello.txt", "wb");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "%s\n",http_index_hml);
fclose(f);
ESP_LOGI(TAG, "File written");
initialise_wifi();
xTaskCreate(&http_server, "http_server", 1024*4, NULL, 5, NULL);
return 0;
}