diff --git a/util/README.md b/compat/README.md similarity index 99% rename from util/README.md rename to compat/README.md index 6c3b10ba3..fff33837d 100644 --- a/util/README.md +++ b/compat/README.md @@ -3,7 +3,7 @@ If you are using [LWIP raw tcp mode](http://lwip.wikia.com/wiki/Raw/TCP) and wan First you have to include the `lwipr_compat.h` header. ```C -#include "util/lwipr_compat.h" +#include "compat/lwipr_compat.h" ``` Then in the code block where you initialize the tcp raw connection you should call `axl_init`. diff --git a/util/lwipr_compat.c b/compat/lwipr_compat.c similarity index 83% rename from util/lwipr_compat.c rename to compat/lwipr_compat.c index 6cd75188f..834b3f071 100644 --- a/util/lwipr_compat.c +++ b/compat/lwipr_compat.c @@ -6,6 +6,8 @@ */ #include "lwipr_compat.h" +AxlTcpDataArray axlFdArray; + #include /* High Level "public" functions */ @@ -24,6 +26,34 @@ int axl_append(struct tcp_pcb *tcp) { return ax_fd_append(&axlFdArray, tcp); } +/** + * Frees the internal mapping from this tcp. Returns the number of occurrences of the tcp + */ +int axl_free(struct tcp_pcb *tcp) { + int i; + int occurances = 0; + + if(tcp == NULL) { + return 0; + } + + AxlTcpDataArray *vector = &axlFdArray; + AXL_DEBUG("AXL: Freeing %d tcp item", vector->size); + for (i = 0; i < vector->size; i++) { + if (vector->data[i].tcp == tcp) { + if(vector->data[i].tcp_pbuf != NULL) { + pbuf_free(vector->data[i].tcp_pbuf); + vector->data[i].tcp_pbuf = NULL; + } + vector->data[i].tcp = NULL; + vector->data[i].pbuf_offset = 0; + occurances++; + } + } + + return occurances; +} + /** * Reads data from the SSL over TCP stream. Returns decrypted data. * @param SSL *sslObj @@ -63,9 +93,13 @@ int axl_ssl_read(SSL *ssl, uint8_t **in_data, struct tcp_pcb *tcp, struct pbuf * data->pbuf_offset = 0; } + AXL_DEBUG("READY TO READ SOME DATA\n"); + tcp_recved(tcp, p->tot_len); do { + WATCHDOG_FEED(); read_bytes = ssl_read(ssl, in_data); + AXL_DEBUG("axl_ssl_read: Read bytes: %d\n", read_bytes); if(read_bytes < SSL_OK) { /* An error has occurred. Give it back for further processing */ total_bytes = read_bytes; @@ -97,6 +131,7 @@ int ax_port_write(int clientfd, uint8_t *buf, uint16_t bytes_needed) { } if (data == NULL || data->tcp == NULL || buf == NULL || bytes_needed == 0) { + AXL_DEBUG("Return Zero.\n"); return 0; } @@ -116,16 +151,17 @@ int ax_port_write(int clientfd, uint8_t *buf, uint16_t bytes_needed) { } do { - err = tcp_write(data->tcp, buf, tcp_len, TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE); + err = tcp_write(data->tcp, buf, tcp_len, TCP_WRITE_FLAG_COPY); if(err < SSL_OK) { AXL_DEBUG("Got error: %d\n", err); } if (err == ERR_MEM) { + AXL_DEBUG("Not enough memory to write data with length: %d (%d)\n", tcp_len, bytes_needed); tcp_len /= 2; } } while (err == ERR_MEM && tcp_len > 1); - AXL_DEBUG("send_raw_packet length %d\n", tcp_len); + AXL_DEBUG("send_raw_packet length %d(%d)\n", tcp_len, bytes_needed); if (err == ERR_OK) { err = tcp_output(data->tcp); if(err != ERR_OK) { @@ -176,6 +212,11 @@ int ax_port_read(int clientfd, uint8_t *buf, int bytes_needed) { return recv_len; } +int ax_get_file(const char *filename, uint8_t **buf) { + *buf = 0; + return 0; +} + /* * Utility functions */ diff --git a/util/lwipr_compat.h b/compat/lwipr_compat.h similarity index 86% rename from util/lwipr_compat.h rename to compat/lwipr_compat.h index 1e5d73fa2..1a8846f94 100644 --- a/util/lwipr_compat.h +++ b/compat/lwipr_compat.h @@ -8,14 +8,16 @@ #ifndef LWIPR_COMPAT_H #define LWIPR_COMPAT_H -#include - /* * All those functions will run only if LWIP tcp raw mode is used */ #if LWIP_RAW==1 -#include "lwip/tcp.h" +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwipr_platform.h" #include "ssl/ssl.h" #include "ssl/tls1.h" @@ -31,7 +33,14 @@ * Define the AXL_DEBUG function to add debug functionality */ #ifndef AXL_DEBUG -#define AXL_DEBUG printf + #define AXL_DEBUG(...) +#endif + +/** + * Define watchdog function to be called during CPU intensive operations. + */ +#ifndef WATCHDOG_FEED + #define WATCHDOG_FEED() #endif typedef struct { @@ -47,14 +56,13 @@ typedef struct { AxlTcpData *data; /* array of TcpData objects */ } AxlTcpDataArray; -AxlTcpDataArray axlFdArray; - /* * High Level Functions - these are the ones that should be used directly */ void axl_init(int capacity); int axl_append(struct tcp_pcb *tcp); +int axl_free(struct tcp_pcb *tcp); #define axl_ssl_write(A, B, C) ssl_write(A, B, C) int axl_ssl_read(SSL *sslObj, uint8_t **in_data, struct tcp_pcb *tcp, struct pbuf *p); @@ -77,6 +85,11 @@ void ax_fd_set(AxlTcpDataArray *vector, int index, struct tcp_pcb *tcp); void ax_fd_double_capacity_if_full(AxlTcpDataArray *vector); void ax_fd_free(AxlTcpDataArray *vector); + +#ifdef __cplusplus +} #endif +#endif /* LWIP_RAW==1 */ + #endif /* LWIPR_COMPAT_H */ diff --git a/compat/lwipr_platform.h b/compat/lwipr_platform.h new file mode 100644 index 000000000..518e8bf4e --- /dev/null +++ b/compat/lwipr_platform.h @@ -0,0 +1,27 @@ +/* + * lwipr_platform.h + * + * Created on: Feb 8, 2016 + * Author: slavey + * + */ + +#ifndef AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ +#define AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ + +/* Add here all platform specific things */ + + +// Some calls require the watchdog to be reset +#ifndef WATCHDOG_FEED + #define WATCHDOG_FEED() +#endif + + +/* SSL_DEBUG is for more information */ +#ifndef SSL_DEBUG + #define AXL_DEBUG(...) +#endif + + +#endif /* AXTLS_8266_COMPAT_LWIPR_PLATFORM_H_ */ diff --git a/replacements/time.c b/replacements/time.c new file mode 100644 index 000000000..4972119bb --- /dev/null +++ b/replacements/time.c @@ -0,0 +1,147 @@ +/* + * time.c - ESP8266-specific functions for SNTP + * Copyright (c) 2015 Peter Dobler. All rights reserved. + * This file is part of the esp8266 core for Arduino environment. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include + +extern uint32_t system_get_time(void); +extern uint64_t system_mktime(uint32_t year, uint32_t mon, uint32_t day, uint32_t hour, uint32_t min, uint32_t sec); + +static int errno_var = 0; + +int* __errno(void) { + // DEBUGV("__errno is called last error: %d (not current)\n", errno_var); + return &errno_var; +} + +unsigned long millis(void) +{ + return system_get_time() / 1000UL; +} + +unsigned long micros(void) +{ + return system_get_time(); +} + +#ifndef _TIMEVAL_DEFINED +#define _TIMEVAL_DEFINED +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +}; +#endif + +extern char* sntp_asctime(const struct tm *t); +extern struct tm* sntp_localtime(const time_t *clock); + +// time gap in seconds from 01.01.1900 (NTP time) to 01.01.1970 (UNIX time) +#define DIFF1900TO1970 2208988800UL + +static int s_daylightOffset_sec = 0; +static long s_timezone_sec = 0; +static time_t s_bootTime = 0; + +// calculate offset used in gettimeofday +static void ensureBootTimeIsSet() +{ + if (!s_bootTime) + { + time_t now = sntp_get_current_timestamp(); + if (now) + { + s_bootTime = now - millis() / 1000; + } + } +} + +static void setServer(int id, const char* name_or_ip) +{ + if (name_or_ip) + { + //TODO: check whether server is given by name or IP + sntp_setservername(id, (char*) name_or_ip); + } +} + +void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3) +{ + sntp_stop(); + + setServer(0, server1); + setServer(1, server2); + setServer(2, server3); + + s_timezone_sec = timezone; + s_daylightOffset_sec = daylightOffset_sec; + sntp_set_timezone(timezone/3600); + sntp_init(); +} + +int clock_gettime(clockid_t unused, struct timespec *tp) +{ + tp->tv_sec = millis() / 1000; + tp->tv_nsec = micros() * 1000; + return 0; +} + +// seconds since 1970 +time_t mktime(struct tm *t) +{ + // system_mktime expects month in range 1..12 + #define START_MONTH 1 + return DIFF1900TO1970 + system_mktime(t->tm_year, t->tm_mon + START_MONTH, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); +} + +time_t time(time_t * t) +{ + time_t seconds = sntp_get_current_timestamp(); + if (t) + { + *t = seconds; + } + return seconds; +} + +char* asctime(const struct tm *t) +{ + return sntp_asctime(t); +} + +struct tm* localtime(const time_t *clock) +{ + return sntp_localtime(clock); +} + +char* ctime(const time_t *t) +{ + struct tm* p_tm = localtime(t); + char* result = asctime(p_tm); + return result; +} + +int gettimeofday(struct timeval *tp, void *tzp) +{ + if (tp) + { + ensureBootTimeIsSet(); + tp->tv_sec = (s_bootTime + millis()) / 1000; + tp->tv_usec = micros() * 1000; + } + return 0; +}