diff --git a/Makefile b/Makefile index b59319b..68bed32 100644 --- a/Makefile +++ b/Makefile @@ -101,8 +101,8 @@ LED_SERIAL_PIN ?= 14 # --------------- esp-link modules config options --------------- -# Optional Modules mqtt rest syslog web-server -MODULES ?= mqtt rest web-server +# Optional Modules: mqtt rest socket web-server syslog +MODULES ?= mqtt rest socket web-server syslog # --------------- esphttpd config options --------------- @@ -223,6 +223,10 @@ ifneq (,$(findstring web-server,$(MODULES))) CFLAGS += -DWEBSERVER endif +ifneq (,$(findstring socket,$(MODULES))) + CFLAGS += -DSOCKET +endif + # which modules (subdirectories) of the project to include in compiling LIBRARIES_DIR = libraries MODULES += espfs httpd user serial cmd esp-link @@ -411,9 +415,9 @@ tools/$(HTML_COMPRESSOR): cd tools; wget --no-check-certificate https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR) -O $(HTML_COMPRESSOR) else tools/$(HTML_COMPRESSOR): - $(Q) mkdir -p tools - cd tools; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) - cd tools; wget https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR) +# $(Q) mkdir -p tools +# cd tools; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI_COMPRESSOR) +# cd tools; wget https://htmlcompressor.googlecode.com/files/$(HTML_COMPRESSOR) endif ifeq ("$(COMPRESS_W_HTMLCOMPRESSOR)","yes") diff --git a/cmd/cmd.h b/cmd/cmd.h index d1a8b19..2cd6cec 100644 --- a/cmd/cmd.h +++ b/cmd/cmd.h @@ -48,12 +48,16 @@ typedef enum { CMD_MQTT_SUBSCRIBE, // subscribe to a topic CMD_MQTT_LWT, // set the last-will-topic and messge - CMD_REST_SETUP = 20, - CMD_REST_REQUEST, - CMD_REST_SETHEADER, + CMD_REST_SETUP = 20, // set-up callbacks + CMD_REST_REQUEST, // do REST request + CMD_REST_SETHEADER, // define header CMD_WEB_DATA = 30, // MCU pushes data using this command CMD_WEB_REQ_CB, // esp-link WEB callback + + CMD_SOCKET_SETUP = 40, // set-up callbacks + CMD_SOCKET_SEND, // send data over UDP socket + } CmdName; typedef void (*cmdfunc_t)(CmdPacket *cmd); diff --git a/cmd/handlers.c b/cmd/handlers.c index 1b45e1f..3697490 100644 --- a/cmd/handlers.c +++ b/cmd/handlers.c @@ -14,6 +14,9 @@ #include #endif #include +#ifdef SOCKET +#include +#endif #ifdef CMD_DBG #define DBG(format, ...) do { os_printf(format, ## __VA_ARGS__); } while(0) @@ -53,6 +56,10 @@ const CmdList commands[] = { {CMD_REST_SETHEADER, "REST_SETHDR", REST_SetHeader}, #endif {CMD_WEB_DATA, "WEB_DATA", WEB_Data}, +#ifdef SOCKET + {CMD_SOCKET_SETUP, "SOCKET_SETUP", SOCKET_Setup}, + {CMD_SOCKET_SEND, "SOCKET_SEND", SOCKET_Send}, +#endif }; //===== List of registered callbacks (to uC) diff --git a/createEspFs.pl b/createEspFs.pl new file mode 100644 index 0000000..1612098 --- /dev/null +++ b/createEspFs.pl @@ -0,0 +1,114 @@ +#!/usr/bin/perl + +use strict; +use Data::Dumper; + +my $dir = shift @ARGV; +my $out = shift @ARGV; + +my $espfs = ''; + +my @structured = read_dir_structure($dir, ""); + +for my $file (@structured) +{ + my $flags = 0; + my $name = $file; + my $compression = 0; + + if( $name =~ /\.gz$/ ) + { + $flags |= 2; + $name =~ s/\.gz$//; + } + + my $head = 'esp-link
'; + + open IF, "<", "$dir/$file" or die "Can't read file: $!"; + my @fc = ; + close(IF); + my $cnt = join("", @fc); + + if( $name =~ /\.html$/ ) + { + if( ! ( $flags & 2 ) ) + { + $cnt = "$head$cnt"; + } + else + { + printf("TODO: prepend headers to GZipped HTML content!\n"); + } + } + + $name .= chr(0); + $name .= chr(0) while( (length($name) & 3) != 0 ); + + my $size = length($cnt); + + $espfs .= "ESfs"; + $espfs .= chr($flags); + $espfs .= chr($compression); + $espfs .= chr( length($name) & 255 ); + $espfs .= chr( length($name) / 256 ); + $espfs .= chr( $size & 255 ); + $espfs .= chr( ( $size / 0x100 ) & 255 ); + $espfs .= chr( ( $size / 0x10000 ) & 255 ); + $espfs .= chr( ( $size / 0x1000000 ) & 255 ); + $espfs .= chr( $size & 255 ); + $espfs .= chr( ( $size / 0x100 ) & 255 ); + $espfs .= chr( ( $size / 0x10000 ) & 255 ); + $espfs .= chr( ( $size / 0x1000000 ) & 255 ); + + $espfs .= $name; + + + + $cnt .= chr(0) while( (length($cnt) & 3) != 0 ); + $espfs .= $cnt; +} + +$espfs .= "ESfs"; +$espfs .= chr(1); +for(my $i=0; $i < 11; $i++) +{ + $espfs .= chr(0); +} + +open FH, ">", $out or die "Can't open file for write, $!"; +print FH $espfs; +close(FH); + + +exit(0); + +sub read_dir_structure +{ + my ($dir, $base) = @_; + + my @files; + + opendir my $dh, $dir or die "Could not open '$dir' for reading: $!\n"; + + while (my $file = readdir $dh) { + if ($file eq '.' or $file eq '..') { + next; + } + + my $path = "$dir/$file"; + if( -d "$path" ) + { + my @sd = read_dir_structure($path, "$base/$file"); + push @files, @sd ; + } + else + { + push @files, "$base/$file"; + } + } + + close( $dh ); + + $_ =~ s/^\/// for(@files); + return @files; +} diff --git a/esp-link-v2.2.beta2/avrflash b/esp-link-v2.2.beta2/avrflash new file mode 100755 index 0000000..20fe890 --- /dev/null +++ b/esp-link-v2.2.beta2/avrflash @@ -0,0 +1,110 @@ +#! /bin/bash +# +# Flash an AVR with optiboot using the esp-link built-in programmer +# Basically we first reset the AVR and get in sync, and then send the hex file +# +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# Thorsten von Eicken wrote this file. As long as you retain +# this notice you can do whatever you want with this stuff. If we meet some day, +# and you think this stuff is worth it, you can buy me a beer in return. +# ---------------------------------------------------------------------------- + +show_help() { + cat </dev/null; then + echo "ERROR: Cannot find curl: it is required for this script." >&2 + exit 1 +fi + +start=`date +%s` + +# ===== Parse arguments + +verbose= + +while getopts "hvx:" opt; do + case "$opt" in + h) show_help; exit 0 ;; + v) verbose=1 ;; + x) foo="$OPTARG" ;; + '?') show_help >&2; exit 1 ;; + esac +done + +# Shift off the options and optional --. +shift "$((OPTIND-1))" + +# Get the fixed arguments +if [[ $# != 2 ]]; then + show_help >&2 + exit 1 +fi +hostname=$1 +hex=$2 + +re='[-A-Za-z0-9.]+' +if [[ ! "$hostname" =~ $re ]]; then + echo "ERROR: hostname ${hostname} is not a valid hostname or ip address" >&2 + exit 1 +fi + +if [[ ! -r "$hex" ]]; then + echo "ERROR: cannot read hex file ($hex)" >&2 + exit 1 +fi + +# ===== Get AVR in sync + +[[ -n "$verbose" ]] && echo "Resetting AVR with http://$hostname/pgm/sync" >&2 +v=; [[ -n "$verbose" ]] && v=-v +sync=`curl -m 10 $v -s -w '%{http_code}' -XPOST "http://$hostname/pgm/sync"` +if [[ $? != 0 || "$sync" != 204 ]]; then + echo "Error resetting AVR" >&2 + exit 1 +fi + +while true; do + sync=`curl -m 10 $v -s "http://$hostname/pgm/sync"` + if [[ $? != 0 ]]; then + echo "Error checking sync" >&2 + exit 1 + fi + case "$sync" in + SYNC*) + echo "AVR in $sync" >&2 + break;; + "NOT READY"*) + [[ -n "$verbose" ]] && echo " Waiting for sync..." >&2 + ;; + *) + echo "Error checking sync: $sync" >&2 + exit 1 + ;; + esac + sleep 0.1 +done + +# ===== Send HEX file + +[[ -n "$verbose" ]] && echo "Sending HEX file for programming" >&2 +sync=`curl -m 10 $v -s -g -d "@$hex" "http://$hostname/pgm/upload"` +echo $sync +if [[ $? != 0 || ! "$sync" =~ ^Success ]]; then + echo "Error programming AVR" >&2 + exit 1 +fi + +sec=$(( `date +%s` - $start )) +echo "Success, took $sec seconds" >&2 +exit 0 diff --git a/esp-link-v2.2.beta2/blank.bin b/esp-link-v2.2.beta2/blank.bin new file mode 100644 index 0000000..7de9e36 --- /dev/null +++ b/esp-link-v2.2.beta2/blank.bin @@ -0,0 +1 @@ +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/esp-link-v2.2.beta2/boot_v1.5.bin b/esp-link-v2.2.beta2/boot_v1.5.bin new file mode 100644 index 0000000..e0b9508 Binary files /dev/null and b/esp-link-v2.2.beta2/boot_v1.5.bin differ diff --git a/esp-link-v2.2.beta2/user1.bin b/esp-link-v2.2.beta2/user1.bin new file mode 100644 index 0000000..9f3b3d7 Binary files /dev/null and b/esp-link-v2.2.beta2/user1.bin differ diff --git a/esp-link-v2.2.beta2/user2.bin b/esp-link-v2.2.beta2/user2.bin new file mode 100644 index 0000000..e0a0f4f Binary files /dev/null and b/esp-link-v2.2.beta2/user2.bin differ diff --git a/esp-link-v2.2.beta2/wiflash b/esp-link-v2.2.beta2/wiflash new file mode 100755 index 0000000..d8c12ea --- /dev/null +++ b/esp-link-v2.2.beta2/wiflash @@ -0,0 +1,133 @@ +#! /bin/bash +# +# Flash an esp8266 over wifi. This communicates with the esphttpd's /flash handlers +# and POSTS the correct binary depending on the parittion that needs to be flashed +# next. +# +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# Thorsten von Eicken wrote this file. As long as you retain +# this notice you can do whatever you want with this stuff. If we meet some day, +# and you think this stuff is worth it, you can buy me a beer in return. +# ---------------------------------------------------------------------------- + +show_help() { + cat < with either or +depending on its current state. Reboot the esp8266 after flashing and wait for it to come +up again. + -v Be verbose + -h show this help + +Example: ${0##*/} -v esp8266 firmware/user1.bin firmware/user2.bin + ${0##*/} 192.168.4.1 firmware/user1.bin firmware/user2.bin +EOT +} + +if ! which curl >/dev/null; then + echo "ERROR: Cannot find curl: it is required for this script." >&2 + exit 1 +fi + +start=`date +%s` + +# ===== Parse arguments + +verbose= + +while getopts "hvx:" opt; do + case "$opt" in + h) show_help; exit 0 ;; + v) verbose=1 ;; + x) foo="$OPTARG" ;; + '?') show_help >&2; exit 1 ;; + esac +done + +# Shift off the options and optional --. +shift "$((OPTIND-1))" + +# Get the fixed arguments +if [[ $# != 3 ]]; then + show_help >&2 + exit 1 +fi +hostname=$1 +user1=$2 +user2=$3 + +re='[-A-Za-z0-9.]+' +if [[ ! "$hostname" =~ $re ]]; then + echo "ERROR: hostname ${hostname} is not a valid hostname or ip address" >&2 + exit 1 +fi + +if [[ ! -r "$user1" ]]; then + echo "ERROR: cannot read user1 firmware file ($user1)" >&2 + exit 1 +fi + +if [[ ! -r "$user2" ]]; then + echo "ERROR: cannot read user2 firmware file ($user2)" >&2 + exit 1 +fi + +# ===== Retrieve the 'next' firmware required + +fw= +while true; do + [[ -n "$verbose" ]] && echo "Fetching http://$hostname/flash/next" >&2 + v=; [[ -n "$verbose" ]] && v=-v + next=`curl -m 10 $v -s "http://$hostname/flash/next"` + if [[ $? != 0 ]]; then + echo "Error retrieving http://$hostname/flash/next" >&2 + exit 1 + fi + case "$next" in + user1.bin) + echo "Flashing user1.bin" >&2 + fw="$user1" + break;; + user2.bin) + echo "Flashing user2.bin" >&2 + fw="$user2" + break;; + *) + echo "Error retrieving or parsing http://$hostname/flash/next" >&2 + exit 1 + ;; + esac +done + +#silent=-s +[[ -n "$verbose" ]] && silent= +res=`curl $silent -XPOST --data-binary "@$fw" "http://$hostname/flash/upload"` +if [[ $? != 0 ]]; then + echo "Error flashing $fw" >&2 + exit 1 +fi + +sleep 2 +echo "Rebooting into new firmware" >&2 +curl -m 10 -s "http://$hostname/flash/reboot" + +sleep 2 +echo "Waiting for ESP8266 to come back" +while true; do + [[ -n "$verbose" ]] && echo "Fetching http://$hostname/flash/next" >&2 + next2=`curl -m 10 $v -s "http://$hostname/flash/next"` + [[ -n "$verbose" ]] && echo "got: $next2" + re='user[12]\.bin' + if [[ "$next2" =~ $re ]]; then + if [[ "$next2" != "$next" ]]; then + sec=$(( `date +%s` - $start )) + echo "Success, took $sec seconds" >&2 + exit 0 + else + echo "Flashing seems to have failed and it reverted to the old firmware?" >&2 + exit 1 + fi + fi + sleep 1 +done diff --git a/socket/socket.c b/socket/socket.c new file mode 100644 index 0000000..a17f216 --- /dev/null +++ b/socket/socket.c @@ -0,0 +1,432 @@ +// Copyright 2016 by BeeGee, see LICENSE.txt +// +// Adapted from: github.com/tuanpmt/esp_bridge, Created on: Mar 4, 2015, Author: Minh +// Adapted from: rest.c, Author: Thorsten von Eicken + +#include "esp8266.h" +#include "c_types.h" +#include "ip_addr.h" +#include "socket.h" +#include "cmd.h" + +#define SOCK_DBG + +#ifdef SOCK_DBG +#define DBG_SOCK(format, ...) os_printf(format, ## __VA_ARGS__) +#else +#define DBG_SOCK(format, ...) do { } while(0) +#endif + +typedef struct { + char *host; + uint32_t port; + ip_addr_t ip; + struct espconn *pCon; + char *data; + uint16_t data_len; + uint16_t data_sent; + uint32_t resp_cb; + uint8_t conn_num; + uint8_t sock_mode; +} SocketClient; + + +// Connection pool for TCP/UDP socket clients/servers. Attached MCU's just call SOCKET_setup and this allocates +// a connection, They never call any 'free' and given that the attached MCU could restart at +// any time, we cannot really rely on the attached MCU to call 'free' ever, so better do without. +// Instead, we allocate a fixed pool of connections an round-robin. What this means is that the +// attached MCU should really use at most as many SOCKET connections as there are slots in the pool. +#define MAX_SOCKET 4 +static SocketClient socketClient[MAX_SOCKET]; +static uint8_t socketNum = 0xff; // index into socketClient for next slot to allocate + +// Any incoming data? +static void ICACHE_FLASH_ATTR +socketclient_recv_cb(void *arg, char *pusrdata, unsigned short length) { + struct espconn *pCon = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pCon->reverse; + + uint8_t clientNum = client->conn_num; + uint8_t cb_type = USERCB_RECV; + DBG_SOCK("SOCKET #%d: Received %d bytes: %s\n", client-socketClient, length, pusrdata); + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 4); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&length, 2); + cmdResponseBody(pusrdata, length); + cmdResponseEnd(); + + if (client->sock_mode != SOCKET_TCP_SERVER) { // We don't wait for a response + DBG_SOCK("SOCKET #%d: disconnect after receiving\n", client-socketClient); + espconn_disconnect(client->pCon); // disconnect from the server + } +} + +// Data is sent +static void ICACHE_FLASH_ATTR +socketclient_sent_cb(void *arg) { + struct espconn *pCon = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pCon->reverse; + + uint8_t clientNum = client->conn_num; + uint8_t cb_type = USERCB_SENT; + DBG_SOCK("SOCKET #%d: Sent\n", client-socketClient); + sint16 sentDataLen = client->data_sent; + if (client->data_sent != client->data_len) + { + // we only sent part of the buffer, send the rest + uint16_t data_left = client->data_len - client->data_sent; + if (data_left > 1400) // we have more than 1400 bytes left + { + data_left = 1400; + espconn_sent(client->pCon, (uint8_t*)(client->data+client->data_sent), 1400 ); + } + espconn_sent(client->pCon, (uint8_t*)(client->data+client->data_sent), data_left ); + client->data_sent += data_left; + } + else + { + // we're done sending, free the memory + if (client->data) os_free(client->data); + client->data = 0; + + if (client->sock_mode == SOCKET_TCP_CLIENT) { // We don't wait for a response + DBG_SOCK("SOCKET #%d: disconnect after sending\n", clientNum); + espconn_disconnect(client->pCon); + } + + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 3); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&sentDataLen, 2); + cmdResponseEnd(); + } +} + +// Connection is disconnected +static void ICACHE_FLASH_ATTR +socketclient_discon_cb(void *arg) { + struct espconn *pespconn = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pespconn->reverse; + + uint8_t clientNum = client->conn_num; + uint8_t cb_type = USERCB_CONN; + sint16 _status = CONNSTAT_DIS; + DBG_SOCK("SOCKET #%d: Disconnect\n", clientNum); + // free the data buffer, if we have one + if (client->data) os_free(client->data); + client->data = 0; + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 3); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&_status, 2); + cmdResponseEnd(); +} + +// Connection was reset +static void ICACHE_FLASH_ATTR +socketclient_recon_cb(void *arg, sint8 errType) { + struct espconn *pCon = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pCon->reverse; + + uint8_t clientNum = client->conn_num; + uint8_t cb_type = USERCB_RECO; + sint16 _errType = errType; + os_printf("SOCKET #%d: conn reset, err=%d\n", clientNum, _errType); + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 3); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&_errType, 2); + cmdResponseEnd(); + // free the data buffer, if we have one + if (client->data) os_free(client->data); + client->data = 0; +} + +// Connection is done +static void ICACHE_FLASH_ATTR +socketclient_connect_cb(void *arg) { + struct espconn *pCon = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pCon->reverse; + + uint8_t clientNum = client->conn_num; + uint8_t cb_type = USERCB_CONN; + sint16 _status = CONNSTAT_CON; + DBG_SOCK("SOCKET #%d: connected socket mode = %d\n", clientNum, client->sock_mode); + espconn_regist_disconcb(client->pCon, socketclient_discon_cb); + espconn_regist_recvcb(client->pCon, socketclient_recv_cb); + espconn_regist_sentcb(client->pCon, socketclient_sent_cb); + + DBG_SOCK("SOCKET #%d: sending %d\n", clientNum, client->data_sent); + if (client->sock_mode != SOCKET_TCP_SERVER) { // Send data after established connection only in client mode + client->data_sent = client->data_len <= 1400 ? client->data_len : 1400; + DBG_SOCK("SOCKET #%d: sending %d\n", clientNum, client->data_sent); + espconn_send(client->pCon, (uint8_t*)client->data, client->data_sent); + } + + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 3); + cmdResponseBody(&cb_type, 1); + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&_status, 2); + cmdResponseEnd(); +} + +static void ICACHE_FLASH_ATTR +socket_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) { + struct espconn *pConn = (struct espconn *)arg; + SocketClient* client = (SocketClient *)pConn->reverse; + uint8_t clientNum = client->conn_num; + + if(ipaddr == NULL) { + sint16 _errType = ESPCONN_RTE; //-4; + uint8_t cb_type = USERCB_RECO; // use Routing problem or define a new one + os_printf("SOCKET #%d DNS: Got no ip, report error\n", clientNum); + cmdResponseStart(CMD_RESP_CB, client->resp_cb, 3); + cmdResponseBody(&cb_type, 2); // Same as connection reset?? or define a new one + cmdResponseBody(&clientNum, 1); + cmdResponseBody(&_errType, 2); + cmdResponseEnd(); + return; + } + DBG_SOCK("SOCKET #%d DNS: found ip %d.%d.%d.%d\n", + clientNum, + *((uint8 *) &ipaddr->addr), + *((uint8 *) &ipaddr->addr + 1), + *((uint8 *) &ipaddr->addr + 2), + *((uint8 *) &ipaddr->addr + 3)); + if(client->ip.addr == 0 && ipaddr->addr != 0) { + os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4); + espconn_connect(client->pCon); + DBG_SOCK("SOCKET #%d: connecting...\n", clientNum); + } +} + +void ICACHE_FLASH_ATTR +SOCKET_Setup(CmdPacket *cmd) { + CmdRequest req; + uint16_t port; + uint8_t sock_mode; + int32_t err = -1; // error code in case of failure + + // start parsing the command + cmdRequest(&req, cmd); + if(cmdGetArgc(&req) != 3) { + DBG_SOCK("SOCKET Setup parse command failure: (cmdGetArgc(&req) != 3)\n"); + goto fail; + } + err--; + + // get the hostname (IP address) + uint16_t len = cmdArgLen(&req); + if (len > 128) { + DBG_SOCK("SOCKET Setup parse command failure: hostname longer than 128 characters\n"); + goto fail; // safety check + } + err--; + uint8_t *socket_host = (uint8_t*)os_zalloc(len + 1); + if (socket_host == NULL) { + DBG_SOCK("SOCKET Setup failed to alloc memory for socket_host\n"); + goto fail; + } + if (cmdPopArg(&req, socket_host, len)) { + DBG_SOCK("SOCKET Setup parse command failure: (cmdPopArg(&req, socket_host, len))\n"); + goto fail; + } + err--; + socket_host[len] = 0; + + // get the port + if (cmdPopArg(&req, (uint8_t*)&port, 2)) { + DBG_SOCK("SOCKET Setup parse command failure: cannot get port\n"); + os_free(socket_host); + goto fail; + } + err--; + + // get the socket mode + if (cmdPopArg(&req, (uint8_t*)&sock_mode, 1)) { + DBG_SOCK("SOCKET Setup parse command failure: cannot get mode\n"); + os_free(socket_host); + goto fail; + } + err--; + DBG_SOCK("SOCKET Setup listener flag\n"); + + // clear connection structures the first time + if (socketNum == 0xff) { + os_memset(socketClient, 0, MAX_SOCKET * sizeof(SocketClient)); + socketNum = 0; + } + + // allocate a connection structure + SocketClient *client = socketClient + socketNum; + uint8_t clientNum = socketNum; + socketNum = (socketNum+1)%MAX_SOCKET; + + // free any data structure that may be left from a previous connection + if (client->data) os_free(client->data); + if (client->pCon) { + if (sock_mode != SOCKET_UDP) { + if (client->pCon->proto.tcp) os_free(client->pCon->proto.tcp); + } else { + if (client->pCon->proto.udp) os_free(client->pCon->proto.udp); + } + os_free(client->pCon); + } + os_memset(client, 0, sizeof(SocketClient)); + DBG_SOCK("SOCKET #%d: Setup host=%s port=%d \n", clientNum, socket_host, port); + + client->sock_mode = sock_mode; + client->resp_cb = cmd->value; + client->conn_num = clientNum; + + client->host = (char *)socket_host; + client->port = port; + + if (sock_mode == SOCKET_UDP) { + wifi_set_broadcast_if(STATIONAP_MODE); + } + + client->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); + if (client->pCon == NULL) { + DBG_SOCK("SOCKET #%d: Setup failed to alloc memory for client_pCon\n", clientNum); + goto fail; + } + + if (sock_mode != SOCKET_UDP) { + client->pCon->type = ESPCONN_TCP; + client->pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); + if (client->pCon->proto.tcp == NULL) { + DBG_SOCK("SOCKET #%d: Setup failed to alloc memory for client->pCon->proto.tcp\n", clientNum); + goto fail; + } + } else { + client->pCon->type = ESPCONN_UDP; + client->pCon->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp)); + if (client->pCon->proto.udp == NULL) { + DBG_SOCK("SOCKET #%d: Setup failed to alloc memory for client->pCon->proto.udp\n", clientNum); + goto fail; + } + } + client->pCon->state = ESPCONN_NONE; + + os_memcpy(client->host, socket_host, 4); + if (sock_mode != SOCKET_UDP) { + client->pCon->proto.tcp->remote_port = client->port; + client->pCon->proto.tcp->local_port = client->port; // espconn_port(); + } else { + client->pCon->proto.udp->remote_port = client->port; + client->pCon->proto.udp->local_port = client->port; + } + + client->pCon->reverse = client; + + espconn_regist_sentcb(client->pCon, socketclient_sent_cb); + espconn_regist_recvcb(client->pCon, socketclient_recv_cb); + if (sock_mode == SOCKET_UDP) { + DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); + + if(UTILS_StrToIP((char *)client->host, &client->pCon->proto.udp->remote_ip)) { + espconn_create(client->pCon); + } else { + DBG_SOCK("SOCKET #%d: failed to copy remote_ip to &client->pCon->proto.udp->remote_ip\n", clientNum); + goto fail; + } + } else { + espconn_regist_reconcb(client->pCon, socketclient_recon_cb); + if (client->sock_mode == SOCKET_TCP_SERVER) { // Server mode? + DBG_SOCK("SOCKET #%d: Enable server mode on port%d\n", clientNum, client->port); + espconn_accept(client->pCon); + espconn_regist_connectcb(client->pCon, socketclient_connect_cb); + } + } + + cmdResponseStart(CMD_RESP_V, clientNum, 0); + cmdResponseEnd(); + DBG_SOCK("SOCKET #%d: setup finished\n", clientNum); + return; + +fail: + cmdResponseStart(CMD_RESP_V, err, 0); + cmdResponseEnd(); + return; +} + +void ICACHE_FLASH_ATTR +SOCKET_Send(CmdPacket *cmd) { + CmdRequest req; + cmdRequest(&req, cmd); + + // Get client + uint32_t clientNum = cmd->value; + SocketClient *client = socketClient + (clientNum % MAX_SOCKET); + DBG_SOCK("SOCKET #%d: send", clientNum); + + if (cmd->argc != 1 && cmd->argc != 2) { + DBG_SOCK("\nSOCKET #%d: send - wrong number of arguments\n", clientNum); + return; + } + + // Get data to sent + client->data_len = cmdArgLen(&req); + DBG_SOCK(" dataLen=%d", client->data_len); + + if (client->data) os_free(client->data); + client->data = (char*)os_zalloc(client->data_len); + if (client->data == NULL) { + DBG_SOCK("\nSOCKET #%d failed to alloc memory for client->data\n", clientNum); + goto fail; + } + cmdPopArg(&req, client->data, client->data_len); + DBG_SOCK(" socketData=%s", client->data); + + // client->data_len = os_sprintf((char*)client->data, socketDataSet, socketData); + + DBG_SOCK("\n"); + + DBG_SOCK("SOCKET #%d: Create connection to ip %s:%d\n", clientNum, client->host, client->port); + + if (client->sock_mode == SOCKET_TCP_SERVER) { // In TCP server mode we should be connected already and send the data immediately + remot_info *premot = NULL; + if (espconn_get_connection_info(client->pCon,&premot,0) == ESPCONN_OK){ + for (uint8 count = 0; count < client->pCon->link_cnt; count ++){ + client->pCon->proto.tcp->remote_port = premot[count].remote_port; + + client->pCon->proto.tcp->remote_ip[0] = premot[count].remote_ip[0]; + client->pCon->proto.tcp->remote_ip[1] = premot[count].remote_ip[1]; + client->pCon->proto.tcp->remote_ip[2] = premot[count].remote_ip[2]; + client->pCon->proto.tcp->remote_ip[3] = premot[count].remote_ip[3]; + DBG_SOCK("SOCKET #%d: connected to %d.%d.%d.%d:%d\n", + clientNum, + client->pCon->proto.tcp->remote_ip[0], + client->pCon->proto.tcp->remote_ip[1], + client->pCon->proto.tcp->remote_ip[2], + client->pCon->proto.tcp->remote_ip[3], + client->pCon->proto.tcp->remote_port + ); + } + client->data_sent = client->data_len <= 1400 ? client->data_len : 1400; + DBG_SOCK("SOCKET #%d: Server sending %d\n", clientNum, client->data_sent); + espconn_send(client->pCon, (uint8_t*)client->data, client->data_sent); + } + } else if (client->sock_mode != SOCKET_UDP) { // In TCP client mode we connect and send the data from the connected callback + espconn_regist_connectcb(client->pCon, socketclient_connect_cb); + + if(UTILS_StrToIP((char *)client->host, &client->pCon->proto.tcp->remote_ip)) { + DBG_SOCK("SOCKET #%d: Connect to ip %s:%d\n", clientNum, client->host, client->port); + espconn_connect(client->pCon); + } else { + DBG_SOCK("SOCKET #%d: Connect to host %s:%d\n", clientNum, client->host, client->port); + espconn_gethostbyname(client->pCon, (char *)client->host, &client->ip, socket_dns_found); + } + } else { // in UDP socket mode we send the data immediately + client->data_sent = client->data_len <= 1400 ? client->data_len : 1400; + DBG_SOCK("SOCKET #%d: sending %d bytes: %s\n", clientNum, client->data_sent, client->data); + espconn_sent(client->pCon, (uint8_t*)client->data, client->data_sent); + } + + return; + +fail: + DBG_SOCK("\n"); +} diff --git a/socket/socket.h b/socket/socket.h new file mode 100644 index 0000000..258109b --- /dev/null +++ b/socket/socket.h @@ -0,0 +1,38 @@ +/* + * socket.h + * + * Created on: Sep 16th 2016 + * Author: BeeGee + */ + +#ifndef MODULES_SOCKET_H_ +#define MODULES_SOCKET_H_ + +#include "cmd.h" + +void SOCKET_Setup(CmdPacket *cmd); +void SOCKET_Send(CmdPacket *cmd); + +// Socket mode +typedef enum { + SOCKET_TCP_CLIENT = 0, /**< TCP socket client for sending only, doesn't wait for response from server */ + SOCKET_TCP_CLIENT_LISTEN, /**< TCP socket client, waits for response from server after sending */ + SOCKET_TCP_SERVER, /**< TCP socket server */ + SOCKET_UDP, /**< UDP socket for sending and receiving UDP packets */ +} socketMode; + +// Callback type +typedef enum { + USERCB_SENT = 0, /**< Data send finished */ + USERCB_RECV, /**< Data received */ + USERCB_RECO, /**< Connection error */ + USERCB_CONN, /**< Connection event */ +} cbType; + +// Connection status +typedef enum { + CONNSTAT_DIS = 0, // Disconnected + CONNSTAT_CON, // Connected +} connStat; + +#endif /* MODULES_SOCKET_H_ */ diff --git a/syslog/syslog.c b/syslog/syslog.c index f359b85..5c88901 100644 --- a/syslog/syslog.c +++ b/syslog/syslog.c @@ -13,6 +13,7 @@ #include "syslog.h" #include "time.h" #include "task.h" +#include "sntp.h" extern void * mem_trim(void *m, size_t s); // not well documented... @@ -401,6 +402,7 @@ syslog_compose(uint8_t facility, uint8_t severity, const char *tag, const char * // create timestamp: FULL-DATE "T" PARTIAL-TIME "Z": 'YYYY-mm-ddTHH:MM:SSZ ' // as long as realtime_stamp is 0 we use tick div 10ⶠas date + uint32_t realtime_stamp = sntp_get_current_timestamp(); now = (realtime_stamp == 0) ? (se->tick / 1000000) : realtime_stamp; tp = gmtime(&now); diff --git a/syslog/syslog.h b/syslog/syslog.h index d556ee9..003ce89 100644 --- a/syslog/syslog.h +++ b/syslog/syslog.h @@ -71,7 +71,7 @@ enum syslog_facility { #define WDEV_NOW() REG_READ(0x3ff20c00) // This variable disappeared from lwip in SDK 2.0... -extern uint32_t realtime_stamp; // 1sec NTP ticker +// extern uint32_t realtime_stamp; // 1sec NTP ticker typedef struct syslog_host_t syslog_host_t; struct syslog_host_t {