1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-09 03:41:41 +03:00

Merge pull request #8 from slaff/feature/lwipr-compat

Restructured the lwip raw compatability code.
This commit is contained in:
Ivan Grokhotkov 2016-02-22 13:13:57 +03:00
commit 43a90bcf35
5 changed files with 237 additions and 9 deletions

View File

@ -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. First you have to include the `lwipr_compat.h` header.
```C ```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`. Then in the code block where you initialize the tcp raw connection you should call `axl_init`.

View File

@ -6,6 +6,8 @@
*/ */
#include "lwipr_compat.h" #include "lwipr_compat.h"
AxlTcpDataArray axlFdArray;
#include <stdlib.h> #include <stdlib.h>
/* High Level "public" functions */ /* High Level "public" functions */
@ -24,6 +26,34 @@ int axl_append(struct tcp_pcb *tcp) {
return ax_fd_append(&axlFdArray, 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. * Reads data from the SSL over TCP stream. Returns decrypted data.
* @param SSL *sslObj * @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; data->pbuf_offset = 0;
} }
AXL_DEBUG("READY TO READ SOME DATA\n");
tcp_recved(tcp, p->tot_len); tcp_recved(tcp, p->tot_len);
do { do {
WATCHDOG_FEED();
read_bytes = ssl_read(ssl, in_data); read_bytes = ssl_read(ssl, in_data);
AXL_DEBUG("axl_ssl_read: Read bytes: %d\n", read_bytes);
if(read_bytes < SSL_OK) { if(read_bytes < SSL_OK) {
/* An error has occurred. Give it back for further processing */ /* An error has occurred. Give it back for further processing */
total_bytes = read_bytes; 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) { if (data == NULL || data->tcp == NULL || buf == NULL || bytes_needed == 0) {
AXL_DEBUG("Return Zero.\n");
return 0; return 0;
} }
@ -116,16 +151,17 @@ int ax_port_write(int clientfd, uint8_t *buf, uint16_t bytes_needed) {
} }
do { 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) { if(err < SSL_OK) {
AXL_DEBUG("Got error: %d\n", err); AXL_DEBUG("Got error: %d\n", err);
} }
if (err == ERR_MEM) { if (err == ERR_MEM) {
AXL_DEBUG("Not enough memory to write data with length: %d (%d)\n", tcp_len, bytes_needed);
tcp_len /= 2; tcp_len /= 2;
} }
} while (err == ERR_MEM && tcp_len > 1); } 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) { if (err == ERR_OK) {
err = tcp_output(data->tcp); err = tcp_output(data->tcp);
if(err != ERR_OK) { if(err != ERR_OK) {
@ -176,6 +212,11 @@ int ax_port_read(int clientfd, uint8_t *buf, int bytes_needed) {
return recv_len; return recv_len;
} }
int ax_get_file(const char *filename, uint8_t **buf) {
*buf = 0;
return 0;
}
/* /*
* Utility functions * Utility functions
*/ */

View File

@ -8,14 +8,16 @@
#ifndef LWIPR_COMPAT_H #ifndef LWIPR_COMPAT_H
#define LWIPR_COMPAT_H #define LWIPR_COMPAT_H
#include <stdint.h>
/* /*
* All those functions will run only if LWIP tcp raw mode is used * All those functions will run only if LWIP tcp raw mode is used
*/ */
#if LWIP_RAW==1 #if LWIP_RAW==1
#include "lwip/tcp.h" #ifdef __cplusplus
extern "C" {
#endif
#include "lwipr_platform.h"
#include "ssl/ssl.h" #include "ssl/ssl.h"
#include "ssl/tls1.h" #include "ssl/tls1.h"
@ -31,7 +33,14 @@
* Define the AXL_DEBUG function to add debug functionality * Define the AXL_DEBUG function to add debug functionality
*/ */
#ifndef AXL_DEBUG #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 #endif
typedef struct { typedef struct {
@ -47,14 +56,13 @@ typedef struct {
AxlTcpData *data; /* array of TcpData objects */ AxlTcpData *data; /* array of TcpData objects */
} AxlTcpDataArray; } AxlTcpDataArray;
AxlTcpDataArray axlFdArray;
/* /*
* High Level Functions - these are the ones that should be used directly * High Level Functions - these are the ones that should be used directly
*/ */
void axl_init(int capacity); void axl_init(int capacity);
int axl_append(struct tcp_pcb *tcp); 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) #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); 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_double_capacity_if_full(AxlTcpDataArray *vector);
void ax_fd_free(AxlTcpDataArray *vector); void ax_fd_free(AxlTcpDataArray *vector);
#ifdef __cplusplus
}
#endif #endif
#endif /* LWIP_RAW==1 */
#endif /* LWIPR_COMPAT_H */ #endif /* LWIPR_COMPAT_H */

27
compat/lwipr_platform.h Normal file
View File

@ -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_ */

147
replacements/time.c Normal file
View File

@ -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 <time.h>
#include <sntp.h>
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;
}