diff --git a/Makefile b/Makefile index 4138886..ccf379f 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ LED_SERIAL_PIN ?= 14 # --------------- esp-link modules config options --------------- # Optional Modules mqtt -MODULES ?= mqtt rest syslog +MODULES ?= mqtt rest syslog web-server # --------------- esphttpd config options --------------- @@ -220,6 +220,10 @@ ifneq (,$(findstring syslog,$(MODULES))) CFLAGS += -DSYSLOG endif +ifneq (,$(findstring web-server,$(MODULES))) + CFLAGS += -DWEBSERVER +endif + # which modules (subdirectories) of the project to include in compiling LIBRARIES_DIR = libraries MODULES += espfs httpd user serial cmd esp-link diff --git a/esp-link/main.c b/esp-link/main.c index 06aa61e..1edef55 100644 --- a/esp-link/main.c +++ b/esp-link/main.c @@ -31,6 +31,7 @@ #include "log.h" #include "gpio.h" #include "cgiservices.h" +#include "web-server.h" #ifdef SYSLOG #include "syslog.h" @@ -157,7 +158,7 @@ void user_init(void) { //os_printf("espFsInit %s\n", res?"ERR":"ok"); // mount the http handlers httpdInit(builtInUrls, 80); - httpdespfsInit(); + webServerInit(); // init the wifi-serial transparent bridge (port 23) serbridgeInit(23, 2323); diff --git a/espfs/espfs.c b/espfs/espfs.c index 8657fd4..39f2e12 100644 --- a/espfs/espfs.c +++ b/espfs/espfs.c @@ -155,54 +155,78 @@ int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { return (int)flags; } +void ICACHE_FLASH_ATTR espFsIteratorInit(EspFsContext *ctx, EspFsIterator *iterator) +{ + if( ctx->data == NULL ) + { + iterator->ctx = NULL; + return; + } + iterator->ctx = ctx; + iterator->p = ctx->data; +} + +int ICACHE_FLASH_ATTR espFsIteratorNext(EspFsIterator *iterator) +{ + if( iterator->ctx == NULL ) + return 0; + + char * p = iterator->p; + + iterator->node = p; + EspFsHeader * hdr = &iterator->header; + espfs_memcpy(iterator->ctx, hdr, p, sizeof(EspFsHeader)); + + if (hdr->magic!=ESPFS_MAGIC) { +#ifdef ESPFS_DBG + os_printf("Magic mismatch. EspFS image broken.\n"); +#endif + return 0; + } + if (hdr->flags&FLAG_LASTFILE) { + //os_printf("End of image.\n"); + return 0; + } + + p += sizeof(EspFsHeader); + + //Grab the name of the file. + espfs_memcpy(iterator->ctx, iterator->name, p, sizeof(iterator->name)); + + p+=hdr->nameLen+hdr->fileLenComp; + if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val + iterator->p = p; + return 1; +} + //Open a file and return a pointer to the file desc struct. EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) { - if (ctx->data == NULL) { + EspFsIterator it; + espFsIteratorInit(ctx, &it); + if (it.ctx == NULL) { #ifdef ESPFS_DBG os_printf("Call espFsInit first!\n"); #endif return NULL; } - char *p=ctx->data; - char *hpos; - char namebuf[256]; - EspFsHeader h; - EspFsFile *r; //Strip initial slashes while(fileName[0]=='/') fileName++; - //Go find that file! - while(1) { - hpos=p; - //Grab the next file header. - espfs_memcpy(ctx, &h, p, sizeof(EspFsHeader)); - if (h.magic!=ESPFS_MAGIC) { -#ifdef ESPFS_DBG - os_printf("Magic mismatch. EspFS image broken.\n"); -#endif - return NULL; - } - if (h.flags&FLAG_LASTFILE) { - //os_printf("End of image.\n"); - return NULL; - } - //Grab the name of the file. - p+=sizeof(EspFsHeader); - espfs_memcpy(ctx, namebuf, p, sizeof(namebuf)); -// os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n", -// namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags); - if (os_strcmp(namebuf, fileName)==0) { + + //Search the file + while( espFsIteratorNext(&it) ) + { + if (os_strcmp(it.name, fileName)==0) { //Yay, this is the file we need! - p+=h.nameLen; //Skip to content. - r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem + EspFsFile * r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem //os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile)); if (r==NULL) return NULL; r->ctx = ctx; - r->header=(EspFsHeader *)hpos; - r->decompressor=h.compression; - r->posComp=p; - r->posStart=p; + r->header=(EspFsHeader *)it.node; + r->decompressor=it.header.compression; + r->posComp=it.node + it.header.nameLen + sizeof(EspFsHeader); + r->posStart=it.node + it.header.nameLen + sizeof(EspFsHeader); r->posDecomp=0; - if (h.compression==COMPRESS_NONE) { + if (it.header.compression==COMPRESS_NONE) { r->decompData=NULL; } else { #ifdef ESPFS_DBG @@ -212,10 +236,8 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) { } return r; } - //We don't need this file. Skip name and file - p+=h.nameLen+h.fileLenComp; - if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val } + return NULL; } //Read len bytes from the given file into buff. Returns the actual amount of bytes read. diff --git a/espfs/espfs.h b/espfs/espfs.h index cab1896..609df36 100644 --- a/espfs/espfs.h +++ b/espfs/espfs.h @@ -1,6 +1,8 @@ #ifndef ESPFS_H #define ESPFS_H +#include "espfsformat.h" + typedef enum { ESPFS_INIT_RESULT_OK, ESPFS_INIT_RESULT_NO_IMAGE, @@ -15,6 +17,14 @@ typedef enum { typedef struct EspFsFile EspFsFile; typedef struct EspFsContext EspFsContext; +typedef struct { + EspFsHeader header; + EspFsContext *ctx; + char name[256]; + char *node; + char * p; +} EspFsIterator; + extern EspFsContext * espLinkCtx; extern EspFsContext * userPageCtx; @@ -25,5 +35,7 @@ int espFsFlags(EspFsFile *fh); int espFsRead(EspFsFile *fh, char *buff, int len); void espFsClose(EspFsFile *fh); +void espFsIteratorInit(EspFsContext *ctx, EspFsIterator *iterator); +int espFsIteratorNext(EspFsIterator *iterator); #endif \ No newline at end of file diff --git a/httpd/httpdespfs.c b/httpd/httpdespfs.c index 8beadca..9321aad 100644 --- a/httpd/httpdespfs.c +++ b/httpd/httpdespfs.c @@ -13,21 +13,11 @@ Connector to let httpd use the espfs filesystem to serve the files in it. * ---------------------------------------------------------------------------- */ #include "httpdespfs.h" -#include "config.h" // The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression. // If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.) static const char *gzipNonSupportedMessage = "HTTP/1.0 501 Not implemented\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 52\r\n\r\nYour browser does not accept gzip-compressed data.\r\n"; -void ICACHE_FLASH_ATTR httpdespfsInit() -{ - espFsInit(userPageCtx, (void *)getUserPageSectionStart(), ESPFS_FLASH); - if( espFsIsValid( userPageCtx ) ) - os_printf("Valid user file system found!\n"); - else - os_printf("No user file system found!\n"); -} - //This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding //path in the filesystem and if it exists, passes the file through. This simulates what a normal //webserver would do with static files. diff --git a/httpd/httpdespfs.h b/httpd/httpdespfs.h index 95c5f50..847a8b6 100644 --- a/httpd/httpdespfs.h +++ b/httpd/httpdespfs.h @@ -7,8 +7,6 @@ #include "cgi.h" #include "httpd.h" -void httpdespfsInit(); - int cgiEspFsHook(HttpdConnData *connData); //int cgiEspFsTemplate(HttpdConnData *connData); //int ICACHE_FLASH_ATTR cgiEspFsHtml(HttpdConnData *connData); diff --git a/web-server/web-server.c b/web-server/web-server.c new file mode 100644 index 0000000..ddfd0ec --- /dev/null +++ b/web-server/web-server.c @@ -0,0 +1,34 @@ +#include "web-server.h" + +#include "espfs.h" +#include "config.h" + +void ICACHE_FLASH_ATTR webServerBrowseFiles() +{ + EspFsIterator it; + espFsIteratorInit(userPageCtx, &it); + { + while( espFsIteratorNext(&it) ) + { + if( strlen(it.name) >= 6 ) + { + if( os_strcmp( it.name + strlen(it.name)-5, ".html" ) == 0 ) + { + os_printf("%s\n", it.name); // TODO + } + } + } + } +} + +void ICACHE_FLASH_ATTR webServerInit() +{ + espFsInit(userPageCtx, (void *)getUserPageSectionStart(), ESPFS_FLASH); + if( espFsIsValid( userPageCtx ) ) { + os_printf("Valid user file system found!\n"); + webServerBrowseFiles(); + } + else + os_printf("No user file system found!\n"); +} + diff --git a/web-server/web-server.h b/web-server/web-server.h new file mode 100644 index 0000000..5917605 --- /dev/null +++ b/web-server/web-server.h @@ -0,0 +1,9 @@ +#ifndef WEB_SERVER_H +#define WEB_SERVER_H + +#include + +void webServerInit(); + +#endif /* WEB_SERVER_H */ +