Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update fork with master #1

Merged
merged 11 commits into from
Jul 4, 2018
7 changes: 5 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
"type": "git",
"url": "https://github.com/me-no-dev/ESPAsyncTCP.git"
},
"version": "1.1.0",
"version": "1.1.3",
"license": "LGPL-3.0",
"frameworks": "arduino",
"platforms":"espressif8266"
"platforms": "espressif8266",
"build": {
"libCompatMode": 2
}
}
83 changes: 55 additions & 28 deletions src/ESPAsyncTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extern "C"{
#include "lwip/tcp.h"
#include "lwip/inet.h"
#include "lwip/dns.h"
#include "lwip/init.h"
}
#include <tcp_axtls.h>

Expand All @@ -49,6 +50,8 @@ AsyncClient::AsyncClient(tcp_pcb* pcb):
, _error_cb_arg(0)
, _recv_cb(0)
, _recv_cb_arg(0)
, _pb_cb(0)
, _pb_cb_arg(0)
, _timeout_cb(0)
, _timeout_cb_arg(0)
, _pcb_busy(false)
Expand Down Expand Up @@ -110,11 +113,12 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
return false;
ip_addr_t addr;
addr.addr = ip;
#if LWIP_VERSION_MAJOR == 1
netif* interface = ip_route(&addr);
if (!interface){ //no route to host
return false;
}

#endif
tcp_pcb* pcb = tcp_new();
if (!pcb){ //could not allocate pcb
return false;
Expand Down Expand Up @@ -281,7 +285,7 @@ size_t AsyncClient::ack(size_t len){

// Private Callbacks

int8_t AsyncClient::_connected(void* pcb, int8_t err){
err_t AsyncClient::_connected(void* pcb, err_t err){
_pcb = reinterpret_cast<tcp_pcb*>(pcb);
if(_pcb){
_pcb_busy = false;
Expand Down Expand Up @@ -334,7 +338,7 @@ int8_t AsyncClient::_close(){
return err;
}

void AsyncClient::_error(int8_t err) {
void AsyncClient::_error(err_t err) {
if(_pcb){
#if ASYNC_TCP_SSL_ENABLED
if(_pcb_secure){
Expand All @@ -361,7 +365,7 @@ void AsyncClient::_ssl_error(int8_t err){
}
#endif

int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) {
err_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) {
_rx_last_packet = millis();
ASYNC_TCP_DEBUG("_sent: %u\n", len);
_tx_unacked_len -= len;
Expand All @@ -375,7 +379,7 @@ int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) {
return ERR_OK;
}

int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
err_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, err_t err) {
if(pb == NULL){
ASYNC_TCP_DEBUG("_recv: pb == NULL! Closing... %d\n", err);
return _close();
Expand All @@ -400,21 +404,25 @@ int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) {
//we should not ack before we assimilate the data
_ack_pcb = true;
pbuf *b = pb;
ASYNC_TCP_DEBUG("_recv: %d\n", b->len);
if(_recv_cb)
_recv_cb(_recv_cb_arg, this, b->payload, b->len);
if(!_ack_pcb)
_rx_ack_len += b->len;
else
tcp_recved(pcb, b->len);
pb = b->next;
b->next = NULL;
pbuf_free(b);
ASYNC_TCP_DEBUG("_recv: %d\n", b->len);
if(_pb_cb){
_pb_cb(_pb_cb_arg, this, b);
} else {
if(_recv_cb)
_recv_cb(_recv_cb_arg, this, b->payload, b->len);
if(!_ack_pcb)
_rx_ack_len += b->len;
else
tcp_recved(pcb, b->len);
pbuf_free(b);
}
}
return ERR_OK;
}

int8_t AsyncClient::_poll(tcp_pcb* pcb){
err_t AsyncClient::_poll(tcp_pcb* pcb){
// Close requested
if(_close_pcb){
_close_pcb = false;
Expand Down Expand Up @@ -448,7 +456,11 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){
return ERR_OK;
}

void AsyncClient::_dns_found(ip_addr_t *ipaddr){
#if LWIP_VERSION_MAJOR == 1
void AsyncClient::_dns_found(struct ip_addr *ipaddr){
#else
void AsyncClient::_dns_found(const ip_addr *ipaddr){
#endif
if(ipaddr){
#if ASYNC_TCP_SSL_ENABLED
connect(IPAddress(ipaddr->addr), _connect_port, _pcb_secure);
Expand All @@ -464,28 +476,31 @@ void AsyncClient::_dns_found(ip_addr_t *ipaddr){
}

// lWIP Callbacks

#if LWIP_VERSION_MAJOR == 1
void AsyncClient::_s_dns_found(const char *name, ip_addr_t *ipaddr, void *arg){
#else
void AsyncClient::_s_dns_found(const char *name, const ip_addr *ipaddr, void *arg){
#endif
reinterpret_cast<AsyncClient*>(arg)->_dns_found(ipaddr);
}

int8_t AsyncClient::_s_poll(void *arg, struct tcp_pcb *tpcb) {
err_t AsyncClient::_s_poll(void *arg, struct tcp_pcb *tpcb) {
return reinterpret_cast<AsyncClient*>(arg)->_poll(tpcb);
}

int8_t AsyncClient::_s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err) {
err_t AsyncClient::_s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err) {
return reinterpret_cast<AsyncClient*>(arg)->_recv(tpcb, pb, err);
}

void AsyncClient::_s_error(void *arg, int8_t err) {
void AsyncClient::_s_error(void *arg, err_t err) {
reinterpret_cast<AsyncClient*>(arg)->_error(err);
}

int8_t AsyncClient::_s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len) {
err_t AsyncClient::_s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len) {
return reinterpret_cast<AsyncClient*>(arg)->_sent(tpcb, len);
}

int8_t AsyncClient::_s_connected(void* arg, void* tpcb, int8_t err){
err_t AsyncClient::_s_connected(void* arg, void* tpcb, err_t err){
return reinterpret_cast<AsyncClient*>(arg)->_connected(tpcb, err);
}

Expand Down Expand Up @@ -681,6 +696,11 @@ void AsyncClient::onData(AcDataHandler cb, void* arg){
_recv_cb_arg = arg;
}

void AsyncClient::onPacket(AcPacketHandler cb, void* arg){
_pb_cb = cb;
_pb_cb_arg = arg;
}

void AsyncClient::onTimeout(AcTimeoutHandler cb, void* arg){
_timeout_cb = cb;
_timeout_cb_arg = arg;
Expand Down Expand Up @@ -715,6 +735,14 @@ size_t AsyncClient::space(){
return 0;
}

void AsyncClient::ackPacket(struct pbuf * pb){
if(!pb){
return;
}
tcp_recved(_pcb, pb->len);
pbuf_free(pb);
}

const char * AsyncClient::errorToString(int8_t error){
switch(error){
case 0: return "OK";
Expand Down Expand Up @@ -855,7 +883,6 @@ void AsyncServer::beginSecure(const char *cert, const char *key, const char *pas
void AsyncServer::end(){
if(_pcb){
//cleanup all connections?
tcp_abort(_pcb);
tcp_arg(_pcb, NULL);
tcp_accept(_pcb, NULL);
if(tcp_close(_pcb) != ERR_OK){
Expand Down Expand Up @@ -896,7 +923,7 @@ uint8_t AsyncServer::status(){
return _pcb->state;
}

int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err){
err_t AsyncServer::_accept(tcp_pcb* pcb, err_t err){
if(_connect_cb){
#if ASYNC_TCP_SSL_ENABLED
if (_noDelay || _ssl_ctx)
Expand Down Expand Up @@ -964,12 +991,12 @@ int8_t AsyncServer::_accept(tcp_pcb* pcb, int8_t err){
return ERR_OK;
}

int8_t AsyncServer::_s_accept(void *arg, tcp_pcb* pcb, int8_t err){
err_t AsyncServer::_s_accept(void *arg, tcp_pcb* pcb, err_t err){
return reinterpret_cast<AsyncServer*>(arg)->_accept(pcb, err);
}

#if ASYNC_TCP_SSL_ENABLED
int8_t AsyncServer::_poll(tcp_pcb* pcb){
err_t AsyncServer::_poll(tcp_pcb* pcb){
if(!tcp_ssl_has_client() && _pending){
struct pending_pcb * p = _pending;
if(p->pcb == pcb){
Expand All @@ -995,7 +1022,7 @@ int8_t AsyncServer::_poll(tcp_pcb* pcb){
return ERR_OK;
}

int8_t AsyncServer::_recv(struct tcp_pcb *pcb, struct pbuf *pb, int8_t err){
err_t AsyncServer::_recv(struct tcp_pcb *pcb, struct pbuf *pb, err_t err){
if(!_pending)
return ERR_OK;

Expand Down Expand Up @@ -1047,11 +1074,11 @@ int AsyncServer::_s_cert(void *arg, const char *filename, uint8_t **buf){
return reinterpret_cast<AsyncServer*>(arg)->_cert(filename, buf);
}

int8_t AsyncServer::_s_poll(void *arg, struct tcp_pcb *pcb){
err_t AsyncServer::_s_poll(void *arg, struct tcp_pcb *pcb){
return reinterpret_cast<AsyncServer*>(arg)->_poll(pcb);
}

int8_t AsyncServer::_s_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, int8_t err){
err_t AsyncServer::_s_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, err_t err){
return reinterpret_cast<AsyncServer*>(arg)->_recv(pcb, pb, err);
}
#endif
67 changes: 43 additions & 24 deletions src/ESPAsyncTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,19 @@
#include "IPAddress.h"
#include <functional>

extern "C" {
#include "lwip/init.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
};

class AsyncClient;

#define ASYNC_MAX_ACK_TIME 5000
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
#define ASYNC_WRITE_FLAG_MORE 0x02 //will not send PSH flag, meaning that there should be more data to be sent before the application should react.

typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler;
typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
typedef std::function<void(void*, AsyncClient*, void *data, size_t len)> AcDataHandler;
typedef std::function<void(void*, AsyncClient*, uint32_t time)> AcTimeoutHandler;

struct tcp_pcb;
struct pbuf;
struct ip_addr;
#if ASYNC_TCP_SSL_ENABLED
struct SSL_;
Expand All @@ -48,6 +47,13 @@ struct SSL_CTX_;
typedef struct SSL_CTX_ SSL_CTX;
#endif

typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler;
typedef std::function<void(void*, AsyncClient*, int8_t error)> AcErrorHandler;
typedef std::function<void(void*, AsyncClient*, void *data, size_t len)> AcDataHandler;
typedef std::function<void(void*, AsyncClient*, struct pbuf *pb)> AcPacketHandler;
typedef std::function<void(void*, AsyncClient*, uint32_t time)> AcTimeoutHandler;

class AsyncClient {
protected:
friend class AsyncTCPbuffer;
Expand All @@ -62,6 +68,8 @@ class AsyncClient {
void* _error_cb_arg;
AcDataHandler _recv_cb;
void* _recv_cb_arg;
AcPacketHandler _pb_cb;
void* _pb_cb_arg;
AcTimeoutHandler _timeout_cb;
void* _timeout_cb_arg;
AcConnectHandler _poll_cb;
Expand All @@ -84,20 +92,28 @@ class AsyncClient {
uint16_t _connect_port;

int8_t _close();
int8_t _connected(void* pcb, int8_t err);
void _error(int8_t err);
err_t _connected(void* pcb, err_t err);
void _error(err_t err);
#if ASYNC_TCP_SSL_ENABLED
void _ssl_error(int8_t err);
#endif
int8_t _poll(tcp_pcb* pcb);
int8_t _sent(tcp_pcb* pcb, uint16_t len);
err_t _poll(tcp_pcb* pcb);
err_t _sent(tcp_pcb* pcb, uint16_t len);
#if LWIP_VERSION_MAJOR == 1
void _dns_found(struct ip_addr *ipaddr);
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
static void _s_error(void *arg, int8_t err);
static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
#else
void _dns_found(const ip_addr *ipaddr);
#endif
static err_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err);
static void _s_error(void *arg, err_t err);
static err_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
static err_t _s_connected(void* arg, void* tpcb, err_t err);
#if LWIP_VERSION_MAJOR == 1
static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
#else
static void _s_dns_found(const char *name, const ip_addr *ipaddr, void *arg);
#endif
#if ASYNC_TCP_SSL_ENABLED
static void _s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len);
static void _s_handshake(void *arg, struct tcp_pcb *tcp, SSL *ssl);
Expand Down Expand Up @@ -177,14 +193,17 @@ class AsyncClient {
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
void onAck(AcAckHandler cb, void* arg = 0); //ack received
void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error
void onData(AcDataHandler cb, void* arg = 0); //data received
void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used)
void onPacket(AcPacketHandler cb, void* arg = 0); //data received
void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout
void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected

void ackPacket(struct pbuf * pb);

const char * errorToString(int8_t error);
const char * stateToString();

int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err);
err_t _recv(tcp_pcb* pcb, pbuf* pb, err_t err);
};

#if ASYNC_TCP_SSL_ENABLED
Expand Down Expand Up @@ -224,15 +243,15 @@ class AsyncServer {
uint8_t status();

protected:
int8_t _accept(tcp_pcb* newpcb, int8_t err);
static int8_t _s_accept(void *arg, tcp_pcb* newpcb, int8_t err);
err_t _accept(tcp_pcb* newpcb, err_t err);
static err_t _s_accept(void *arg, tcp_pcb* newpcb, err_t err);
#if ASYNC_TCP_SSL_ENABLED
int _cert(const char *filename, uint8_t **buf);
int8_t _poll(tcp_pcb* pcb);
int8_t _recv(tcp_pcb *pcb, struct pbuf *pb, int8_t err);
err_t _poll(tcp_pcb* pcb);
err_t _recv(tcp_pcb *pcb, struct pbuf *pb, err_t err);
static int _s_cert(void *arg, const char *filename, uint8_t **buf);
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
static err_t _s_poll(void *arg, struct tcp_pcb *tpcb);
static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err);
#endif
};

Expand Down