Subversion Repositories ESP8266_P1_Meter

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 raymond 1
/*
2
  Asynchronous TCP library for Espressif MCUs
3
 
4
  Copyright (c) 2016 Hristo Gochkov. All rights reserved.
5
  This file is part of the esp8266 core for Arduino environment.
6
 
7
  This library is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public
9
  License as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
 
12
  This library is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
  Lesser General Public License for more details.
16
 
17
  You should have received a copy of the GNU Lesser General Public
18
  License along with this library; if not, write to the Free Software
19
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
*/
21
 
22
#ifndef ASYNCTCP_H_
23
#define ASYNCTCP_H_
24
 
25
#include <async_config.h>
26
#include "IPAddress.h"
27
#include <functional>
28
#include <memory>
29
 
30
extern "C" {
31
    #include "lwip/init.h"
32
    #include "lwip/err.h"
33
    #include "lwip/pbuf.h"
34
};
35
 
36
class AsyncClient;
37
class AsyncServer;
38
class ACErrorTracker;
39
 
40
#define ASYNC_MAX_ACK_TIME 5000
41
#define ASYNC_WRITE_FLAG_COPY 0x01 //will allocate new buffer to hold the data while sending (else will hold reference to the data given)
42
#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.
43
 
44
struct tcp_pcb;
45
struct ip_addr;
46
#if ASYNC_TCP_SSL_ENABLED
47
struct SSL_;
48
typedef struct SSL_ SSL;
49
struct SSL_CTX_;
50
typedef struct SSL_CTX_ SSL_CTX;
51
#endif
52
 
53
typedef std::function<void(void*, AsyncClient*)> AcConnectHandler;
54
typedef std::function<void(void*, AsyncClient*, size_t len, uint32_t time)> AcAckHandler;
55
typedef std::function<void(void*, AsyncClient*, err_t error)> AcErrorHandler;
56
typedef std::function<void(void*, AsyncClient*, void *data, size_t len)> AcDataHandler;
57
typedef std::function<void(void*, AsyncClient*, struct pbuf *pb)> AcPacketHandler;
58
typedef std::function<void(void*, AsyncClient*, uint32_t time)> AcTimeoutHandler;
59
typedef std::function<void(void*, size_t event)> AsNotifyHandler;
60
 
61
enum error_events {
62
  EE_OK = 0,
63
  EE_ABORTED,       // Callback or foreground aborted connections
64
  EE_ERROR_CB,      // Stack initiated aborts via error Callbacks.
65
  EE_CONNECTED_CB,
66
  EE_RECV_CB,
67
  EE_ACCEPT_CB,
68
  EE_MAX
69
};
70
// DEBUG_MORE is for gathering more information on which CBs close events are
71
// occuring and count.
72
// #define DEBUG_MORE 1
73
class ACErrorTracker {
74
  private:
75
    AsyncClient *_client;
76
    err_t _close_error;
77
    int _errored;
78
#if DEBUG_ESP_ASYNC_TCP
79
    size_t _connectionId;
80
#endif
81
#ifdef DEBUG_MORE
82
    AsNotifyHandler _error_event_cb;
83
    void* _error_event_cb_arg;
84
#endif
85
 
86
  protected:
87
    friend class AsyncClient;
88
    friend class AsyncServer;
89
#ifdef DEBUG_MORE
90
    void onErrorEvent(AsNotifyHandler cb, void *arg);
91
#endif
92
#if DEBUG_ESP_ASYNC_TCP
93
    void setConnectionId(size_t id) { _connectionId=id;}
94
    size_t getConnectionId(void) { return _connectionId;}
95
#endif
96
    void setCloseError(err_t e);
97
    void setErrored(size_t errorEvent);
98
    err_t getCallbackCloseError(void);
99
    void clearClient(void){ if (_client) _client = NULL;}
100
 
101
  public:
102
    err_t getCloseError(void) const { return _close_error;}
103
    bool hasClient(void) const { return (_client != NULL);}
104
    ACErrorTracker(AsyncClient *c);
105
    ~ACErrorTracker() {}
106
};
107
 
108
class AsyncClient {
109
  protected:
110
    friend class AsyncTCPbuffer;
111
    friend class AsyncServer;
112
    tcp_pcb* _pcb;
113
    AcConnectHandler _connect_cb;
114
    void* _connect_cb_arg;
115
    AcConnectHandler _discard_cb;
116
    void* _discard_cb_arg;
117
    AcAckHandler _sent_cb;
118
    void* _sent_cb_arg;
119
    AcErrorHandler _error_cb;
120
    void* _error_cb_arg;
121
    AcDataHandler _recv_cb;
122
    void* _recv_cb_arg;
123
    AcPacketHandler _pb_cb;
124
    void* _pb_cb_arg;
125
    AcTimeoutHandler _timeout_cb;
126
    void* _timeout_cb_arg;
127
    AcConnectHandler _poll_cb;
128
    void* _poll_cb_arg;
129
    bool _pcb_busy;
130
#if ASYNC_TCP_SSL_ENABLED
131
    bool _pcb_secure;
132
    bool _handshake_done;
133
#endif
134
    uint32_t _pcb_sent_at;
135
    bool _close_pcb;
136
    bool _ack_pcb;
137
    uint32_t _tx_unacked_len;
138
    uint32_t _tx_acked_len;
139
    uint32_t _rx_ack_len;
140
    uint32_t _rx_last_packet;
141
    uint32_t _rx_since_timeout;
142
    uint32_t _ack_timeout;
143
    uint16_t _connect_port;
144
    u8_t _recv_pbuf_flags;
145
    std::shared_ptr<ACErrorTracker> _errorTracker;
146
 
147
    void _close();
148
    void _connected(std::shared_ptr<ACErrorTracker>& closeAbort, void* pcb, err_t err);
149
    void _error(err_t err);
150
#if ASYNC_TCP_SSL_ENABLED
151
    void _ssl_error(int8_t err);
152
#endif
153
    void _poll(std::shared_ptr<ACErrorTracker>& closeAbort, tcp_pcb* pcb);
154
    void _sent(std::shared_ptr<ACErrorTracker>& closeAbort, tcp_pcb* pcb, uint16_t len);
155
#if LWIP_VERSION_MAJOR == 1
156
    void _dns_found(struct ip_addr *ipaddr);
157
#else
158
    void _dns_found(const ip_addr *ipaddr);
159
#endif
160
    static err_t _s_poll(void *arg, struct tcp_pcb *tpcb);
161
    static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err);
162
    static void _s_error(void *arg, err_t err);
163
    static err_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
164
    static err_t _s_connected(void* arg, void* tpcb, err_t err);
165
#if LWIP_VERSION_MAJOR == 1
166
    static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
167
#else
168
    static void _s_dns_found(const char *name, const ip_addr *ipaddr, void *arg);
169
#endif
170
#if ASYNC_TCP_SSL_ENABLED
171
    static void _s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len);
172
    static void _s_handshake(void *arg, struct tcp_pcb *tcp, SSL *ssl);
173
    static void _s_ssl_error(void *arg, struct tcp_pcb *tcp, int8_t err);
174
#endif
175
    std::shared_ptr<ACErrorTracker> getACErrorTracker(void) const { return _errorTracker; };
176
    void setCloseError(err_t e) const { _errorTracker->setCloseError(e);}
177
 
178
  public:
179
    AsyncClient* prev;
180
    AsyncClient* next;
181
 
182
#if ASYNC_TCP_SSL_ENABLED
183
    AsyncClient(tcp_pcb* pcb = 0, SSL_CTX * ssl_ctx = NULL);
184
#else
185
    AsyncClient(tcp_pcb* pcb = 0);
186
#endif
187
    ~AsyncClient();
188
 
189
    AsyncClient & operator=(const AsyncClient &other);
190
    AsyncClient & operator+=(const AsyncClient &other);
191
 
192
    bool operator==(const AsyncClient &other);
193
 
194
    bool operator!=(const AsyncClient &other) {
195
      return !(*this == other);
196
    }
197
#if ASYNC_TCP_SSL_ENABLED
198
    bool connect(IPAddress ip, uint16_t port, bool secure=false);
199
    bool connect(const char* host, uint16_t port, bool secure=false);
200
#else
201
    bool connect(IPAddress ip, uint16_t port);
202
    bool connect(const char* host, uint16_t port);
203
#endif
204
    void close(bool now = false);
205
    void stop();
206
    void abort();
207
    bool free();
208
 
209
    bool canSend();//ack is not pending
210
    size_t space();
211
    size_t add(const char* data, size_t size, uint8_t apiflags=0);//add for sending
212
    bool send();//send all data added with the method above
213
    size_t ack(size_t len); //ack data that you have not acked using the method below
214
    void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData
215
    bool isRecvPush(){ return !!(_recv_pbuf_flags & PBUF_FLAG_PUSH); }
216
#if DEBUG_ESP_ASYNC_TCP
217
    size_t getConnectionId(void) const { return _errorTracker->getConnectionId();}
218
#endif
219
#if ASYNC_TCP_SSL_ENABLED
220
    SSL *getSSL();
221
#endif
222
 
223
    size_t write(const char* data);
224
    size_t write(const char* data, size_t size, uint8_t apiflags=0); //only when canSend() == true
225
 
226
    uint8_t state();
227
    bool connecting();
228
    bool connected();
229
    bool disconnecting();
230
    bool disconnected();
231
    bool freeable();//disconnected or disconnecting
232
 
233
    uint16_t getMss();
234
    uint32_t getRxTimeout();
235
    void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds
236
    uint32_t getAckTimeout();
237
    void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds
238
    void setNoDelay(bool nodelay);
239
    bool getNoDelay();
240
    uint16_t getRemotePort();
241
    uint16_t getLocalPort();
242
 
243
    IPAddress remoteIP();
244
    uint16_t  remotePort();
245
    IPAddress localIP();
246
    uint16_t  localPort();
247
 
248
    void onConnect(AcConnectHandler cb, void* arg = 0);     //on successful connect
249
    void onDisconnect(AcConnectHandler cb, void* arg = 0);  //disconnected
250
    void onAck(AcAckHandler cb, void* arg = 0);             //ack received
251
    void onError(AcErrorHandler cb, void* arg = 0);         //unsuccessful connect or error
252
    void onData(AcDataHandler cb, void* arg = 0);           //data received (called if onPacket is not used)
253
    void onPacket(AcPacketHandler cb, void* arg = 0);       //data received
254
    void onTimeout(AcTimeoutHandler cb, void* arg = 0);     //ack timeout
255
    void onPoll(AcConnectHandler cb, void* arg = 0);        //every 125ms when connected
256
    void ackPacket(struct pbuf * pb);
257
 
258
    const char * errorToString(err_t error);
259
    const char * stateToString();
260
 
261
    void _recv(std::shared_ptr<ACErrorTracker>& closeAbort, tcp_pcb* pcb, pbuf* pb, err_t err);
262
    err_t getCloseError(void) const { return _errorTracker->getCloseError();}
263
};
264
 
265
#if ASYNC_TCP_SSL_ENABLED
266
typedef std::function<int(void* arg, const char *filename, uint8_t **buf)> AcSSlFileHandler;
267
struct pending_pcb;
268
#endif
269
 
270
 
271
class AsyncServer {
272
  protected:
273
    uint16_t _port;
274
    IPAddress _addr;
275
    bool _noDelay;
276
    tcp_pcb* _pcb;
277
    AcConnectHandler _connect_cb;
278
    void* _connect_cb_arg;
279
#if ASYNC_TCP_SSL_ENABLED
280
    struct pending_pcb * _pending;
281
    SSL_CTX * _ssl_ctx;
282
    AcSSlFileHandler _file_cb;
283
    void* _file_cb_arg;
284
#endif
285
#ifdef DEBUG_MORE
286
    int _event_count[EE_MAX];
287
#endif
288
 
289
  public:
290
 
291
    AsyncServer(IPAddress addr, uint16_t port);
292
    AsyncServer(uint16_t port);
293
    ~AsyncServer();
294
    void onClient(AcConnectHandler cb, void* arg);
295
#if ASYNC_TCP_SSL_ENABLED
296
    void onSslFileRequest(AcSSlFileHandler cb, void* arg);
297
    void beginSecure(const char *cert, const char *private_key_file, const char *password);
298
#endif
299
    void begin();
300
    void end();
301
    void setNoDelay(bool nodelay);
302
    bool getNoDelay();
303
    uint8_t status();
304
#ifdef DEBUG_MORE
305
    int getEventCount(size_t ee) const { return _event_count[ee];}
306
#endif
307
  protected:
308
    err_t _accept(tcp_pcb* newpcb, err_t err);
309
    static err_t _s_accept(void *arg, tcp_pcb* newpcb, err_t err);
310
#ifdef DEBUG_MORE
311
    int incEventCount(size_t ee) { return ++_event_count[ee];}
312
#endif
313
#if ASYNC_TCP_SSL_ENABLED
314
    int _cert(const char *filename, uint8_t **buf);
315
    err_t _poll(tcp_pcb* pcb);
316
    err_t _recv(tcp_pcb *pcb, struct pbuf *pb, err_t err);
317
    static int _s_cert(void *arg, const char *filename, uint8_t **buf);
318
    static err_t _s_poll(void *arg, struct tcp_pcb *tpcb);
319
    static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err);
320
#endif
321
};
322
 
323
 
324
#endif /* ASYNCTCP_H_ */