9 #ifndef TinyGsmClientESP8266_h 
   10 #define TinyGsmClientESP8266_h 
   14 #if !defined(TINY_GSM_RX_BUFFER) 
   15 #define TINY_GSM_RX_BUFFER 512 
   18 #define TINY_GSM_MUX_COUNT 5 
   20 #include "TinyGsmCommon.h" 
   23 static const char GSM_OK[] TINY_GSM_PROGMEM = 
"OK" GSM_NL;
 
   24 static const char GSM_ERROR[] TINY_GSM_PROGMEM = 
"ERROR" GSM_NL;
 
   25 static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120;
 
   32     class GsmClient : 
public Client
 
   40         GsmClient(
TinyGsm& modem, uint8_t mux = 1)
 
   45         bool init(
TinyGsm* modem, uint8_t mux = 1)
 
   49             sock_connected = 
false;
 
   51             at->sockets[mux] = 
this;
 
   57         virtual int connect(
const char *host, uint16_t port)
 
   62             sock_connected = at->modemConnect(host, port, mux);
 
   63             return sock_connected;
 
   66         virtual int connect(
IPAddress ip, uint16_t port)
 
   77             return connect(host.c_str(), port);
 
   83             at->sendAT(GF(
"+CIPCLOSE="), mux);
 
   84             sock_connected = 
false;
 
   89         virtual size_t write(
const uint8_t *buf, 
size_t size)
 
   93             return at->modemSend(buf, size, mux);
 
   96         virtual size_t write(uint8_t c)
 
  101         virtual int available()
 
  104             if (!rx.size() && sock_connected) {
 
  110         virtual int read(uint8_t *buf, 
size_t size)
 
  115                 size_t chunk = TinyGsmMin(size-cnt, rx.size());
 
  123                 if (!rx.size() && sock_connected) {
 
  134             if (read(&c, 1) == 1) {
 
  149         virtual uint8_t connected()
 
  154             return sock_connected;
 
  156         virtual operator bool()
 
  165         String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
 
  184         virtual int connect(
const char *host, uint16_t port)
 
  189             sock_connected = at->modemConnect(host, port, mux, 
true);
 
  190             return sock_connected;
 
  196     explicit TinyGsm(Stream& stream)
 
  199         memset(sockets, 0, 
sizeof(sockets));
 
  216         if (waitResponse() != 1) {
 
  222     void setBaud(
unsigned long baud)
 
  224         sendAT(GF(
"+IPR="), baud);
 
  227     bool testAT(
unsigned long timeout = 10000L)
 
  229         for (
unsigned long start = millis(); millis() - start < timeout; ) {
 
  231             if (waitResponse(200) == 1) {
 
  242         waitResponse(10, NULL, NULL);
 
  245     bool factoryDefault()
 
  247         sendAT(GF(
"+RESTORE"));
 
  248         return waitResponse() == 1;
 
  251     String getModemInfo()
 
  255         if (waitResponse(1000L, res) != 1) {
 
  258         res.replace(GSM_NL 
"OK" GSM_NL, 
"");
 
  259         res.replace(GSM_NL, 
" ");
 
  279         if (waitResponse(10000L) != 1) {
 
  282         if (waitResponse(10000L, GF(GSM_NL 
"ready" GSM_NL)) != 1) {
 
  294     int getSignalQuality()
 
  296         sendAT(GF(
"+CWJAP_CUR?"));
 
  297         int res1 = waitResponse(GF(
"No AP"), GF(
"+CWJAP_CUR:"));
 
  302         streamSkipUntil(
',');  
 
  303         streamSkipUntil(
',');  
 
  304         streamSkipUntil(
',');  
 
  305         int res2 = stream.parseInt();  
 
  310     bool isNetworkConnected()
 
  312         sendAT(GF(
"+CIPSTATUS"));
 
  313         int res1 = waitResponse(3000, GF(
"STATUS:"));
 
  316             res2 = waitResponse(GFP(GSM_ERROR), GF(
"2"), GF(
"3"), GF(
"4"), GF(
"5"));
 
  324         if (res2 == 2 || res2 == 3 || res2 == 4) {
 
  331     bool waitForNetwork(
unsigned long timeout = 60000L)
 
  333         for (
unsigned long start = millis(); millis() - start < timeout; ) {
 
  334             sendAT(GF(
"+CIPSTATUS"));
 
  335             int res1 = waitResponse(3000, GF(
"busy p..."), GF(
"STATUS:"));
 
  337                 int res2 = waitResponse(GFP(GSM_ERROR), GF(
"2"), GF(
"3"), GF(
"4"), GF(
"5"));
 
  338                 if (res2 == 2 || res2 == 3 || res2 == 4) {
 
  351     bool networkConnect(
const char* ssid, 
const char* pwd)
 
  354         sendAT(GF(
"+CIPMUX=1"));
 
  355         if (waitResponse() != 1) {
 
  359         sendAT(GF(
"+CWMODE_CUR=1"));
 
  360         if (waitResponse() != 1) {
 
  364         sendAT(GF(
"+CWJAP_CUR=\""), ssid, GF(
"\",\""), pwd, GF(
"\""));
 
  365         if (waitResponse(30000L, GFP(GSM_OK), GF(GSM_NL 
"FAIL" GSM_NL)) != 1) {
 
  372     bool networkDisconnect()
 
  374         sendAT(GF(
"+CWQAP"));
 
  375         bool retVal = waitResponse(10000L) == 1;
 
  376         waitResponse(GF(
"WIFI DISCONNECT"));
 
  382         sendAT(GF(
"+CIPSTA_CUR??"));
 
  383         int res1 = waitResponse(GF(
"ERROR"), GF(
"+CWJAP_CUR:"));
 
  387         String res2 = stream.readStringUntil(
'"');
 
  394         return TinyGsmIpFromString(getLocalIP());
 
  399     bool modemConnect(
const char* host, uint16_t port, uint8_t mux, 
bool ssl = 
false)
 
  402             sendAT(GF(
"+CIPSSLSIZE=4096"));
 
  405         sendAT(GF(
"+CIPSTART="), mux, 
',', ssl ? GF(
"\"SSL") : GF(
"\"TCP"), GF(
"\",\""), host, GF(
"\","),
 
  406                port, GF(
","), TINY_GSM_TCP_KEEP_ALIVE);
 
  408         int rsp = waitResponse(75000L,
 
  411                                GF(
"ALREADY CONNECT"));
 
  416     int modemSend(
const void* buff, 
size_t len, uint8_t mux)
 
  418         sendAT(GF(
"+CIPSEND="), mux, 
',', len);
 
  419         if (waitResponse(GF(
">")) != 1) {
 
  422         stream.write((uint8_t*)buff, len);
 
  424         if (waitResponse(10000L, GF(GSM_NL 
"SEND OK" GSM_NL)) != 1) {
 
  430     bool modemGetConnected(uint8_t mux)
 
  433         sendAT(GF(
"+CIPSTATUS="), mux);
 
  434         int res1 = waitResponse(3000, GF(
"STATUS:"));
 
  437             res2 = waitResponse(GFP(GSM_ERROR), GF(
"2"), GF(
"3"), GF(
"4"), GF(
"5"));
 
  445         if (res2 == 2 || res2 == 3 || res2 == 4) {
 
  457     void streamWrite(T 
last)
 
  462     template<
typename T, 
typename... Args>
 
  463     void streamWrite(T head, Args... tail)
 
  466         streamWrite(tail...);
 
  469     bool streamSkipUntil(
char c)   
 
  472             while (!stream.available()) {
 
  475             if (stream.read() == c) {
 
  482     template<
typename... Args>
 
  483     void sendAT(Args... cmd)
 
  485         streamWrite(
"AT", cmd..., GSM_NL);
 
  492     uint8_t waitResponse(uint32_t timeout, String& 
data,
 
  493                          GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
 
  494                          GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
 
  504         unsigned long startMillis = millis();
 
  507             while (stream.available() > 0) {
 
  508                 int a = stream.read();
 
  513                 if (r1 && 
data.endsWith(r1)) {
 
  516                 } 
else if (r2 && 
data.endsWith(r2)) {
 
  519                 } 
else if (r3 && 
data.endsWith(r3)) {
 
  522                 } 
else if (r4 && 
data.endsWith(r4)) {
 
  525                 } 
else if (r5 && 
data.endsWith(r5)) {
 
  528                 } 
else if (
data.endsWith(GF(GSM_NL 
"+IPD,"))) {
 
  529                     int mux = stream.readStringUntil(
',').toInt();
 
  530                     int len = stream.readStringUntil(
':').toInt();
 
  532                     if (len > sockets[mux]->rx.free()) {
 
  533                         DBG(
"### Buffer overflow: ", len, 
"->", sockets[mux]->rx.free());
 
  535                         DBG(
"### Got: ", len, 
"->", sockets[mux]->rx.free());
 
  538                         while (!stream.available()) {
 
  541                         sockets[mux]->rx.put(stream.read());
 
  543                     if (len_orig > sockets[mux]->available()) { 
 
  544                         DBG(
"### Fewer characters received than expected: ", sockets[mux]->available(), 
" vs ", len_orig);
 
  547                 } 
else if (
data.endsWith(GF(
"CLOSED"))) {
 
  548                     int muxStart = 
max(0,
data.lastIndexOf(GSM_NL, 
data.length()-8));
 
  549                     int coma = 
data.indexOf(
',', muxStart);
 
  550                     int mux = 
data.substring(muxStart, coma).toInt();
 
  551                     if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
 
  552                         sockets[mux]->sock_connected = 
false;
 
  555                     DBG(
"### Closed: ", mux);
 
  558         } 
while (millis() - startMillis < timeout);
 
  563                 DBG(
"### Unhandled:", 
data);
 
  570     uint8_t waitResponse(uint32_t timeout,
 
  571                          GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
 
  572                          GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
 
  575         return waitResponse(timeout, 
data, r1, r2, r3, r4, r5);
 
  578     uint8_t waitResponse(GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
 
  579                          GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
 
  581         return waitResponse(1000, r1, r2, r3, r4, r5);
 
  588     GsmClient*    sockets[TINY_GSM_MUX_COUNT];