Skip to content

Commit

Permalink
spiffs support works
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaminwater committed Feb 5, 2019
1 parent abe8048 commit 366e894
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 53 deletions.
10 changes: 6 additions & 4 deletions main/core/httpd/httpd.c
Expand Up @@ -29,6 +29,7 @@
#define IS_URI_SEP(c) (c == '?' || c == '&' || c == '=')

esp_err_t download_get_handler(httpd_req_t *req);
esp_err_t init_spiffs(void);

/* static size_t get_char_count(const char *uri) {
size_t i = 0;
Expand Down Expand Up @@ -178,32 +179,33 @@ httpd_uri_t uri_setstr = {
.user_ctx = NULL
};

/* URI handler for getting uploaded files */
httpd_uri_t file_download = {
.uri = "/fs/*", // Match all URIs of type /path/to/file (except index.html)
.uri = "/fs/?*",
.method = HTTP_GET,
.handler = download_get_handler,
.user_ctx = NULL // Pass server data as context
.user_ctx = NULL
};

static httpd_handle_t server = NULL;

static httpd_handle_t start_webserver(void) {

httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.uri_match_fn = httpd_uri_match_wildcard;

if (httpd_start(&server, &config) == ESP_OK) {
httpd_register_uri_handler(server, &file_download);
httpd_register_uri_handler(server, &uri_geti);
httpd_register_uri_handler(server, &uri_seti);
httpd_register_uri_handler(server, &uri_getstr);
httpd_register_uri_handler(server, &uri_setstr);
httpd_register_uri_handler(server, &file_download);
}
return server;
}

void init_httpd() {
ESP_LOGI(SGO_LOG_EVENT, "@MQTT Intializing MQTT task");

init_spiffs();
start_webserver();
}
95 changes: 62 additions & 33 deletions main/core/httpd/httpd_fs.c
Expand Up @@ -24,8 +24,8 @@
#include <dirent.h>

#include "esp_err.h"
#include "esp_log.h"

#include "../log/log.h"
#include "esp_vfs.h"
#include "esp_spiffs.h"
#include "esp_http_server.h"
Expand All @@ -37,10 +37,7 @@

/* Scratch buffer size */
#define FILE_BUFSIZE 8192

char file_buffer[FILE_BUFSIZE];

static const char *TAG = "file_server";
char file_buffer[FILE_BUFSIZE] = {0};

/* Send HTTP response with a run-time generated html consisting of
* a list of all files and folders under the requested path */
Expand All @@ -62,26 +59,28 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req)
dir = opendir(fullpath);
const size_t entrypath_offset = strlen(fullpath);

ESP_LOGI(SGO_LOG_NOSEND, "http_resp_dir_html %s", fullpath);

if (!dir) {
/* If opening directory failed then send 404 server error */
httpd_resp_send_404(req);
return ESP_OK;
}

httpd_resp_set_type(req, "text/plain");
/* Iterate over all files / folders and fetch their names and sizes */
while ((entry = readdir(dir)) != NULL) {
entrytype = (entry->d_type == DT_DIR ? "directory" : "file");

strncpy(fullpath + entrypath_offset, entry->d_name, sizeof(fullpath) - entrypath_offset);
if (stat(fullpath, &entry_stat) == -1) {
ESP_LOGE(TAG, "Failed to stat %s : %s", entrytype, entry->d_name);
ESP_LOGE(SGO_LOG_NOSEND, "Failed to stat %s : %s", entrytype, entry->d_name);
continue;
}
sprintf(entrysize, "%ld", entry_stat.st_size);
ESP_LOGI(TAG, "Found %s : %s (%s bytes)", entrytype, entry->d_name, entrysize);
ESP_LOGI(SGO_LOG_NOSEND, "Found %s : %s (%s bytes)", entrytype, entry->d_name, entrysize);

/* Send chunk of HTML file containing table entries with file name and size */
httpd_resp_sendstr_chunk(req, "<tr><td><a href=\"");
httpd_resp_sendstr_chunk(req, req->uri);
httpd_resp_sendstr_chunk(req, entry->d_name);
if (entry->d_type == DT_DIR) {
Expand All @@ -93,15 +92,10 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req)
httpd_resp_sendstr_chunk(req, entrytype);
httpd_resp_sendstr_chunk(req, ";");
httpd_resp_sendstr_chunk(req, entrysize);
httpd_resp_sendstr_chunk(req, "\n");
}
closedir(dir);

/* Finish the file list table */
httpd_resp_sendstr_chunk(req, "</tbody></table>");

/* Send remaining chunk of HTML file to complete it */
httpd_resp_sendstr_chunk(req, "</body></html>");

/* Send empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
Expand All @@ -113,7 +107,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req)
/* Set HTTP response content type according to file extension */
static esp_err_t set_content_type_from_file(httpd_req_t *req)
{
if (IS_FILE_EXT(req->uri, ".pdf")) {
if (IS_FILE_EXT(req->uri, ".html")) {
return httpd_resp_set_type(req, "text/html");
} else if (IS_FILE_EXT(req->uri, ".jpeg")) {
return httpd_resp_set_type(req, "image/jpeg");
Expand All @@ -139,37 +133,38 @@ static esp_err_t http_resp_file(httpd_req_t *req)
strcpy(filepath, FILE_BASE_PATH);

/* Concatenate the requested file path */
strcat(filepath, req->uri);
strcat(filepath, &(req->uri[3]));
ESP_LOGI(SGO_LOG_NOSEND, "http_resp_file %s", filepath);
if (stat(filepath, &file_stat) == -1) {
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
ESP_LOGE(SGO_LOG_NOSEND, "Failed to stat file : %s", filepath);
/* If file doesn't exist respond with 404 Not Found */
httpd_resp_send_404(req);
return ESP_OK;
}

ESP_LOGI(SGO_LOG_NOSEND, "Sending file : %s (%ld bytes)...", filepath, file_stat.st_size);
set_content_type_from_file(req);

fd = fopen(filepath, "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
ESP_LOGE(SGO_LOG_NOSEND, "Failed to read existing file : %s", filepath);
/* If file exists but unable to open respond with 500 Server Error */
httpd_resp_set_status(req, "500 Server Error");
httpd_resp_sendstr(req, "Failed to read existing file!");
return ESP_OK;
}

ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filepath, file_stat.st_size);
set_content_type_from_file(req);

/* Retrieve the pointer to file_buffer buffer for temporary storage */
char *chunk = file_buffer;
size_t chunksize;
do {
/* Read file in chunks into the file_buffer buffer */
chunksize = fread(chunk, 1, FILE_BUFSIZE, fd);
chunksize = fread(file_buffer, 1, FILE_BUFSIZE, fd);
ESP_LOGI(SGO_LOG_NOSEND, "%d", chunksize);

/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
if (httpd_resp_send_chunk(req, file_buffer, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
ESP_LOGE(SGO_LOG_NOSEND, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Send error message with status code */
Expand All @@ -183,7 +178,7 @@ static esp_err_t http_resp_file(httpd_req_t *req)

/* Close file after sending complete */
fclose(fd);
ESP_LOGI(TAG, "File sending complete");
ESP_LOGI(SGO_LOG_NOSEND, "File sending complete");

/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
Expand All @@ -193,13 +188,47 @@ static esp_err_t http_resp_file(httpd_req_t *req)
/* Handler to download a file kept on the server */
esp_err_t download_get_handler(httpd_req_t *req)
{
// Check if the target is a directory
if (req->uri[strlen(req->uri) - 1] == '/') {
// In so, send an html with directory listing
http_resp_dir_html(req);
ESP_LOGI(SGO_LOG_NOSEND, "download_get_handler");
// Check if the target is a directory
if (req->uri[strlen(req->uri) - 1] == '/') {
// In so, send an html with directory listing
http_resp_dir_html(req);
} else {
// Else send the file
http_resp_file(req);
}
return ESP_OK;
}

esp_err_t init_spiffs(void) {
ESP_LOGI(SGO_LOG_EVENT, "Initializing SPIFFS");

esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = true
};

esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(SGO_LOG_EVENT, "Failed to mount or format filesystem");
} else if (ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(SGO_LOG_EVENT, "Failed to find SPIFFS partition");
} else {
// Else send the file
http_resp_file(req);
ESP_LOGE(SGO_LOG_EVENT, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return ESP_OK;
return ESP_FAIL;
}

size_t total = 0, used = 0;
ret = esp_spiffs_info(NULL, &total, &used);
if (ret != ESP_OK) {
ESP_LOGE(SGO_LOG_EVENT, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
return ESP_FAIL;
}

ESP_LOGI(SGO_LOG_NOSEND, "Partition size: total=%d, used=%d", total, used);
return ESP_OK;
}
2 changes: 1 addition & 1 deletion main/core/mqtt/mqtt.c
Expand Up @@ -113,7 +113,7 @@ static void mqtt_task(void *param) {
if (connected) {
memset(buf_out, 0, MAX_LOG_QUEUE_ITEM_SIZE);
while (xQueueReceive(log_queue, buf_out, 0)) {
esp_mqtt_client_publish(client, log_channel, (char *)buf_out, 0, 2, 1);
esp_mqtt_client_publish(client, log_channel, (char *)buf_out, 0, 0, 0);
memset(buf_out, 0, MAX_LOG_QUEUE_ITEM_SIZE);
}
}
Expand Down
10 changes: 5 additions & 5 deletions main/sht21/sht21.c
Expand Up @@ -48,10 +48,10 @@ static bool send_sht21_cmd(int portId, uint8_t cmd_b) {
esp_err_t ret = i2c_master_cmd_begin(portId, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(SGO_LOG_NOSEND, "@SHT21_%d Write bus is busy", boxId);
ESP_LOGI(SGO_LOG_EVENT, "@SHT21_%d Write bus is busy", boxId);
return false;
} else if (ret != ESP_OK) {
ESP_LOGI(SGO_LOG_NOSEND, "@SHT21_%d Write failed", boxId);
ESP_LOGI(SGO_LOG_EVENT, "@SHT21_%d Write failed", boxId);
return false;
}
return true;
Expand All @@ -73,16 +73,16 @@ static uint16_t read_sht21(int portId) {
esp_err_t ret = i2c_master_cmd_begin(portId, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGI(SGO_LOG_NOSEND, "@SHT21_%d Read bus is busy", boxId);
ESP_LOGI(SGO_LOG_EVENT, "@SHT21_%d Read bus is busy", boxId);
return 255;
} else if (ret != ESP_OK) {
ESP_LOGI(SGO_LOG_NOSEND, "@SHT21_%d Read failed", boxId);
ESP_LOGI(SGO_LOG_EVENT, "@SHT21_%d Read failed", boxId);
return 255;
}

if(!crc_checksum(v, 2, v[2])) {
//reset();
ESP_LOGI(SGO_LOG_NOSEND, "@SHT21_%d Wrong crc", boxId);
ESP_LOGI(SGO_LOG_EVENT, "@SHT21_%d Wrong crc", boxId);
return 255;
}

Expand Down
10 changes: 5 additions & 5 deletions partitions.csv
@@ -1,8 +1,8 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x9000, 0x4000
otadata, data, ota, 0xd000, 0x2000
phy_init, data, phy, 0xf000, 0x1000
ota_0, 0, ota_0, 0x10000, 0x178000
ota_1, 0, ota_1, , 0x178000
storage, data, spiffs, , 0x4000
otadata, data, ota, , 0x2000
phy_init, data, phy, , 0x1000
ota_0, 0, ota_0, , 0x1f0000
ota_1, 0, ota_1, , 0x1f0000
storage, data, spiffs, , 0x8000
3 changes: 1 addition & 2 deletions sdkconfig
Expand Up @@ -878,8 +878,7 @@ CONFIG_SPIFFS_PAGE_SIZE=256
CONFIG_SPIFFS_OBJ_NAME_LEN=32
CONFIG_SPIFFS_USE_MAGIC=y
CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
CONFIG_SPIFFS_META_LENGTH=4
CONFIG_SPIFFS_USE_MTIME=y
CONFIG_SPIFFS_META_LENGTH=0

#
# Debug Configuration
Expand Down
Binary file modified spiffs.bin
Binary file not shown.
8 changes: 8 additions & 0 deletions spiffs_fs/index.html
@@ -0,0 +1,8 @@
<html>
<head>
<title>SuperGreenDriver</title>
</head>
</body>
lol
</body>
</html>
6 changes: 3 additions & 3 deletions write_spiffs.sh
Expand Up @@ -2,6 +2,6 @@

set -e

mkspiffs -c spiffs_fs/ -b 4096 -p 256 -s 0x4000 spiffs.bin
python releases/SuperGreenOS/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 115200 write_flash -z 0x300000 spiffs.bin
rm spiffs.bin
mkspiffs -c spiffs_fs/ -b 4096 -p 256 -s 0x8000 spiffs.bin
python releases/SuperGreenOS/esptool.py --chip esp32 --port /dev/ttyUSB1 --baud 115200 write_flash -z 0x3f0000 spiffs.bin
# rm spiffs.bin

0 comments on commit 366e894

Please sign in to comment.