Merge branch 'stable' into _7m9/dev/http
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/pr Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/pr Build is passing
				
			This commit is contained in:
		
						commit
						a9b3928e57
					
				
					 13 changed files with 159 additions and 156 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -21,7 +21,7 @@ clean: | |||
| 
 | ||||
| firmware_docker: | ||||
| 	sh -c "docker build -t fiatlux_firmware_env docker/firmware" | ||||
| 	sh -c "docker run --volume "$$(pwd)"/firmware:/app/firmware fiatlux_firmware_env make -C firmware all" | ||||
| 	sh -c "docker run --volume "$$(pwd)"/firmware:/app/firmware fiatlux_firmware_env make -C firmware html all" | ||||
| 
 | ||||
| pcb_docker: | ||||
| 	sh -c "docker build -t fiatlux_pcb_env docker/pcb" | ||||
|  |  | |||
|  | @ -13,7 +13,7 @@ git submodule update --init --recursive | |||
| ### Build Requirements | ||||
| 
 | ||||
|  - make | ||||
|  - bash gawk perl | ||||
|  - bash gawk | ||||
|  - g++ gcc | ||||
|  - libc6-dev | ||||
|  - flex bison | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ RUN cd app; git clone --recursive https://github.com/SuperHouse/esp-open-rtos.gi | |||
| RUN cd app; sed -i 's/GNU bash, version (3\\\.\[1-9\]|4)/GNU bash, version (3.[1-9]|4|5)/g' modules/sdk/crosstool-NG/configure.ac; mkdir -p modules/sdk/crosstool-NG/.build/tarballs; wget https://github.com/libexpat/libexpat/releases/download/R_2_1_0/expat-2.1.0.tar.gz -O modules/sdk/crosstool-NG/.build/tarballs/expat-2.1.0.tar.gz | ||||
| RUN cd app/modules/sdk; export CT_EXPERIMENTAL=y; export CT_ALLOW_BUILD_AS_ROOT=y; export CT_ALLOW_BUILD_AS_ROOT_SURE=y; make standalone=y -j$(nproc); wget -N https://raw.githubusercontent.com/espressif/esptool/master/esptool.py -O xtensa-lx106-elf/bin/esptool.py | ||||
| USER 0 | ||||
| RUN apt remove --purge -y python2 && apt autoremove --purge -y && apt install -y python3 python3-serial perl | ||||
| RUN apt remove --purge -y python2 && apt autoremove --purge -y && apt install -y python3 python3-serial | ||||
| RUN apt install -y --reinstall python-is-python3 | ||||
| USER 1000 | ||||
| WORKDIR /app | ||||
|  |  | |||
							
								
								
									
										4
									
								
								firmware/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								firmware/.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -142,5 +142,5 @@ dkms.conf | |||
| 
 | ||||
| *.remove | ||||
| firmware/ | ||||
| fsdata/fsdata.c | ||||
| compile_commands.json | ||||
| build/ | ||||
| compile_commands.json | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| PROGRAM=fiatlux | ||||
| 
 | ||||
| EXTRA_CFLAGS=-O3 -Ifsdata | ||||
| EXTRA_CFLAGS=-O3 -Ibuild/gen | ||||
| 
 | ||||
| EXTRA_COMPONENTS=extras/i2s_dma extras/ws2812_i2s extras/dhcpserver extras/rboot-ota extras/mbedtls extras/httpd extras/sntp extras/cpp_support | ||||
| 
 | ||||
|  | @ -10,11 +10,12 @@ FLASH_MODE = dio | |||
| 
 | ||||
| include ../modules/rtos/common.mk | ||||
| 
 | ||||
| html: fsdata/fsdata.c | ||||
| html: build/gen/fsdata.c | ||||
| 
 | ||||
| fsdata/fsdata.c: fsdata/fs/index.html fsdata/fs/404.html fsdata/fs/css/picnic.min.css fsdata/fs/css/style.css fsdata/fs/js/smoothie_min.js | ||||
| build/gen/fsdata.c: webdir/index.html webdir/404.html webdir/css/picnic.min.css webdir/css/style.css webdir/js/smoothie_min.js | ||||
| 	@echo "Generating fsdata.." | ||||
| 	cd fsdata && ./makefsdata | ||||
| 	@mkdir -p $(dir $@) | ||||
| 	@./mkwebfs.py --gzip -o $@ $^ | ||||
| 
 | ||||
| test: unittest systest | ||||
| 
 | ||||
|  | @ -24,4 +25,4 @@ unittest: | |||
| systest: | ||||
| 	true | ||||
| 
 | ||||
| .NOTPARALLEL: html all | ||||
| .NOTPARALLEL: html all | ||||
|  |  | |||
|  | @ -1,22 +0,0 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
| 	<head> | ||||
| 		<meta charset="utf-8"> | ||||
| 		<meta name="viewport" content="width=device-width, user-scalable=no"> | ||||
| 		<link rel="shortcut icon" href="img/favicon.png"> | ||||
| 		<title>HTTP Server</title> | ||||
| 	</head> | ||||
| 	<body> | ||||
| 		<ul class="navbar"> | ||||
| 			<li><a href="/">Home</a></li> | ||||
| 			<li><a href="websockets">WebSockets</a></li> | ||||
| 			<li><a href="about">About</a></li> | ||||
| 		</ul> | ||||
| 
 | ||||
| 		<div class="grid main"> | ||||
| 			<h1>404 - Page not found</h1> | ||||
| 			<div class="alert alert-error">Sorry, the page you are requesting was not found on this server.</div> | ||||
| 		</div> | ||||
| 	</body> | ||||
| </html> | ||||
| 
 | ||||
|  | @ -1,114 +0,0 @@ | |||
| #!/usr/bin/perl | ||||
| 
 | ||||
| $incHttpHeader = 1; | ||||
| 
 | ||||
| open(OUTPUT, "> fsdata.c"); | ||||
| print(OUTPUT "#include \"httpd/fsdata.h\"\n\n"); | ||||
| 
 | ||||
| chdir("fs"); | ||||
| open(FILES, "find . -type f |"); | ||||
| 
 | ||||
| while($file = <FILES>) { | ||||
| 
 | ||||
|     # Do not include files in CVS directories nor backup files. | ||||
|     if($file =~ /(CVS|~)/) { | ||||
|         next; | ||||
|     } | ||||
| 
 | ||||
|     chop($file); | ||||
| 
 | ||||
|     if($incHttpHeader == 1) { | ||||
|         open(HEADER, "> /tmp/header") || die $!; | ||||
|         if($file =~ /404/) { | ||||
|             print(HEADER "HTTP/1.0 404 File not found\r\n"); | ||||
|         } else { | ||||
|             print(HEADER "HTTP/1.0 200 OK\r\n"); | ||||
|         } | ||||
|         print(HEADER "lwIP/1.4.1 (http://savannah.nongnu.org/projects/lwip)\r\n"); | ||||
|         if($file =~ /\.html$/ || $file =~ /\.htm$/ || $file =~ /\.shtml$/ || $file =~ /\.shtm$/ || $file =~ /\.ssi$/) { | ||||
|             print(HEADER "Content-type: text/html\r\n"); | ||||
|         } elsif($file =~ /\.js$/) { | ||||
|             print(HEADER "Content-type: application/x-javascript\r\n\r\n"); | ||||
|         } elsif($file =~ /\.css$/) { | ||||
|             print(HEADER "Content-type: text/css\r\n\r\n"); | ||||
|         } elsif($file =~ /\.ico$/) { | ||||
|             print(HEADER "Content-type: image/x-icon\r\n\r\n"); | ||||
|         } elsif($file =~ /\.gif$/) { | ||||
|             print(HEADER "Content-type: image/gif\r\n"); | ||||
|         } elsif($file =~ /\.png$/) { | ||||
|             print(HEADER "Content-type: image/png\r\n"); | ||||
|         } elsif($file =~ /\.jpg$/) { | ||||
|             print(HEADER "Content-type: image/jpeg\r\n"); | ||||
|         } elsif($file =~ /\.bmp$/) { | ||||
|             print(HEADER "Content-type: image/bmp\r\n\r\n"); | ||||
|         } elsif($file =~ /\.class$/) { | ||||
|             print(HEADER "Content-type: application/octet-stream\r\n"); | ||||
|         } elsif($file =~ /\.ram$/) { | ||||
|             print(HEADER "Content-type: audio/x-pn-realaudio\r\n"); | ||||
|         } else { | ||||
|             print(HEADER "Content-type: text/plain\r\n"); | ||||
|         } | ||||
|         print(HEADER "\r\n"); | ||||
|         close(HEADER); | ||||
| 
 | ||||
|         unless($file =~ /\.plain$/ || $file =~ /cgi/) { | ||||
|             system("cat /tmp/header $file > /tmp/file"); | ||||
|         } else { | ||||
|             system("cp $file /tmp/file"); | ||||
|         } | ||||
|     } else { | ||||
|         system("cp $file /tmp/file"); | ||||
|     } | ||||
| 
 | ||||
|     open(FILE, "/tmp/file"); | ||||
|     unlink("/tmp/file"); | ||||
|     unlink("/tmp/header"); | ||||
| 
 | ||||
|     $file =~ s/\.//; | ||||
|     $fvar = $file; | ||||
|     $fvar =~ s-/-_-g; | ||||
|     $fvar =~ s-\.-_-g; | ||||
| 
 | ||||
|     print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); | ||||
|     print(OUTPUT "\t/* $file */\n\t"); | ||||
|     for($j = 0; $j < length($file); $j++) { | ||||
|         printf(OUTPUT "0x%02X, ", unpack("C", substr($file, $j, 1))); | ||||
|     } | ||||
|     printf(OUTPUT "0,\n"); | ||||
| 
 | ||||
| 
 | ||||
|     $i = 0; | ||||
|     while(read(FILE, $data, 1)) { | ||||
|         if($i == 0) { | ||||
|             print(OUTPUT "\t"); | ||||
|         } | ||||
|         printf(OUTPUT "0x%02X, ", unpack("C", $data)); | ||||
|         $i++; | ||||
|         if($i == 10) { | ||||
|             print(OUTPUT "\n"); | ||||
|             $i = 0; | ||||
|         } | ||||
|     } | ||||
|     print(OUTPUT "};\n\n"); | ||||
|     close(FILE); | ||||
|     push(@fvars, $fvar); | ||||
|     push(@files, $file); | ||||
| } | ||||
| 
 | ||||
| for($i = 0; $i < @fvars; $i++) { | ||||
|     $file = $files[$i]; | ||||
|     $fvar = $fvars[$i]; | ||||
| 
 | ||||
|     if($i == 0) { | ||||
|         $prevfile = "NULL"; | ||||
|     } else { | ||||
|         $prevfile = "file" . $fvars[$i - 1]; | ||||
|     } | ||||
|     print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{\n$prevfile,\ndata$fvar, "); | ||||
|     print(OUTPUT "data$fvar + ". (length($file) + 1) .",\n"); | ||||
|     print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) .",\n"); | ||||
|     print(OUTPUT $incHttpHeader."\n}};\n\n"); | ||||
| } | ||||
| 
 | ||||
| print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); | ||||
| print(OUTPUT "#define FS_NUMFILES $i\n"); | ||||
							
								
								
									
										112
									
								
								firmware/mkwebfs.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										112
									
								
								firmware/mkwebfs.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,112 @@ | |||
| #!/usr/bin/env python3 | ||||
| import os | ||||
| import gzip | ||||
| import argparse | ||||
| 
 | ||||
| parser = argparse.ArgumentParser() | ||||
| parser.add_argument('-o', '--output', help='Output file name', default='stdout') | ||||
| parser.add_argument('-W', '--webroot', help='Output file name', default='webdir/') | ||||
| parser.add_argument('--gzip', dest='gzip', action='store_true') | ||||
| parser.add_argument('--no-gzip', dest='gzip', action='store_false') | ||||
| parser.set_defaults(gzip=False) | ||||
| parser.add_argument('--header', dest='header', action='store_true') | ||||
| parser.add_argument('--no-header', dest='header', action='store_false') | ||||
| parser.set_defaults(header=True) | ||||
| parser.add_argument('input', nargs='+', default=os.getcwd()) | ||||
| args = parser.parse_args() | ||||
| 
 | ||||
| 
 | ||||
| def dumpBin2CHex(f, b): | ||||
|     oStr = "\t" | ||||
|     n = 0 | ||||
|     for val in b: | ||||
|         oStr += hex(val) + ", " | ||||
|         n += 1 | ||||
|         if n % 8 == 0: | ||||
|             oStr += "\n\t" | ||||
|     oStr += "\n" | ||||
|     f.write(oStr) | ||||
| 
 | ||||
| 
 | ||||
| f_fsdata_c = open(args.output, 'w') | ||||
| f_fsdata_c.write('#include "httpd/fsdata.h"\n\n') | ||||
| 
 | ||||
| httpFiles = [file for file in args.input if (args.webroot in file)] | ||||
| 
 | ||||
| lastFileStruct = "NULL" | ||||
| 
 | ||||
| for file in httpFiles: | ||||
|     response = b'' | ||||
| 
 | ||||
|     webPath = ("/" + file.removeprefix(args.webroot)).replace("//", "/") | ||||
|     print("{} > {}".format(file, webPath)) | ||||
| 
 | ||||
|     if args.header: | ||||
|         if ("404" in file): | ||||
|             response = b'HTTP/1.0 404 File not found\r\n' | ||||
|         else: | ||||
|             response = b'HTTP/1.0 200 OK\r\n' | ||||
|         response += b"lwIP/1.4.1 (http://savannah.nongnu.org/projects/lwip)\r\n" | ||||
|         fext = file.split('.')[-1] | ||||
|         ctype = b'Content-type: text/plain\r\n' | ||||
|         if (fext.endswith("html") or fext.endswith("htm") or fext.endswith("shtml") or fext.endswith( | ||||
|                 "shtm") or fext.endswith("ssi")): | ||||
|             ctype = b'Content-type: text/html\r\n' | ||||
|         if (fext.endswith("js")): | ||||
|             ctype = b'Content-type: application/x-javascript\r\n' | ||||
|         if (fext.endswith("css")): | ||||
|             ctype = b'Content-type: text/css\r\n' | ||||
|         if (fext.endswith("ico")): | ||||
|             ctype = b'Content-type: image/x-icon\r\n' | ||||
|         if (fext.endswith("gif")): | ||||
|             ctype = b'Content-type: image/gif\r\n' | ||||
|         if (fext.endswith("png")): | ||||
|             ctype = b'Content-type: image/png\r\n' | ||||
|         if(fext.endswith("jpg")): | ||||
|             ctype = b'Content-type: image/jpeg\r\n' | ||||
|         if(fext.endswith("bmp")): | ||||
|             ctype = b'Content-type: image/bmp\r\n' | ||||
|         if(fext.endswith("class")): | ||||
|             ctype = b'Content-type: application/octet-stream\r\n' | ||||
|         if(fext.endswith("ram")): | ||||
|             ctype = b'Content-type: audio/x-pn-realaudio\r\n' | ||||
|         response += ctype | ||||
| 
 | ||||
|         binFile = open(file, 'rb') | ||||
|         binData = binFile.read() | ||||
|         compEff = False | ||||
|         if args.gzip: | ||||
|             compData = gzip.compress(binData, 9) | ||||
|             if len(compData) < len(binData): | ||||
|                 compEff = True | ||||
|                 print("- Compressed from {} to {}".format(len(binData), len(compData))) | ||||
|                 binData = compData | ||||
|             else: | ||||
|                 print("- Compression skipped Orig: {} Comp: {}".format(len(binData), len(compData))) | ||||
|         binFile.close() | ||||
| 
 | ||||
|         if compEff: | ||||
|             response += b'Content-Encoding: gzip\r\n' | ||||
|         response += b"\r\n" | ||||
|         response += binData | ||||
|         binFile.close() | ||||
|         escFile = file.replace("/", "_").replace(".", "_") | ||||
|         escFileData = "data_" + escFile | ||||
|         escFileFile = "file_" + escFile | ||||
| 
 | ||||
|         f_fsdata_c.write('static const unsigned char {}[] = {{\n'.format(escFileData)) | ||||
|         f_fsdata_c.write('\t/* LOCAL:{} */\n'.format(file)) | ||||
|         f_fsdata_c.write('\t/* WEB:  {} */\n'.format(webPath)) | ||||
|         fnameBin = webPath.encode("ascii") + b'\0' | ||||
|         dumpBin2CHex(f_fsdata_c, fnameBin) | ||||
|         dumpBin2CHex(f_fsdata_c, response) | ||||
|         f_fsdata_c.write("};\n\n") | ||||
| 
 | ||||
|         f_fsdata_c.write("const struct fsdata_file {}[] = {{{{\n  {},\n  {}, {} + {}, sizeof({}) - {}, 1 }}}};\n\n" | ||||
|                 .format(escFileFile, lastFileStruct, escFileData, escFileData, len(fnameBin), escFileData, len(fnameBin))) | ||||
|         # TODO: The last value is 1 if args.header == True | ||||
|         lastFileStruct = escFileFile | ||||
| 
 | ||||
| f_fsdata_c.write("\n") | ||||
| f_fsdata_c.write("#define FS_ROOT {}\n\n".format(lastFileStruct)) | ||||
| f_fsdata_c.write("#define FS_NUMFILES {}\n\n".format(len(httpFiles))) | ||||
							
								
								
									
										22
									
								
								firmware/webdir/404.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								firmware/webdir/404.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| <!DOCTYPE html> | ||||
| <html> | ||||
| <head> | ||||
| 	<meta charset="utf-8"> | ||||
| 	<meta name="viewport" content="width=device-width, user-scalable=no"> | ||||
| 	<link rel="shortcut icon" href="img/favicon.png"> | ||||
| 	<title>HTTP Server</title> | ||||
| </head> | ||||
| <body> | ||||
| <ul class="navbar"> | ||||
| 	<li><a href="/">Home</a></li> | ||||
| 	<li><a href="websockets">WebSockets</a></li> | ||||
| 	<li><a href="about">About</a></li> | ||||
| </ul> | ||||
| 
 | ||||
| <div class="grid main"> | ||||
| 	<h1>404 - Page not found</h1> | ||||
| 	<div class="alert alert-error">Sorry, the page you are requesting was not found on this server.</div> | ||||
| </div> | ||||
| </body> | ||||
| </html> | ||||
| 
 | ||||
|  | @ -6,15 +6,15 @@ main { | |||
| 	margin-right: auto; | ||||
| } | ||||
| 
 | ||||
| canvas{ | ||||
| canvas { | ||||
| 	width: 100%; | ||||
| } | ||||
| 
 | ||||
| main section:target ~ section, main section#io, main section#wifi,  main section#ota  { | ||||
| main section:target ~ section, main section#io, main section#wifi, main section#ota { | ||||
| 	display: none; | ||||
| } | ||||
| 
 | ||||
| main section:target{ | ||||
| main section:target { | ||||
| 	display: block !important; | ||||
| } | ||||
| 
 | ||||
|  | @ -22,30 +22,34 @@ main section:target{ | |||
| 	width: 100%; | ||||
| 	display: table; | ||||
| } | ||||
| .table>.row{ | ||||
| 
 | ||||
| .table > .row { | ||||
| 	display: table-row; | ||||
| } | ||||
| .table>.row:nth-child(2n) { | ||||
| 	background: rgba(17,17,17,0.05); | ||||
| 
 | ||||
| .table > .row:nth-child(2n) { | ||||
| 	background: rgba(17, 17, 17, 0.05); | ||||
| } | ||||
| .table>.row>*{ | ||||
| 
 | ||||
| .table > .row > * { | ||||
| 	display: table-cell; | ||||
| 	padding: .3em 2.4em .3em .6em; | ||||
| } | ||||
| .table>header.row>*{ | ||||
| 
 | ||||
| .table > header.row > * { | ||||
| 	text-align: left; | ||||
| 	font-weight: 900; | ||||
| 	color: #fff; | ||||
| 	background-color: #0074d9; | ||||
| } | ||||
| 
 | ||||
| .table>.row>input{ | ||||
| .table > .row > input { | ||||
| 	border: none; | ||||
| 	background: none; | ||||
| 	font-weight: 900; | ||||
| } | ||||
| 
 | ||||
| .plain{ | ||||
| .plain { | ||||
| 	opacity: initial; | ||||
| 	width: initial; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue