diff --git a/Makefile b/Makefile index 840f7a3b..2af0707c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ .NOTPARALLEL: # SDK version NodeMCU is locked to -SDK_VER:=2.1.0 +SDK_VER:=2.2.0 # no patch: SDK_BASE_VER equals SDK_VER and sdk dir depends on sdk_extracted SDK_BASE_VER:=$(SDK_VER) @@ -13,13 +13,13 @@ SDK_DIR_DEPENDS:=sdk_extracted #SDK_DIR_DEPENDS:=sdk_patched SDK_FILE_VER:=$(SDK_BASE_VER) -SDK_FILE_SHA1:=66a4272894dc1bcec19f5f8bf79fee80f60a021b +SDK_FILE_SHA1:=8b63f1066d3560ff77f119e8ba30a9c39e7baaad #SDK_PATCH_VER:=$(SDK_VER)_patch_20160704 #SDK_PATCH_SHA1:=388d9e91df74e3b49fca126da482cf822cf1ebf1 # Ensure we search "our" SDK before the tool-chain's SDK (if any) TOP_DIR:=$(abspath $(dir $(lastword $(MAKEFILE_LIST)))) SDK_DIR:=$(TOP_DIR)/sdk/esp_iot_sdk_v$(SDK_VER) -CCFLAGS:= -I$(TOP_DIR)/sdk-overrides/include -I$(SDK_DIR)/include +CCFLAGS:= -I$(TOP_DIR)/sdk-overrides/include -I$(TOP_DIR)/app/include/lwip/app -I$(SDK_DIR)/include LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld $(LDFLAGS) ifdef DEBUG @@ -39,6 +39,7 @@ ifeq ($(OS),Windows_NT) # It is xcc AR = xt-ar CC = xt-xcc + CXX = xt-xcc NM = xt-nm CPP = xt-cpp OBJCOPY = xt-objcopy @@ -50,6 +51,7 @@ ifeq ($(OS),Windows_NT) CCFLAGS += -ffunction-sections -fno-jump-tables -fdata-sections AR = xtensa-lx106-elf-ar CC = xtensa-lx106-elf-gcc + CXX = xtensa-lx106-elf-g++ NM = xtensa-lx106-elf-nm CPP = xtensa-lx106-elf-cpp OBJCOPY = xtensa-lx106-elf-objcopy @@ -77,6 +79,7 @@ else CCFLAGS += -ffunction-sections -fno-jump-tables -fdata-sections AR = xtensa-lx106-elf-ar CC = $(WRAPCC) xtensa-lx106-elf-gcc + CXX = $(WRAPCC) xtensa-lx106-elf-g++ NM = xtensa-lx106-elf-nm CPP = $(WRAPCC) xtensa-lx106-elf-gcc -E OBJCOPY = xtensa-lx106-elf-objcopy @@ -104,6 +107,7 @@ ESPTOOL ?= ../tools/esptool.py CSRCS ?= $(wildcard *.c) +CXXSRCS ?= $(wildcard *.cpp) ASRCs ?= $(wildcard *.s) ASRCS ?= $(wildcard *.S) SUBDIRS ?= $(patsubst %/,%,$(dir $(filter-out tools/Makefile,$(wildcard */Makefile)))) @@ -112,10 +116,12 @@ ODIR := .output OBJODIR := $(ODIR)/$(TARGET)/$(FLAVOR)/obj OBJS := $(CSRCS:%.c=$(OBJODIR)/%.o) \ + $(CXXSRCS:%.cpp=$(OBJODIR)/%.o) \ $(ASRCs:%.s=$(OBJODIR)/%.o) \ $(ASRCS:%.S=$(OBJODIR)/%.o) DEPS := $(CSRCS:%.c=$(OBJODIR)/%.d) \ + $(CXXSCRS:%.cpp=$(OBJODIR)/%.d) \ $(ASRCs:%.s=$(OBJODIR)/%.d) \ $(ASRCS:%.S=$(OBJODIR)/%.d) @@ -206,9 +212,11 @@ sdk_patched: sdk_extracted $(TOP_DIR)/sdk/.patched-$(SDK_VER) $(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER): $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip mkdir -p "$(dir $@)" - (cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) ESP8266_NONOS_SDK-$(SDK_VER) && unzip $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip ESP8266_NONOS_SDK-$(SDK_VER)/lib/* ESP8266_NONOS_SDK-$(SDK_VER)/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK-$(SDK_VER)/include/* ESP8266_NONOS_SDK-$(SDK_VER)/bin/esp_init_data_default.bin) + (cd "$(dir $@)" && rm -fr esp_iot_sdk_v$(SDK_VER) ESP8266_NONOS_SDK-$(SDK_VER) && unzip $(TOP_DIR)/cache/v$(SDK_FILE_VER).zip ESP8266_NONOS_SDK-$(SDK_VER)/lib/* ESP8266_NONOS_SDK-$(SDK_VER)/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK-$(SDK_VER)/include/* ESP8266_NONOS_SDK-$(SDK_VER)/bin/esp_init_data_default_v05.bin) mv $(dir $@)/ESP8266_NONOS_SDK-$(SDK_VER) $(dir $@)/esp_iot_sdk_v$(SDK_VER) - rm -f $(SDK_DIR)/lib/liblwip.a + rm -f $(SDK_DIR)/lib/liblwip.a $(SDK_DIR)/lib/libssl.a $(SDK_DIR)/lib/libmbedtls.a + ar d $(SDK_DIR)/lib/libmain.a time.o + ar d $(SDK_DIR)/lib/libc.a lib_a-time.o touch $@ $(TOP_DIR)/sdk/.patched-$(SDK_VER): $(TOP_DIR)/cache/esp_iot_sdk_v$(SDK_PATCH_VER).zip @@ -306,6 +314,17 @@ $(OBJODIR)/%.d: %.c sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ +$(OBJODIR)/%.o: %.cpp + @mkdir -p $(OBJODIR); + $(CXX) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $< + +$(OBJODIR)/%.d: %.cpp + @mkdir -p $(OBJODIR); + @echo DEPEND: $(CXX) -M $(CFLAGS) $< + @set -e; rm -f $@; \ + sed 's,\($*\.o\)[ :]*,$(OBJODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + $(OBJODIR)/%.o: %.s @mkdir -p $(OBJODIR); $(CC) $(CFLAGS) -o $@ -c $< diff --git a/app/Makefile b/app/Makefile index c2250ead..ee472211 100644 --- a/app/Makefile +++ b/app/Makefile @@ -166,6 +166,7 @@ CONFIGURATION_DEFINES = -D__ets__ \ -DLWIP_OPEN_SRC \ -DPBUF_RSV_FOR_WLAN \ -DEBUF_LWIP \ + -DUSE_OPTIMIZE_PRINTF \ -DMBEDTLS_USER_CONFIG_FILE=\"user_mbedtls.h\" \ DEFINES += \ diff --git a/app/driver/key.c b/app/driver/key.c index afd7b142..15806514 100644 --- a/app/driver/key.c +++ b/app/driver/key.c @@ -132,9 +132,9 @@ key_50ms_cb(struct single_key_param *single_key) LOCAL void key_intr_handler(void *arg) { - struct keys_param *keys = arg; uint8 i; uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS); + struct keys_param *keys = arg; for (i = 0; i < keys->key_num; i++) { if (gpio_status & BIT(keys->single_key[i]->gpio_id)) { diff --git a/app/include/arch/cc.h b/app/include/arch/cc.h index d2ff311f..2be195ce 100755 --- a/app/include/arch/cc.h +++ b/app/include/arch/cc.h @@ -65,7 +65,7 @@ typedef uint32_t mem_ptr_t; #define U32_F "d" #define X32_F "x" - +#define LWIP_ERR_T s32_t //#define PACK_STRUCT_FIELD(x) x __attribute__((packed)) #define PACK_STRUCT_FIELD(x) x diff --git a/app/include/lwip/app/espconn.h b/app/include/lwip/app/espconn.h index 5167ce1f..9963b140 100644 --- a/app/include/lwip/app/espconn.h +++ b/app/include/lwip/app/espconn.h @@ -1,6 +1,31 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2016 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + #ifndef __ESPCONN_H__ #define __ESPCONN_H__ +#include "lwip/err.h" #include "lwip/dns.h" #include "os_type.h" #include "lwip/app/espconn_buf.h" @@ -37,8 +62,7 @@ typedef void (* espconn_reconnect_callback)(void *arg, sint8 err); #define ESPCONN_NODATA -17 /* No data can be read */ #define ESPCONN_HANDSHAKE -28 /* ssl handshake failed */ -#define ESPCONN_RESP_TIMEOUT -29 /* ssl handshake no response*/ -#define ESPCONN_PROTO_MSG -61 /* ssl application invalid */ +#define ESPCONN_SSL_INVALID_DATA -61 /* ssl application invalid */ #define ESPCONN_SSL 0x01 #define ESPCONN_NORM 0x00 @@ -121,6 +145,7 @@ enum espconn_option{ ESPCONN_NODELAY = 0x02, ESPCONN_COPY = 0x04, ESPCONN_KEEPALIVE = 0x08, + ESPCONN_MANUALRECV = 0x10, ESPCONN_END }; @@ -461,6 +486,17 @@ extern sint8 espconn_regist_sentcb(struct espconn *espconn, espconn_sent_callbac *******************************************************************************/ extern sint8 espconn_regist_write_finish(struct espconn *espconn, espconn_connect_callback write_finish_fn); +/****************************************************************************** + * FunctionName : espconn_send + * Description : sent data for client or server + * Parameters : espconn -- espconn to set for client or server + * psent -- data to send + * length -- length of data to send + * Returns : none +*******************************************************************************/ +extern sint8 espconn_send(struct espconn *espconn, uint8 *psent, uint16 length); + + /****************************************************************************** * FunctionName : espconn_sent * Description : sent data for client or server @@ -573,7 +609,163 @@ extern sint8 espconn_get_keepalive(struct espconn *espconn, uint8 level, void *o * - ESPCONN_ARG: dns client not initialized or invalid hostname *******************************************************************************/ -extern sint8 espconn_gethostbyname(struct espconn *pespconn, const char *name, ip_addr_t *addr, dns_found_callback found); +extern err_t espconn_gethostbyname(struct espconn *pespconn, const char *name, ip_addr_t *addr, dns_found_callback found); + +/****************************************************************************** + * FunctionName : espconn_abort + * Description : Forcely abort with host + * Parameters : espconn -- the espconn used to connect with the host + * Returns : result +*******************************************************************************/ + +extern sint8 espconn_abort(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_encry_connect + * Description : The function given as connection + * Parameters : espconn -- the espconn used to connect with the host + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_secure_connect(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_encry_disconnect + * Description : The function given as the disconnection + * Parameters : espconn -- the espconn used to disconnect with the host + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_secure_disconnect(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_secure_send + * Description : sent data for client or server + * Parameters : espconn -- espconn to set for client or server + * psent -- data to send + * length -- length of data to send + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_secure_send(struct espconn *espconn, uint8 *psent, uint16 length); + +/****************************************************************************** + * FunctionName : espconn_encry_sent + * Description : sent data for client or server + * Parameters : espconn -- espconn to set for client or server + * psent -- data to send + * length -- length of data to send + * Returns : none +*******************************************************************************/ + +extern sint8 espconn_secure_sent(struct espconn *espconn, uint8 *psent, uint16 length); + +/****************************************************************************** + * FunctionName : espconn_secure_set_size + * Description : set the buffer size for client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * size -- buffer size + * Returns : true or false +*******************************************************************************/ + +extern bool espconn_secure_set_size(uint8 level, uint16 size); + +/****************************************************************************** + * FunctionName : espconn_secure_get_size + * Description : get buffer size for client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * Returns : buffer size for client or server +*******************************************************************************/ + +extern sint16 espconn_secure_get_size(uint8 level); + +/****************************************************************************** + * FunctionName : espconn_secure_ca_enable + * Description : enable the certificate authenticate and set the flash sector + * as client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * flash_sector -- flash sector for save certificate + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_ca_enable(uint8 level, uint32 flash_sector ); + +/****************************************************************************** + * FunctionName : espconn_secure_ca_disable + * Description : disable the certificate authenticate as client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_ca_disable(uint8 level); + + +/****************************************************************************** + * FunctionName : espconn_secure_cert_req_enable + * Description : enable the client certificate authenticate and set the flash sector + * as client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * flash_sector -- flash sector for save certificate + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_cert_req_enable(uint8 level, uint32 flash_sector ); + +/****************************************************************************** + * FunctionName : espconn_secure_ca_disable + * Description : disable the client certificate authenticate as client or server + * Parameters : level -- set for client or server + * 1: client,2:server,3:client and server + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_cert_req_disable(uint8 level); + +/****************************************************************************** + * FunctionName : espconn_secure_set_default_certificate + * Description : Load the certificates in memory depending on compile-time + * and user options. + * Parameters : certificate -- Load the certificate + * length -- Load the certificate length + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_set_default_certificate(const uint8* certificate, uint16 length); + +/****************************************************************************** + * FunctionName : espconn_secure_set_default_private_key + * Description : Load the key in memory depending on compile-time + * and user options. + * Parameters : private_key -- Load the key + * length -- Load the key length + * Returns : result true or false +*******************************************************************************/ + +extern bool espconn_secure_set_default_private_key(const uint8* private_key, uint16 length); + +/****************************************************************************** + * FunctionName : espconn_secure_accept + * Description : The function given as the listen + * Parameters : espconn -- the espconn used to listen the connection + * Returns : result +*******************************************************************************/ + +extern sint8 espconn_secure_accept(struct espconn *espconn); + +/****************************************************************************** + * FunctionName : espconn_secure_accepts + * Description : delete the secure server host + * Parameters : espconn -- the espconn used to listen the connection + * Returns : result +*******************************************************************************/ + +extern sint8 espconn_secure_delete(struct espconn *espconn); + /****************************************************************************** * FunctionName : espconn_igmp_join @@ -593,6 +785,22 @@ extern sint8 espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip); *******************************************************************************/ extern sint8 espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip); +/****************************************************************************** + * FunctionName : espconn_recv_hold + * Description : hold tcp receive + * Parameters : espconn -- espconn to hold + * Returns : none +*******************************************************************************/ +extern sint8 espconn_recv_hold(struct espconn *pespconn); + +/****************************************************************************** + * FunctionName : espconn_recv_unhold + * Description : unhold tcp receive + * Parameters : espconn -- espconn to unhold + * Returns : none +*******************************************************************************/ +extern sint8 espconn_recv_unhold(struct espconn *pespconn); + /****************************************************************************** * FunctionName : espconn_mdns_init * Description : register a device with mdns diff --git a/app/include/lwip/app/espconn_tcp.h b/app/include/lwip/app/espconn_tcp.h index 5598a5cd..1dfd483f 100644 --- a/app/include/lwip/app/espconn_tcp.h +++ b/app/include/lwip/app/espconn_tcp.h @@ -13,6 +13,9 @@ #define espconn_keepalive_enable(pcb) ((pcb)->so_options |= SOF_KEEPALIVE) #define espconn_keepalive_disable(pcb) ((pcb)->so_options &= ~SOF_KEEPALIVE) +#define espconn_manual_recv_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_MANUALRECV) != 0) +#define espconn_manual_recv_enabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_MANUALRECV) == 0) + /****************************************************************************** * FunctionName : espconn_kill_oldest_pcb * Description : A oldest incoming connection has been killed. diff --git a/app/include/lwip/app/time.h b/app/include/lwip/app/time.h deleted file mode 100644 index 189d7d1f..00000000 --- a/app/include/lwip/app/time.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * time.h - * - * Created on: May 31, 2016 - * Author: liuhan - */ - -#ifndef TIME_H_ -#define TIME_H_ -#include "osapi.h" -#include "os_type.h" -#include "lwip/sntp.h" - -struct timeval { - unsigned long tv_sec; /* seconds */ - unsigned long tv_usec; /* and microseconds */ -}; - -/***************************RTC TIME OPTION***************************************/ -// daylight settings -// Base calculated with value obtained from NTP server (64 bits) -#define sntp_base (*((uint64_t*)RTC_STORE0)) -// Timer value when base was obtained -#define TIM_REF_SET(value) WRITE_PERI_REG(RTC_STORE2, value) -#define TIM_REF_GET() READ_PERI_REG(RTC_STORE2) - -// Setters and getters for CAL, TZ and DST. -#define RTC_CAL_SET(val) do {uint32 value = READ_PERI_REG(RTC_STORE3);\ - value |= ((val) & 0x0000FFFF);\ - WRITE_PERI_REG(RTC_STORE3, value);\ - }while(0) -#define RTC_DST_SET(val) do {uint32 value = READ_PERI_REG(RTC_STORE3);\ - value |= (((val)<<16) & 0x00010000);\ - WRITE_PERI_REG(RTC_STORE3, value);\ - }while(0) -#define RTC_TZ_SET(val) do {uint32 value = READ_PERI_REG(RTC_STORE3);\ - value |= (((val)<<24) & 0xFF000000);\ - WRITE_PERI_REG(RTC_STORE3, value);\ - }while(0) - -#define RTC_CAL_GET() (READ_PERI_REG(RTC_STORE3) & 0x0000FFFF) -#define RTC_DST_GET() ((READ_PERI_REG(RTC_STORE3) & 0x00010000)>>16) -#define RTC_TZ_GET() ((((int)READ_PERI_REG(RTC_STORE3)) & ((int)0xFF000000))>>24) -void system_update_rtc(time_t t, uint32_t us); -time_t sntp_get_rtc_time(sint32_t *us); - -int gettimeofday(struct timeval* t, void* timezone); -void updateTime(uint32 ms); -bool configTime(int timezone, int daylightOffset, char *server1, char *server2, char *server3, bool enable); -time_t time(time_t *t); -unsigned long millis(void); -unsigned long micros(void); -#endif /* TIME_H_ */ diff --git a/app/include/lwip/mem.h b/app/include/lwip/mem.h index af6e3609..41ba85ca 100644 --- a/app/include/lwip/mem.h +++ b/app/include/lwip/mem.h @@ -78,7 +78,7 @@ do{\ #define mem_malloc(s) ({const char *file = mem_debug_file; pvPortMalloc(s, file, __LINE__);}) #endif #ifndef mem_calloc -#define mem_calloc(s) ({const char *file = mem_debug_file; pvPortCalloc(s, file, __LINE__);}) +#define mem_calloc(l, s) ({const char *file = mem_debug_file; pvPortCalloc(l, s, file, __LINE__);}) #endif #ifndef mem_realloc #define mem_realloc(p, s) ({const char *file = mem_debug_file; pvPortRealloc(p, s, file, __LINE__);}) diff --git a/app/include/lwip/sntp.h b/app/include/lwip/sntp.h deleted file mode 100644 index e0d523be..00000000 --- a/app/include/lwip/sntp.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef LWIP_SNTP_H -#define LWIP_SNTP_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef long time_t; - -/** The maximum number of SNTP servers that can be set */ -#ifndef SNTP_MAX_SERVERS -#define SNTP_MAX_SERVERS 3 -#endif - -/** Set this to 1 to implement the callback function called by dhcp when - * NTP servers are received. */ -#ifndef SNTP_GET_SERVERS_FROM_DHCP -#define SNTP_GET_SERVERS_FROM_DHCP 0//LWIP_DHCP_GET_NTP_SRV -#endif - -/* Set this to 1 to support DNS names (or IP address strings) to set sntp servers */ -#ifndef SNTP_SERVER_DNS -#define SNTP_SERVER_DNS 1 -#endif - -bool sntp_get_timetype(void); -void sntp_set_receive_time_size(void); -/** One server address/name can be defined as default if SNTP_SERVER_DNS == 1: - * #define SNTP_SERVER_ADDRESS "pool.ntp.org" - */ -uint32 sntp_get_current_timestamp(); -char* sntp_get_real_time(long t); - -void sntp_init(void); -void sntp_stop(void); - -sint8 sntp_get_timezone(void); -bool sntp_set_timezone(sint8 timezone); -void sntp_setserver(u8_t idx, ip_addr_t *addr); -ip_addr_t sntp_getserver(u8_t idx); - -#if SNTP_SERVER_DNS -void sntp_setservername(u8_t idx, char *server); -char *sntp_getservername(u8_t idx); -#endif /* SNTP_SERVER_DNS */ - -#if SNTP_GET_SERVERS_FROM_DHCP -void sntp_servermode_dhcp(int set_servers_from_dhcp); -#else /* SNTP_GET_SERVERS_FROM_DHCP */ -#define sntp_servermode_dhcp(x) -#endif /* SNTP_GET_SERVERS_FROM_DHCP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNTP_H */ diff --git a/app/include/user_mbedtls.h b/app/include/user_mbedtls.h index 59e6372c..d823820f 100644 --- a/app/include/user_mbedtls.h +++ b/app/include/user_mbedtls.h @@ -5,8 +5,9 @@ #undef MBEDTLS_HAVE_ASM #undef MBEDTLS_HAVE_SSE2 -#define MBEDTLS_HAVE_TIME -#define MBEDTLS_HAVE_TIME_DATE +// These are disabled until we have a real, working RTC-based gettimeofday +#undef MBEDTLS_HAVE_TIME +#undef MBEDTLS_HAVE_TIME_DATE #define MBEDTLS_PLATFORM_MEMORY #undef MBEDTLS_PLATFORM_NO_STD_FUNCTIONS diff --git a/app/lwip/app/espconn.c b/app/lwip/app/espconn.c index a11b413f..b03cac22 100644 --- a/app/lwip/app/espconn.c +++ b/app/lwip/app/espconn.c @@ -441,6 +441,7 @@ sint16 ICACHE_FLASH_ATTR espconn_recv(struct espconn *espconn, void *mem, size_t espconn_msg *pnode = NULL; bool value = false; int bytes_used = 0; + struct tcp_pcb *tpcb = NULL; if (espconn == NULL || mem == NULL || len == 0) return ESPCONN_ARG; @@ -454,13 +455,15 @@ sint16 ICACHE_FLASH_ATTR espconn_recv(struct espconn *espconn, void *mem, size_t len = bytes_used; } ringbuf_memcpy_from(mem, pnode->readbuf, len); - espconn_recv_unhold(pnode->pespconn); + tpcb = pnode->pcommon.pcb; + if (tpcb && tpcb->state == ESTABLISHED) + tcp_recved(pnode->pcommon.pcb, len); return len; } else { return ESPCONN_OK; } } else{ - return ESPCONN_OK; + return ESPCONN_MEM; } } else{ return ESPCONN_ARG; diff --git a/app/lwip/app/espconn_tcp.c b/app/lwip/app/espconn_tcp.c index 69c86c22..49942e4e 100644 --- a/app/lwip/app/espconn_tcp.c +++ b/app/lwip/app/espconn_tcp.c @@ -231,6 +231,10 @@ void ICACHE_FLASH_ATTR espconn_tcp_memp_free(espconn_msg *pmemp) if (pmemp == NULL) return; + /*Enable block option for fetches the data proactive*/ + if (espconn_manual_recv_disabled(pmemp)) + espconn_list_delete(&plink_active, pmemp); + if (pmemp->espconn_mode == ESPCONN_TCPSERVER_MODE){ if (pmemp->pespconn != NULL && pmemp->pespconn->proto.tcp != NULL) os_free(pmemp->pespconn->proto.tcp); @@ -431,11 +435,13 @@ espconn_Task(os_event_t *events) case SIG_ESPCONN_ERRER: /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, task_msg); - espconn_tcp_reconnect(task_msg); + if (espconn_manual_recv_enabled(task_msg)) + espconn_list_delete(&plink_active, task_msg); break; case SIG_ESPCONN_CLOSE: /*remove the node from the client's active connection list*/ - espconn_list_delete(&plink_active, task_msg); + if (espconn_manual_recv_enabled(task_msg)) + espconn_list_delete(&plink_active, task_msg); espconn_tcp_disconnect_successful(task_msg); break; default: @@ -538,6 +544,66 @@ void ICACHE_FLASH_ATTR espconn_tcp_disconnect(espconn_msg *pdiscon,u8 type) } } +/****************************************************************************** + * FunctionName : espconn_tcp_recv + * Description : Data has been received on this pcb. + * Parameters : arg -- Additional argument to pass to the callback function + * pcb -- The connection pcb which received data + * p -- The received data (or NULL when the connection has been closed!) + * err -- An error code if there has been an error receiving + * Returns : ERR_ABRT: if you have called tcp_abort from within the function! +*******************************************************************************/ +static err_t ICACHE_FLASH_ATTR +espconn_tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + espconn_msg *precv_cb = arg; + struct pbuf *pthis = NULL; + uint8_t *ring = NULL; + size_t bytes_used = 0; + + tcp_arg(pcb, arg); + + if (precv_cb->readbuf == NULL) { + precv_cb->readbuf = ringbuf_new(TCP_WND); + if (precv_cb->readbuf == NULL) + return ESPCONN_MEM; + } + + if (err == ERR_OK) { + precv_cb->pcommon.recv_check = 0; + if (p != NULL) { + /*store the data to the adapter for application fetches it proactive*/ + for (pthis = p; pthis != NULL ; pthis = pthis->next) { + ring = ringbuf_memcpy_into(precv_cb->readbuf, pthis->payload, pthis->len); + if (ring) + pbuf_free(pthis); + else + break; + } + bytes_used = ringbuf_bytes_used(precv_cb->readbuf); + + /*switch the state of espconn for application process*/ + precv_cb->pespconn->state = ESPCONN_READ; + precv_cb->pcommon.pcb = pcb; + if (precv_cb->pespconn->recv_callback != NULL) { + precv_cb->pespconn->recv_callback(precv_cb->pespconn, NULL, bytes_used); + } + + /*switch the state of espconn for next packet copy*/ + if (pcb->state == ESTABLISHED) + precv_cb->pespconn->state = ESPCONN_CONNECT; + } else { + if (precv_cb->preverse) { + espconn_server_close(precv_cb, pcb, 0); + } else { + espconn_client_close(precv_cb, pcb, 0); + } + } + } + + return ERR_OK; +} + ///////////////////////////////client function///////////////////////////////// /****************************************************************************** * FunctionName : espconn_client_close @@ -933,6 +999,10 @@ espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn); } + /*Enable block option for fetches the data proactive*/ + if (espconn_manual_recv_disabled(pcon)) + tcp_recv(tpcb, espconn_tcp_recv); + /*Enable keep alive option*/ if (espconn_keepalive_disabled(pcon)) espconn_keepalive_enable(tpcb); @@ -1358,6 +1428,10 @@ espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn); } + /*Enable block option for fetches the data proactive*/ + if (espconn_manual_recv_disabled(paccept)) + tcp_recv(pcb, espconn_tcp_recv); + /*Enable keep alive option*/ if (espconn_keepalive_disabled(paccept)) espconn_keepalive_enable(pcb); diff --git a/app/lwip/app/espconn_udp.c b/app/lwip/app/espconn_udp.c index e3ac8e60..0c834fc6 100644 --- a/app/lwip/app/espconn_udp.c +++ b/app/lwip/app/espconn_udp.c @@ -237,9 +237,10 @@ espconn_udp_sendto(void *arg, uint8 *psent, uint16 length) if(wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL) { - if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \ - ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) { + if( netif_is_up(sta_netif) && \ + netif_is_up(ap_netif) && \ + ip_addr_isbroadcast(&dst_ip, sta_netif) && \ + ip_addr_isbroadcast(&dst_ip, ap_netif)) { p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); if (pbuf_copy (p_temp,p) != ERR_OK) { diff --git a/app/lwip/core/sntp.c b/app/lwip/core/sntp.c deleted file mode 100644 index 4d157014..00000000 --- a/app/lwip/core/sntp.c +++ /dev/null @@ -1,1185 +0,0 @@ -/** - * @file - * SNTP client module - * - * This is simple "SNTP" client for the lwIP raw API. - * It is a minimal implementation of SNTPv4 as specified in RFC 4330. - * - * For a list of some public NTP servers, see this link : - * http://support.ntp.org/bin/view/Servers/NTPPoolServers - * - * @todo: - * - set/change servers at runtime - * - complete SNTP_CHECK_RESPONSE checks 3 and 4 - * - support broadcast/multicast mode? - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt (lwIP raw API part) - */ - -#include "lwip/sntp.h" -#include "osapi.h" -#include "os_type.h" -#include "lwip/opt.h" -#include "lwip/timers.h" -#include "lwip/udp.h" -#include "lwip/dns.h" -#include "lwip/ip_addr.h" -#include "lwip/pbuf.h" -#include "lwip/app/time.h" -//#include -#if LWIP_UDP - -/** - * SNTP_DEBUG: Enable debugging for SNTP. - */ -#ifndef SNTP_DEBUG -#define SNTP_DEBUG LWIP_DBG_ON -#endif - -/** SNTP server port */ -#ifndef SNTP_PORT -#define SNTP_PORT 123 -#endif - -/** Set this to 1 to allow config of SNTP server(s) by DNS name */ -#ifndef SNTP_SERVER_DNS -#define SNTP_SERVER_DNS 0 -#endif - -/** Handle support for more than one server via NTP_MAX_SERVERS, - * but catch legacy style of setting SNTP_SUPPORT_MULTIPLE_SERVERS, probably outside of this file - */ -#ifndef SNTP_SUPPORT_MULTIPLE_SERVERS -#if SNTP_MAX_SERVERS > 1 -#define SNTP_SUPPORT_MULTIPLE_SERVERS 1 -#else /* NTP_MAX_SERVERS > 1 */ -#define SNTP_SUPPORT_MULTIPLE_SERVERS 0 -#endif /* NTP_MAX_SERVERS > 1 */ -#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ -/* The developer has defined SNTP_SUPPORT_MULTIPLE_SERVERS, probably from old code */ -#if SNTP_MAX_SERVERS <= 1 -#error "SNTP_MAX_SERVERS needs to be defined to the max amount of servers if SNTP_SUPPORT_MULTIPLE_SERVERS is defined" -#endif /* SNTP_MAX_SERVERS <= 1 */ -#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ - - -/** Sanity check: - * Define this to - * - 0 to turn off sanity checks (default; smaller code) - * - >= 1 to check address and port of the response packet to ensure the - * response comes from the server we sent the request to. - * - >= 2 to check returned Originate Timestamp against Transmit Timestamp - * sent to the server (to ensure response to older request). - * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp - * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast). - * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each - * greater than or equal to 0 and less than infinity, where infinity is - * currently a cozy number like one second. This check avoids using a - * server whose synchronization source has expired for a very long time. - */ -#ifndef SNTP_CHECK_RESPONSE -#define SNTP_CHECK_RESPONSE 0 -#endif - -/** According to the RFC, this shall be a random delay - * between 1 and 5 minutes (in milliseconds) to prevent load peaks. - * This can be defined to a random generation function, - * which must return the delay in milliseconds as u32_t. - * Turned off by default. - */ -#ifndef SNTP_STARTUP_DELAY -#define SNTP_STARTUP_DELAY 0 -#endif - -/** If you want the startup delay to be a function, define this - * to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1. - */ -#ifndef SNTP_STARTUP_DELAY_FUNC -#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY -#endif - -/** SNTP receive timeout - in milliseconds - * Also used as retry timeout - this shouldn't be too low. - * Default is 3 seconds. - */ -#ifndef SNTP_RECV_TIMEOUT -#define SNTP_RECV_TIMEOUT 3000 -#endif - -/** SNTP update delay - in milliseconds - * Default is 1 hour. - */ -#ifndef SNTP_UPDATE_DELAY -#define SNTP_UPDATE_DELAY 3600000 -#endif -#if (SNTP_UPDATE_DELAY < 15000) && !SNTP_SUPPRESS_DELAY_CHECK -#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds!" -#endif - -/** SNTP macro to change system time and/or the update the RTC clock */ -#ifndef SNTP_SET_SYSTEM_TIME -#define SNTP_SET_SYSTEM_TIME(sec) ((void)sec) -#endif - -/** SNTP macro to change system time including microseconds */ -uint8 sntp_receive_time_size = 1; -#define SNTP_RECEIVE_TIME_SIZE sntp_receive_time_size -#define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_update_rtc(sec, us) -//#ifdef SNTP_SET_SYSTEM_TIME_US -//#define SNTP_SET_SYSTEM_TIME_US(sec, us) sntp_update_rtc(sec, us) -//#define SNTP_CALC_TIME_US 1 -//#define SNTP_RECEIVE_TIME_SIZE 2 -//#else -//#define SNTP_SET_SYSTEM_TIME_US(sec, us) -//#define SNTP_CALC_TIME_US 0 -//#define SNTP_RECEIVE_TIME_SIZE sntp_receive_time_size -//#endif - -/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2 - * to send in request and compare in response. - */ -#ifndef SNTP_GET_SYSTEM_TIME -#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0) -#endif - -/** Default retry timeout (in milliseconds) if the response - * received is invalid. - * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached. - */ -#ifndef SNTP_RETRY_TIMEOUT -#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT -#endif - -/** Maximum retry timeout (in milliseconds). */ -#ifndef SNTP_RETRY_TIMEOUT_MAX -#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10) -#endif - -/** Increase retry timeout with every retry sent - * Default is on to conform to RFC. - */ -#ifndef SNTP_RETRY_TIMEOUT_EXP -#define SNTP_RETRY_TIMEOUT_EXP 1 -#endif - -/* the various debug levels for this file */ -#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) -#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) -#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) -#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) - -#define SNTP_ERR_KOD 1 - -/* SNTP protocol defines */ -#define SNTP_MSG_LEN 48 - -#define SNTP_OFFSET_LI_VN_MODE 0 -#define SNTP_LI_MASK 0xC0 -#define SNTP_LI_NO_WARNING 0x00 -#define SNTP_LI_LAST_MINUTE_61_SEC 0x01 -#define SNTP_LI_LAST_MINUTE_59_SEC 0x02 -#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */ - -#define SNTP_VERSION_MASK 0x38 -#define SNTP_VERSION (4/* NTP Version 4*/<<3) - -#define SNTP_MODE_MASK 0x07 -#define SNTP_MODE_CLIENT 0x03 -#define SNTP_MODE_SERVER 0x04 -#define SNTP_MODE_BROADCAST 0x05 - -#define SNTP_OFFSET_STRATUM 1 -#define SNTP_STRATUM_KOD 0x00 - -#define SNTP_OFFSET_ORIGINATE_TIME 24 -#define SNTP_OFFSET_RECEIVE_TIME 32 -#define SNTP_OFFSET_TRANSMIT_TIME 40 - -/* number of seconds between 1900 and 1970 */ -#define DIFF_SEC_1900_1970 (2208988800UL) - -/** - * SNTP packet format (without optional fields) - * Timestamps are coded as 64 bits: - * - 32 bits seconds since Jan 01, 1970, 00:00 - * - 32 bits seconds fraction (0-padded) - * For future use, if the MSB in the seconds part is set, seconds are based - * on Feb 07, 2036, 06:28:16. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -#define PACK_STRUCT_FLD_8 PACK_STRUCT_FIELD -struct sntp_msg { - PACK_STRUCT_FLD_8(u8_t li_vn_mode); - PACK_STRUCT_FLD_8(u8_t stratum); - PACK_STRUCT_FLD_8(u8_t poll); - PACK_STRUCT_FLD_8(u8_t precision); - PACK_STRUCT_FIELD(u32_t root_delay); - PACK_STRUCT_FIELD(u32_t root_dispersion); - PACK_STRUCT_FIELD(u32_t reference_identifier); - PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); - PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); - PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); - PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* function prototypes */ -static void sntp_request(void *arg); - -/** The UDP pcb used by the SNTP client */ -static struct udp_pcb* sntp_pcb; - -sint8 time_zone = 8; -/** Names/Addresses of servers */ -struct sntp_server { -#if SNTP_SERVER_DNS - char* name; -#endif /* SNTP_SERVER_DNS */ - ip_addr_t addr; -}; -static struct sntp_server sntp_servers[SNTP_MAX_SERVERS]; - -static u8_t sntp_set_servers_from_dhcp; -#if SNTP_SUPPORT_MULTIPLE_SERVERS -/** The currently used server (initialized to 0) */ -static u8_t sntp_current_server; -#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ -#define sntp_current_server 0 -#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ - -#if SNTP_RETRY_TIMEOUT_EXP -#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT -/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */ -static u32_t sntp_retry_timeout; -#else /* SNTP_RETRY_TIMEOUT_EXP */ -#define SNTP_RESET_RETRY_TIMEOUT() -#define sntp_retry_timeout SNTP_RETRY_TIMEOUT -#endif /* SNTP_RETRY_TIMEOUT_EXP */ - -#if SNTP_CHECK_RESPONSE >= 1 -/** Saves the last server address to compare with response */ -static ip_addr_t sntp_last_server_address; -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - -#if SNTP_CHECK_RESPONSE >= 2 -/** Saves the last timestamp sent (which is sent back by the server) - * to compare against in response */ -static u32_t sntp_last_timestamp_sent[2]; -#endif /* SNTP_CHECK_RESPONSE >= 2 */ - -//uint32 current_stamp_1 = 0; -//uint32 current_stamp_2 = 0; -static bool sntp_time_flag = false; -static uint32 sntp_update_delay = SNTP_UPDATE_DELAY; -static uint32 realtime_stamp = 0; -LOCAL os_timer_t sntp_timer; -/*****************************************/ -#define SECSPERMIN 60L -#define MINSPERHOUR 60L -#define HOURSPERDAY 24L -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY) -#define DAYSPERWEEK 7 -#define MONSPERYEAR 12 - -#define YEAR_BASE 1900 -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY 4 -#define EPOCH_YEARS_SINCE_LEAP 2 -#define EPOCH_YEARS_SINCE_CENTURY 70 -#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370 - -#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) - -int __tznorth; -int __tzyear; -char reult[100]; -static const int mon_lengths[2][12] = { - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -} ; - -static const int year_lengths[2] = { - 365, - 366 -} ; -struct tm -{ - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; -}; - -struct tm res_buf; -typedef struct __tzrule_struct -{ - char ch; - int m; - int n; - int d; - int s; - time_t change; - int offset; -} __tzrule_type; - -__tzrule_type sntp__tzrule[2]; -struct tm * ICACHE_FLASH_ATTR -sntp_mktm_r(const time_t * tim_p ,struct tm *res ,int is_gmtime) -{ - long days, rem; - time_t lcltime; - int i; - int y; - int yleap; - const int *ip; - - /* base decision about std/dst time on current time */ - lcltime = *tim_p; - - days = ((long)lcltime) / SECSPERDAY; - rem = ((long)lcltime) % SECSPERDAY; - while (rem < 0) - { - rem += SECSPERDAY; - --days; - } - while (rem >= SECSPERDAY) - { - rem -= SECSPERDAY; - ++days; - } - - /* compute hour, min, and sec */ - res->tm_hour = (int) (rem / SECSPERHOUR); - rem %= SECSPERHOUR; - res->tm_min = (int) (rem / SECSPERMIN); - res->tm_sec = (int) (rem % SECSPERMIN); - - /* compute day of week */ - if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0) - res->tm_wday += DAYSPERWEEK; - - /* compute year & day of year */ - y = EPOCH_YEAR; - if (days >= 0) - { - for (;;) - { - yleap = isleap(y); - if (days < year_lengths[yleap]) - break; - y++; - days -= year_lengths[yleap]; - } - } - else - { - do - { - --y; - yleap = isleap(y); - days += year_lengths[yleap]; - } while (days < 0); - } - - res->tm_year = y - YEAR_BASE; - res->tm_yday = days; - ip = mon_lengths[yleap]; - for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon) - days -= ip[res->tm_mon]; - res->tm_mday = days + 1; - - if (!is_gmtime) - { - int offset; - int hours, mins, secs; - -// TZ_LOCK; -// if (_daylight) -// { -// if (y == __tzyear || __tzcalc_limits (y)) -// res->tm_isdst = (__tznorth -// ? (*tim_p >= __tzrule[0].change && *tim_p < __tzrule[1].change) -// : (*tim_p >= __tzrule[0].change || *tim_p < __tzrule[1].change)); -// else -// res->tm_isdst = -1; -// } -// else - res->tm_isdst = 0; - - offset = (res->tm_isdst == 1 ? sntp__tzrule[1].offset : sntp__tzrule[0].offset); - - hours = offset / SECSPERHOUR; - offset = offset % SECSPERHOUR; - - mins = offset / SECSPERMIN; - secs = offset % SECSPERMIN; - - res->tm_sec -= secs; - res->tm_min -= mins; - res->tm_hour -= hours; - - if (res->tm_sec >= SECSPERMIN) - { - res->tm_min += 1; - res->tm_sec -= SECSPERMIN; - } - else if (res->tm_sec < 0) - { - res->tm_min -= 1; - res->tm_sec += SECSPERMIN; - } - if (res->tm_min >= MINSPERHOUR) - { - res->tm_hour += 1; - res->tm_min -= MINSPERHOUR; - } - else if (res->tm_min < 0) - { - res->tm_hour -= 1; - res->tm_min += MINSPERHOUR; - } - if (res->tm_hour >= HOURSPERDAY) - { - ++res->tm_yday; - ++res->tm_wday; - if (res->tm_wday > 6) - res->tm_wday = 0; - ++res->tm_mday; - res->tm_hour -= HOURSPERDAY; - if (res->tm_mday > ip[res->tm_mon]) - { - res->tm_mday -= ip[res->tm_mon]; - res->tm_mon += 1; - if (res->tm_mon == 12) - { - res->tm_mon = 0; - res->tm_year += 1; - res->tm_yday = 0; - } - } - } - else if (res->tm_hour < 0) - { - res->tm_yday -= 1; - res->tm_wday -= 1; - if (res->tm_wday < 0) - res->tm_wday = 6; - res->tm_mday -= 1; - res->tm_hour += 24; - if (res->tm_mday == 0) - { - res->tm_mon -= 1; - if (res->tm_mon < 0) - { - res->tm_mon = 11; - res->tm_year -= 1; - res->tm_yday = 365 + isleap(res->tm_year); - } - res->tm_mday = ip[res->tm_mon]; - } - } -// TZ_UNLOCK; - } - else - res->tm_isdst = 0; -// os_printf("res %d %d %d %d %d\n",res->tm_year,res->tm_mon,res->tm_mday,res->tm_yday,res->tm_hour); - return (res); -} -struct tm * ICACHE_FLASH_ATTR -sntp_localtime_r(const time_t * tim_p , - struct tm *res) -{ - return sntp_mktm_r (tim_p, res, 0); -} - -struct tm * ICACHE_FLASH_ATTR -sntp_localtime(const time_t * tim_p) -{ - return sntp_localtime_r (tim_p, &res_buf); -} - - -int ICACHE_FLASH_ATTR -sntp__tzcalc_limits(int year) -{ - int days, year_days, years; - int i, j; - - if (year < EPOCH_YEAR) - return 0; - - __tzyear = year; - - years = (year - EPOCH_YEAR); - - year_days = years * 365 + - (years - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - (years - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + - (years - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400; - - for (i = 0; i < 2; ++i) - { - if (sntp__tzrule[i].ch == 'J') - days = year_days + sntp__tzrule[i].d + (isleap(year) && sntp__tzrule[i].d >= 60); - else if (sntp__tzrule[i].ch == 'D') - days = year_days + sntp__tzrule[i].d; - else - { - int yleap = isleap(year); - int m_day, m_wday, wday_diff; - const int *ip = mon_lengths[yleap]; - - days = year_days; - - for (j = 1; j < sntp__tzrule[i].m; ++j) - days += ip[j-1]; - - m_wday = (EPOCH_WDAY + days) % DAYSPERWEEK; - - wday_diff = sntp__tzrule[i].d - m_wday; - if (wday_diff < 0) - wday_diff += DAYSPERWEEK; - m_day = (sntp__tzrule[i].n - 1) * DAYSPERWEEK + wday_diff; - - while (m_day >= ip[j-1]) - m_day -= DAYSPERWEEK; - - days += m_day; - } - - /* store the change-over time in GMT form by adding offset */ - sntp__tzrule[i].change = days * SECSPERDAY + sntp__tzrule[i].s + sntp__tzrule[i].offset; - } - - __tznorth = (sntp__tzrule[0].change < sntp__tzrule[1].change); - - return 1; -} - -char * ICACHE_FLASH_ATTR -sntp_asctime_r(struct tm *tim_p ,char *result) -{ - static const char day_name[7][4] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static const char mon_name[12][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - os_sprintf (result, "%s %s %02d %02d:%02d:%02d %02d\n", - day_name[tim_p->tm_wday], - mon_name[tim_p->tm_mon], - tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min, - tim_p->tm_sec, 1900 + tim_p->tm_year); - return result; -} -char *ICACHE_FLASH_ATTR -sntp_asctime(struct tm *tim_p) -{ - - return sntp_asctime_r (tim_p, reult); -} - -uint32 sntp_get_current_timestamp() -{ - if(realtime_stamp == 0){ - os_printf("please start sntp first !\n"); - return 0; - } else { - return realtime_stamp; - } -} - -char* sntp_get_real_time(time_t t) -{ - return sntp_asctime(sntp_localtime (&t)); -} -/** - * SNTP get time_zone default GMT + 8 - */ -sint8 ICACHE_FLASH_ATTR -sntp_get_timezone(void) -{ - return time_zone; -} -/** - * SNTP set time_zone default GMT + 8 - */ - -bool ICACHE_FLASH_ATTR -sntp_set_timezone(sint8 timezone) -{ - if(timezone >= -11 || timezone <= 13) { - if (sntp_get_timetype()){ - RTC_TZ_SET(time_zone); - } else - time_zone = timezone; - return true; - } else { - return false; - } - -} - -void ICACHE_FLASH_ATTR sntp_set_daylight(int daylight) -{ - if (sntp_get_timetype()){ - RTC_DST_SET(daylight); - } -} - -void ICACHE_FLASH_ATTR -sntp_time_inc(void) -{ - realtime_stamp++; -} -/** - * SNTP processing of received timestamp - */ -static void ICACHE_FLASH_ATTR -sntp_process(u32_t *receive_timestamp) -{ - /* convert SNTP time (1900-based) to unix GMT time (1970-based) - * @todo: if MSB is 1, SNTP time is 2036-based! - */ - time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970); - if (sntp_get_timetype()){ - u32_t us = ntohl(receive_timestamp[1]) / 4295; - SNTP_SET_SYSTEM_TIME_US(t, us); - /* display local time from GMT time */ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us)); - } else{ - /* change system time and/or the update the RTC clock */ - SNTP_SET_SYSTEM_TIME(t); - /* display local time from GMT time */ - t += time_zone * 60 * 60;// format GMT + time_zone TIME ZONE - realtime_stamp = t; - os_timer_disarm(&sntp_timer); - os_timer_setfn(&sntp_timer, (os_timer_func_t *)sntp_time_inc, NULL); - os_timer_arm(&sntp_timer, 1000, 1); - } -#if 0 -#if SNTP_CALC_TIME_US - u32_t us = ntohl(receive_timestamp[1]) / 4295; - SNTP_SET_SYSTEM_TIME_US(t, us); - /* display local time from GMT time */ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us)); - -#else /* SNTP_CALC_TIME_US */ - - /* change system time and/or the update the RTC clock */ - SNTP_SET_SYSTEM_TIME(t); - /* display local time from GMT time */ - t += time_zone * 60 * 60;// format GMT + time_zone TIME ZONE - realtime_stamp = t; - os_timer_disarm(&sntp_timer); - os_timer_setfn(&sntp_timer, (os_timer_func_t *)sntp_time_inc, NULL); - os_timer_arm(&sntp_timer, 1000, 1); -#endif /* SNTP_CALC_TIME_US */ -#endif -} - -/** - * Initialize request struct to be sent to server. - */ -static void ICACHE_FLASH_ATTR -sntp_initialize_request(struct sntp_msg *req) -{ - os_memset(req, 0, SNTP_MSG_LEN); - req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; - -#if SNTP_CHECK_RESPONSE >= 2 - { - u32_t sntp_time_sec, sntp_time_us; - /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */ - SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us); - sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970); - req->transmit_timestamp[0] = sntp_last_timestamp_sent[0]; - /* we send/save us instead of fraction to be faster... */ - sntp_last_timestamp_sent[1] = htonl(sntp_time_us); - req->transmit_timestamp[1] = sntp_last_timestamp_sent[1]; - } -#endif /* SNTP_CHECK_RESPONSE >= 2 */ -} - -/** - * Retry: send a new request (and increase retry timeout). - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void ICACHE_FLASH_ATTR -sntp_retry(void* arg) -{ - LWIP_UNUSED_ARG(arg); - - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n", - sntp_retry_timeout)); - - /* set up a timer to send a retry and increase the retry delay */ - sys_timeout(sntp_retry_timeout, sntp_request, NULL); - -#if SNTP_RETRY_TIMEOUT_EXP - { - u32_t new_retry_timeout; - /* increase the timeout for next retry */ - new_retry_timeout = sntp_retry_timeout << 1; - /* limit to maximum timeout and prevent overflow */ - if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && - (new_retry_timeout > sntp_retry_timeout)) { - sntp_retry_timeout = new_retry_timeout; - } - } -#endif /* SNTP_RETRY_TIMEOUT_EXP */ -} - -#if SNTP_SUPPORT_MULTIPLE_SERVERS -/** - * If Kiss-of-Death is received (or another packet parsing error), - * try the next server or retry the current server and increase the retry - * timeout if only one server is available. - * (implicitly, SNTP_MAX_SERVERS > 1) - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void -sntp_try_next_server(void* arg) -{ - u8_t old_server, i; - LWIP_UNUSED_ARG(arg); - - old_server = sntp_current_server; - for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) { - sntp_current_server++; - if (sntp_current_server >= SNTP_MAX_SERVERS) { - sntp_current_server = 0; - } - if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr) -#if SNTP_SERVER_DNS - || (sntp_servers[sntp_current_server].name != NULL) -#endif - ) { - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", - (u16_t)sntp_current_server)); - /* new server: reset retry timeout */ - SNTP_RESET_RETRY_TIMEOUT(); - /* instantly send a request to the next server */ - sntp_request(NULL); - return; - } - } - /* no other valid server found */ - sntp_current_server = old_server; - sntp_retry(NULL); -} -#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ -/* Always retry on error if only one server is supported */ -#define sntp_try_next_server sntp_retry -#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ - -/** UDP recv callback for the sntp pcb */ -static void ICACHE_FLASH_ATTR -sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) -{ - u8_t mode; - u8_t stratum; - u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE]; - err_t err; -//os_printf("sntp_recv\n"); - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - - /* packet received: stop retry timeout */ - sys_untimeout(sntp_try_next_server, NULL); - sys_untimeout(sntp_request, NULL); - - err = ERR_ARG; -#if SNTP_CHECK_RESPONSE >= 1 - /* check server address and port */ - if (ip_addr_cmp(addr, &sntp_last_server_address) && - (port == SNTP_PORT)) -#else /* SNTP_CHECK_RESPONSE >= 1 */ - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - { - /* process the response */ - if (p->tot_len == SNTP_MSG_LEN) { - pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE); - mode &= SNTP_MODE_MASK; - /* if this is a SNTP response... */ - if ((mode == SNTP_MODE_SERVER) || - (mode == SNTP_MODE_BROADCAST)) { - pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM); - if (stratum == SNTP_STRATUM_KOD) { - /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ - err = SNTP_ERR_KOD; - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); - } else { -#if SNTP_CHECK_RESPONSE >= 2 - /* check originate_timetamp against sntp_last_timestamp_sent */ - u32_t originate_timestamp[2]; - pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME); - if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) || - (originate_timestamp[1] != sntp_last_timestamp_sent[1])) - { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n")); - } else -#endif /* SNTP_CHECK_RESPONSE >= 2 */ - /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ - { - /* correct answer */ - err = ERR_OK; - pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME); - } - } - } else { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); - } - } else { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); - } - } - pbuf_free(p); - if (err == ERR_OK) { - /* Correct response, reset retry timeout */ - SNTP_RESET_RETRY_TIMEOUT(); - - sntp_process(receive_timestamp); - - /* Set up timeout for next request */ - sys_timeout((u32_t)sntp_update_delay, sntp_request, NULL); - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", - (u32_t)sntp_update_delay)); - } else if (err == SNTP_ERR_KOD) { - /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ - sntp_try_next_server(NULL); - } else { - /* another error, try the same server again */ - sntp_retry(NULL); - } -} - -/** Actually send an sntp request to a server. - * - * @param server_addr resolved IP address of the SNTP server - */ -static void ICACHE_FLASH_ATTR -sntp_send_request(ip_addr_t *server_addr) -{ - struct pbuf* p; -// os_printf("sntp_send_request\n"); - p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); - if (p != NULL) { - struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); - /* initialize request message */ - sntp_initialize_request(sntpmsg); - /* send request */ - udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); - /* free the pbuf after sending it */ - pbuf_free(p); - /* set up receive timeout: try next server or retry on timeout */ - sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); -#if SNTP_CHECK_RESPONSE >= 1 - /* save server address to verify it in sntp_recv */ - ip_addr_set(&sntp_last_server_address, server_addr); -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - } else { - LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", - (u32_t)SNTP_RETRY_TIMEOUT)); - /* out of memory: set up a timer to send a retry */ - sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); - } -} - -#if SNTP_SERVER_DNS -/** - * DNS found callback when using DNS names as server address. - */ -static void -sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg) -{ - LWIP_UNUSED_ARG(hostname); - LWIP_UNUSED_ARG(arg); - - if (ipaddr != NULL) { - /* Address resolved, send request */ - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); - sntp_send_request(ipaddr); - } else { - /* DNS resolving failed -> try another server */ - LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); - sntp_try_next_server(NULL); - } -} -#endif /* SNTP_SERVER_DNS */ - -/** - * Send out an sntp request. - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void ICACHE_FLASH_ATTR -sntp_request(void *arg) -{ - ip_addr_t sntp_server_address; - err_t err; - - LWIP_UNUSED_ARG(arg); - - /* initialize SNTP server address */ -#if SNTP_SERVER_DNS - - if (sntp_servers[sntp_current_server].name) { - /* always resolve the name and rely on dns-internal caching & timeout */ - ip_addr_set_any(&sntp_servers[sntp_current_server].addr); - err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address, - sntp_dns_found, NULL); - if (err == ERR_INPROGRESS) { - /* DNS request sent, wait for sntp_dns_found being called */ - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); - return; - } else if (err == ERR_OK) { - sntp_servers[sntp_current_server].addr = sntp_server_address; - } - } else -#endif /* SNTP_SERVER_DNS */ - { - sntp_server_address = sntp_servers[sntp_current_server].addr; -// os_printf("sntp_server_address ip %d\n",sntp_server_address.addr); - err = (ip_addr_isany(&sntp_server_address)) ? ERR_ARG : ERR_OK; - } - - if (err == ERR_OK) { - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %u.%u.%u.%u\n", - ip4_addr1(&sntp_server_address), ip4_addr2(&sntp_server_address), ip4_addr3(&sntp_server_address), ip4_addr4(&sntp_server_address))); - sntp_send_request(&sntp_server_address); - } else { - /* address conversion failed, try another server */ - LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); - sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); - } -} - -/** - * Initialize this module. - * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC). - */ -void ICACHE_FLASH_ATTR -sntp_init(void) -{ -#ifdef SNTP_SERVER_ADDRESS -#if SNTP_SERVER_DNS - sntp_setservername(0, SNTP_SERVER_ADDRESS); -#else -#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0 -#endif -#endif /* SNTP_SERVER_ADDRESS */ - - if (sntp_pcb == NULL) { - SNTP_RESET_RETRY_TIMEOUT(); - sntp_pcb = udp_new(); - LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); - if (sntp_pcb != NULL) { - udp_recv(sntp_pcb, sntp_recv, NULL); -#if SNTP_STARTUP_DELAY - sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL); -#else - sntp_request(NULL); -#endif - } - } -} - -/** - * Stop this module. - */ -void ICACHE_FLASH_ATTR -sntp_stop(void) -{ - if (sntp_pcb != NULL) { - sys_untimeout(sntp_request, NULL); - udp_remove(sntp_pcb); - sntp_pcb = NULL; - } - os_timer_disarm(&sntp_timer); - realtime_stamp = 0; -} - -#if SNTP_GET_SERVERS_FROM_DHCP -/** - * Config SNTP server handling by IP address, name, or DHCP; clear table - * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp - */ -void -sntp_servermode_dhcp(int set_servers_from_dhcp) -{ - u8_t new_mode = set_servers_from_dhcp ? 1 : 0; - if (sntp_set_servers_from_dhcp != new_mode) { - sntp_set_servers_from_dhcp = new_mode; - } -} -#endif /* SNTP_GET_SERVERS_FROM_DHCP */ - -/** - * Initialize one of the NTP servers by IP address - * - * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param dnsserver IP address of the NTP server to set - */ -void ICACHE_FLASH_ATTR -sntp_setserver(u8_t idx, ip_addr_t *server) -{ - if (idx < SNTP_MAX_SERVERS) { - if (server != NULL) { - sntp_servers[idx].addr = (*server); -// os_printf("server ip %d\n",server->addr); - } else { - ip_addr_set_any(&sntp_servers[idx].addr); - } -#if SNTP_SERVER_DNS - sntp_servers[idx].name = NULL; -#endif - } -} - -#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP -/** - * Initialize one of the NTP servers by IP address, required by DHCP - * - * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param dnsserver IP address of the NTP server to set - */ -void -dhcp_set_ntp_servers(u8_t num, ip_addr_t *server) -{ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n", - (sntp_set_servers_from_dhcp ? "Got" : "Rejected"), - ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num)); - if (sntp_set_servers_from_dhcp && num) { - u8_t i; - for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) { - sntp_setserver(i, &server[i]); - } - for (i = num; i < SNTP_MAX_SERVERS; i++) { - sntp_setserver(i, NULL); - } - } -} -#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */ - -/** - * Obtain one of the currently configured by IP address (or DHCP) NTP servers - * - * @param numdns the index of the NTP server - * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP - * server has not been configured by address (or at all). - */ -ip_addr_t ICACHE_FLASH_ATTR -sntp_getserver(u8_t idx) -{ - if (idx < SNTP_MAX_SERVERS) { - return sntp_servers[idx].addr; - } - return *IP_ADDR_ANY; -} - -#if SNTP_SERVER_DNS -/** - * Initialize one of the NTP servers by name - * - * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param dnsserver DNS name of the NTP server to set, to be resolved at contact time - */ -void ICACHE_FLASH_ATTR -sntp_setservername(u8_t idx, char *server) -{ - if (idx < SNTP_MAX_SERVERS) { - sntp_servers[idx].name = server; - } -} - -/** - * Obtain one of the currently configured by name NTP servers. - * - * @param numdns the index of the NTP server - * @return IP address of the indexed NTP server or NULL if the NTP - * server has not been configured by name (or at all) - */ -char * ICACHE_FLASH_ATTR -sntp_getservername(u8_t idx) -{ - if (idx < SNTP_MAX_SERVERS) { - return sntp_servers[idx].name; - } - return NULL; -} -#endif /* SNTP_SERVER_DNS */ - -void ICACHE_FLASH_ATTR -sntp_set_update_delay(uint32 ms) -{ - sntp_update_delay = ms > 15000?ms:15000; -} - -void ICACHE_FLASH_ATTR -sntp_set_timetype(bool type) -{ - sntp_time_flag = type; -} - -bool sntp_get_timetype(void) -{ - return sntp_time_flag; -} - -void ICACHE_FLASH_ATTR -sntp_set_receive_time_size(void) -{ - if (sntp_get_timetype()){ - sntp_receive_time_size = 2; - } else{ - sntp_receive_time_size = 1; - } -} - -#endif /* LWIP_UDP */ diff --git a/app/lwip/core/tcp_in.c b/app/lwip/core/tcp_in.c index be74a28a..f32fb2db 100644 --- a/app/lwip/core/tcp_in.c +++ b/app/lwip/core/tcp_in.c @@ -500,7 +500,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) /* For incoming segments with the ACK flag set, respond with a RST. */ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst(ackno + 1, seqno + tcplen, + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) {//�յ�SYN���� diff --git a/app/lwip/core/tcp_out.c b/app/lwip/core/tcp_out.c index b9d69e46..6685a442 100644 --- a/app/lwip/core/tcp_out.c +++ b/app/lwip/core/tcp_out.c @@ -461,6 +461,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) return ERR_MEM; } +#if !LWIP_NETIF_TX_SINGLE_PBUF /* * Phase 2: Chain a new pbuf to the end of pcb->unsent. * @@ -510,6 +511,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) pos += seglen; queuelen += pbuf_clen(concat_p); } +#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ } else { #if TCP_OVERSIZE LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", @@ -1336,6 +1338,12 @@ tcp_rexmit(struct tcp_pcb *pcb) } seg->next = *cur_seg; *cur_seg = seg; +#if TCP_OVERSIZE + if (seg->next == NULL) { + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ ++pcb->nrtx; diff --git a/app/mbedtls/app/espconn_mbedtls.c b/app/mbedtls/app/espconn_mbedtls.c index 72e4c51a..6a4ded6c 100644 --- a/app/mbedtls/app/espconn_mbedtls.c +++ b/app/mbedtls/app/espconn_mbedtls.c @@ -353,6 +353,8 @@ static void mbedtls_msg_free(pmbedtls_msg *msg) os_free((*msg)->ssl.out_buf); (*msg)->ssl.out_buf = NULL; } + if((*msg)->pfinished != NULL) + mbedtls_finished_free(&(*msg)->pfinished); #endif mbedtls_entropy_free(&(*msg)->entropy); mbedtls_ssl_free(&(*msg)->ssl); @@ -427,10 +429,6 @@ static void mbedtls_fail_info(espconn_msg *pinfo, int ret) TLSmsg = pinfo->pssl; lwIP_REQUIRE_ACTION(TLSmsg,exit,); - if (TLSmsg->quiet) { - mbedtls_ssl_close_notify(&TLSmsg->ssl); - } - /* Don't complain to console if we've been told the other end is hanging * up. That's entirely normal and not worthy of the confusion it sows! */ @@ -441,6 +439,7 @@ static void mbedtls_fail_info(espconn_msg *pinfo, int ret) } else { os_printf("client's data invalid protocol\n"); } + mbedtls_ssl_close_notify(&TLSmsg->ssl); } else{ if (pinfo->preverse != NULL) { os_printf("server handshake failed!\n"); @@ -564,6 +563,11 @@ static void espconn_close_internal(void *arg, netconn_event event_type) ssl_reerr = pssl_recon->pcommon.err; hs_status = pssl_recon->hs_status; if (espconn != NULL) { + //clear pcommon parameters. + pssl_recon->pcommon.write_flag = false; + pssl_recon->pcommon.ptrbuf = NULL; + pssl_recon->pcommon.cntr = 0; + pssl_recon->pcommon.err = 0; espconn = pssl_recon->preverse; } else { espconn = pssl_recon->pespconn; @@ -667,6 +671,11 @@ again: offerset += sizeof(file_head) + pfile_param->file_head.file_length; goto again; } + /*Optional is load the cert*/ + if (auth_info->auth_type == ESPCONN_CERT_OWN && os_memcmp(pfile_param->file_head.file_name, "certificate", os_strlen("certificate")) != 0){ + offerset += sizeof(file_head) + pfile_param->file_head.file_length; + goto again; + } load_buf = (uint8_t *) os_zalloc( pfile_param->file_head.file_length + FILE_OFFSET); if (load_buf == NULL){ os_free(pfile_param); @@ -839,6 +848,9 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error) if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == 0){ ret = ESPCONN_OK; break; + } else if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY){ + ret = ESPCONN_OK; + mbedtls_ssl_close_notify(&TLSmsg->ssl); } else{ break; } @@ -891,6 +903,9 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error) } system_soft_wdt_stop(); + uint8 cpu_freq; + cpu_freq = system_get_cpu_freq(); + system_update_cpu_freq(160); while ((ret = mbedtls_ssl_handshake(&TLSmsg->ssl)) != 0) { if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { @@ -901,6 +916,7 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error) } } system_soft_wdt_restart(); + system_update_cpu_freq(cpu_freq); lwIP_REQUIRE_NOERROR(ret, exit); /**/ TLSmsg->quiet = mbedtls_handshake_result(TLSmsg); @@ -937,6 +953,9 @@ int __attribute__((weak)) mbedtls_parse_internal(int socket, sint8 error) exit: if (ret != ESPCONN_OK){ mbedtls_fail_info(Threadmsg, ret); + if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY){ + Threadmsg->hs_status = ESPCONN_OK; + } ets_post(lwIPThreadPrio, NETCONN_EVENT_CLOSE,(uint32)Threadmsg); } return ret; diff --git a/app/mbedtls/app/lwIPSocket.c b/app/mbedtls/app/lwIPSocket.c index 87a09a2a..6739b06f 100644 --- a/app/mbedtls/app/lwIPSocket.c +++ b/app/mbedtls/app/lwIPSocket.c @@ -302,6 +302,20 @@ static err_t do_accepted(void *arg, struct tcp_pcb *newpcb, err_t err) lwIP_netconn *newconn = NULL; lwIP_netconn *conn = arg; err = ERR_OK; + + //Avoid two TCP connections coming in simultaneously + struct tcp_pcb *pactive_pcb; + int active_pcb_num=0; + for(pactive_pcb = tcp_active_pcbs; pactive_pcb != NULL; pactive_pcb = pactive_pcb->next){ + if (pactive_pcb->state == ESTABLISHED ||pactive_pcb->state == SYN_RCVD){ + active_pcb_num++; + if (active_pcb_num > MEMP_NUM_TCP_PCB){ + ESP_LOG("%s %d active_pcb_number:%d\n",__FILE__, __LINE__,active_pcb_num); + return ERR_MEM; + } + } + } + lwIP_REQUIRE_ACTION(conn, exit, err = ESP_ARG); /* We have to set the callback here even though * the new socket is unknown. conn->socket is marked as -1. */ @@ -738,23 +752,30 @@ int lwip_close(int s) return -1; } - if (sock->conn->state != NETCONN_STATE_ERROR){ - tcp_recv(sock->conn->tcp, NULL); - err = tcp_close(sock->conn->tcp); + /*Do not set callback function when tcp->state is LISTEN. + Avoid memory overlap when conn->tcp changes from + struct tcp_bcb to struct tcp_pcb_listen after lwip_listen.*/ + if (sock->conn->tcp->state != LISTEN) + { + if (sock->conn->state != NETCONN_STATE_ERROR){ + tcp_recv(sock->conn->tcp, NULL); + err = tcp_close(sock->conn->tcp); - if (err != ERR_OK) - { - /* closing failed, try again later */ - tcp_recv(sock->conn->tcp, recv_tcp); - return -1; - } - } - - /* closing succeeded */ - remove_tcp(sock->conn); - free_netconn(sock->conn); - free_socket(sock); - return ERR_OK; + if (err != ERR_OK) + { + /* closing failed, try again later */ + tcp_recv(sock->conn->tcp, recv_tcp); + return -1; + } + } + /* closing succeeded */ + remove_tcp(sock->conn); + } else { + tcp_close(sock->conn->tcp); + } + free_netconn(sock->conn); + free_socket(sock); + return ERR_OK; } int lwip_write(int s, const void *data, size_t size) diff --git a/app/modules/tls.c b/app/modules/tls.c index 4da99f77..4f98e752 100644 --- a/app/modules/tls.c +++ b/app/modules/tls.c @@ -15,6 +15,7 @@ #include "mem.h" #include "lwip/ip_addr.h" #include "espconn.h" +#include "sys/espconn_mbedtls.h" #include "lwip/err.h" #include "lwip/dns.h" diff --git a/app/sqlite3/esp8266.c b/app/sqlite3/esp8266.c index 4347718f..99809167 100644 --- a/app/sqlite3/esp8266.c +++ b/app/sqlite3/esp8266.c @@ -576,8 +576,11 @@ static int esp8266_Sleep( sqlite3_vfs * vfs, int microseconds ) static int esp8266_CurrentTime( sqlite3_vfs * vfs, double * result ) { - time_t t = time(NULL); - *result = t / 86400.0 + 2440587.5; + // This is stubbed out until we have a working RTCTIME solution; + // as it stood, this would always have returned the UNIX epoch. + // time_t t = time(NULL); + // *result = t / 86400.0 + 2440587.5; + *result = 2440587.5; dbg_printf("esp8266_CurrentTime: %g\n", *result); return SQLITE_OK; } diff --git a/app/user/Makefile b/app/user/Makefile index 87f4be55..5ffdb00a 100644 --- a/app/user/Makefile +++ b/app/user/Makefile @@ -24,7 +24,7 @@ STD_CFLAGS=-std=gnu11 -Wimplicit # makefile at its root level - these are then overridden # for a subtree within the makefile rooted therein # -DEFINES += -DESP_INIT_DATA_DEFAULT="\"$(SDK_DIR)/bin/esp_init_data_default.bin\"" +DEFINES += -DESP_INIT_DATA_DEFAULT="\"$(SDK_DIR)/bin/esp_init_data_default_v05.bin\"" ############################################################# # Recursion Magic - Don't touch this!! diff --git a/bin/.gitignore b/bin/.gitignore index 03d17079..fa851d57 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -6,3 +6,4 @@ !.gitignore !blank.bin !esp_init_data_default.bin +!esp_init_data_default_v05.bin diff --git a/ld/nodemcu.ld b/ld/nodemcu.ld index 80a80058..9488045a 100644 --- a/ld/nodemcu.ld +++ b/ld/nodemcu.ld @@ -116,7 +116,6 @@ SECTIONS /* *libcrypto.a:*(.literal .text) - tested that safe to keep in iROM */ /* *libdriver.a:*(.literal .text) - not used anywhere in NodeMCU */ /* *libespnow.a:*(.literal .text) - not used anywhere in NodeMCU */ - /* *libmesh.a:*(.literal .text) - not used anywhere in NodeMCU */ /* *liblwip_536.a:*(.literal .text) - source-based library used instead */ /* *libpwm.a:*(.literal .text) - our own implementation used instead */ /* *libwpa.a:*(.literal .text) - tested that safe to keep in iROM */