9 #ifndef TinyGsmClientM590_h
10 #define TinyGsmClientM590_h
14 #if !defined(TINY_GSM_RX_BUFFER)
15 #define TINY_GSM_RX_BUFFER 256
18 #define TINY_GSM_MUX_COUNT 2
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;
47 class GsmClient :
public Client
55 GsmClient(
TinyGsm& modem, uint8_t mux = 1)
60 bool init(
TinyGsm* modem, uint8_t mux = 1)
64 sock_connected =
false;
66 at->sockets[mux] =
this;
72 virtual int connect(
const char *host, uint16_t port)
77 sock_connected = at->modemConnect(host, port, mux);
78 return sock_connected;
81 virtual int connect(
IPAddress ip, uint16_t port)
92 return connect(host.c_str(), port);
98 at->sendAT(GF(
"+TCPCLOSE="), mux);
99 sock_connected =
false;
104 virtual size_t write(
const uint8_t *buf,
size_t size)
108 return at->modemSend(buf, size, mux);
111 virtual size_t write(uint8_t c)
116 virtual int available()
119 if (!rx.size() && sock_connected) {
125 virtual int read(uint8_t *buf,
size_t size)
130 size_t chunk = TinyGsmMin(size-cnt, rx.size());
138 if (!rx.size() && sock_connected) {
149 if (read(&c, 1) == 1) {
164 virtual uint8_t connected()
169 return sock_connected;
171 virtual operator bool()
180 String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
191 explicit
TinyGsm(Stream& stream)
194 memset(sockets, 0,
sizeof(sockets));
211 if (waitResponse() != 1) {
214 #ifdef TINY_GSM_DEBUG
215 sendAT(GF(
"+CMEE=2"));
223 void setBaud(
unsigned long baud)
225 sendAT(GF(
"+IPR="), baud);
228 bool testAT(
unsigned long timeout = 10000L)
230 for (
unsigned long start = millis(); millis() - start < timeout; ) {
232 if (waitResponse(200) == 1) {
244 waitResponse(10, NULL, NULL);
248 bool factoryDefault()
250 sendAT(GF(
"&FZE0&W"));
252 sendAT(GF(
"+ICF=3,1"));
254 sendAT(GF(
"+ENPWRSAVE=0"));
256 sendAT(GF(
"+XISP=0"));
259 return waitResponse() == 1;
262 String getModemInfo()
266 if (waitResponse(1000L, res) != 1) {
269 res.replace(GSM_NL
"OK" GSM_NL,
"");
270 res.replace(GSM_NL,
" ");
289 sendAT(GF(
"+CFUN=15"));
290 if (waitResponse(10000L) != 1) {
294 waitResponse(60000L, GF(GSM_NL
"+PBREADY" GSM_NL));
300 sendAT(GF(
"+CPWROFF"));
301 return waitResponse(3000L) == 1;
304 bool radioOff() TINY_GSM_ATTR_NOT_IMPLEMENTED;
306 bool sleepEnable(
bool enable = true)
308 sendAT(GF(
"+ENPWRSAVE="), enable);
309 return waitResponse() == 1;
316 bool simUnlock(
const char *pin)
318 sendAT(GF(
"+CPIN=\""), pin, GF(
"\""));
319 return waitResponse() == 1;
325 if (waitResponse(GF(GSM_NL
"+CCID:")) != 1) {
328 String res = stream.readStringUntil(
'\n');
337 if (waitResponse(GF(GSM_NL)) != 1) {
340 String res = stream.readStringUntil(
'\n');
346 SimStatus getSimStatus(
unsigned long timeout = 10000L)
348 for (
unsigned long start = millis(); millis() - start < timeout; ) {
349 sendAT(GF(
"+CPIN?"));
350 if (waitResponse(GF(GSM_NL
"+CPIN:")) != 1) {
354 int status = waitResponse(GF(
"READY"), GF(
"SIM PIN"), GF(
"SIM PUK"));
369 RegStatus getRegistrationStatus()
371 sendAT(GF(
"+CREG?"));
372 if (waitResponse(GF(GSM_NL
"+CREG:")) != 1) {
375 streamSkipUntil(
',');
376 int status = stream.readStringUntil(
'\n').toInt();
378 return (RegStatus)status;
383 sendAT(GF(
"+COPS?"));
384 if (waitResponse(GF(GSM_NL
"+COPS:")) != 1) {
387 streamSkipUntil(
'"');
388 String res = stream.readStringUntil(
'"');
397 int getSignalQuality()
400 if (waitResponse(GF(GSM_NL
"+CSQ:")) != 1) {
403 int res = stream.readStringUntil(
',').toInt();
408 bool isNetworkConnected()
410 RegStatus s = getRegistrationStatus();
411 return (s == REG_OK_HOME || s == REG_OK_ROAMING);
414 bool waitForNetwork(
unsigned long timeout = 60000L)
416 for (
unsigned long start = millis(); millis() - start < timeout; ) {
417 if (isNetworkConnected()) {
428 bool gprsConnect(
const char* apn,
const char* user = NULL,
const char* pwd = NULL)
432 sendAT(GF(
"+XISP=0"));
435 sendAT(GF(
"+CGDCONT=1,\"IP\",\""), apn,
'"');
444 sendAT(GF(
"+XGAUTH=1,1,\""), user, GF(
"\",\""), pwd, GF(
"\""));
447 sendAT(GF(
"+XIIC=1"));
450 const unsigned long timeout = 60000L;
451 for (
unsigned long start = millis(); millis() - start < timeout; ) {
452 if (isGprsConnected()) {
461 sendAT(GF(
"+DNSSERVER=1,8.8.8.8"));
464 sendAT(GF(
"+DNSSERVER=2,8.8.4.4"));
470 bool gprsDisconnect()
477 bool isGprsConnected()
479 sendAT(GF(
"+XIIC?"));
480 if (waitResponse(GF(GSM_NL
"+XIIC:")) != 1) {
483 int res = stream.readStringUntil(
',').toInt();
490 sendAT(GF(
"+XIIC?"));
491 if (waitResponse(GF(GSM_NL
"+XIIC:")) != 1) {
494 stream.readStringUntil(
',');
495 String res = stream.readStringUntil(
'\n');
503 return TinyGsmIpFromString(getLocalIP());
510 bool setGsmBusy(
bool busy =
true) TINY_GSM_ATTR_NOT_AVAILABLE;
512 bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE;
514 bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE;
516 bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE;
522 String sendUSSD(const String& code)
524 sendAT(GF(
"+CMGF=1"));
526 sendAT(GF(
"+CSCS=\"HEX\""));
528 sendAT(GF(
"D"), code);
529 if (waitResponse(10000L, GF(GSM_NL
"+CUSD:")) != 1) {
532 stream.readStringUntil(
'"');
533 String hex = stream.readStringUntil(
'"');
534 stream.readStringUntil(
',');
535 int dcs = stream.readStringUntil(
'\n').toInt();
537 if (waitResponse() != 1) {
542 return TinyGsmDecodeHex8bit(hex);
543 }
else if (dcs == 72) {
544 return TinyGsmDecodeHex16bit(hex);
550 bool sendSMS(
const String& number,
const String& text)
552 sendAT(GF(
"+CSCS=\"GSM\""));
554 sendAT(GF(
"+CMGF=1"));
556 sendAT(GF(
"+CMGS=\""), number, GF(
"\""));
557 if (waitResponse(GF(
">")) != 1) {
561 stream.write((
char)0x1A);
563 return waitResponse(60000L) == 1;
566 bool sendSMS_UTF16(
const String& number,
const void* text,
size_t len)
567 TINY_GSM_ATTR_NOT_AVAILABLE;
573 String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
579 uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
581 int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
585 bool modemConnect(const
char* host, uint16_t port, uint8_t mux)
587 for (
int i=0; i<3; i++) {
588 String ip = dnsIpQuery(host);
590 sendAT(GF(
"+TCPSETUP="), mux, GF(
","), ip, GF(
","), port);
591 int rsp = waitResponse(75000L,
594 GF(
"+TCPSETUP:Error" GSM_NL));
597 }
else if (3 == rsp) {
598 sendAT(GF(
"+TCPCLOSE="), mux);
606 int modemSend(
const void* buff,
size_t len, uint8_t mux)
608 sendAT(GF(
"+TCPSEND="), mux,
',', len);
609 if (waitResponse(GF(
">")) != 1) {
612 stream.write((uint8_t*)buff, len);
613 stream.write((
char)0x0D);
615 if (waitResponse(30000L, GF(GSM_NL
"+TCPSEND:")) != 1) {
618 stream.readStringUntil(
'\n');
622 bool modemGetConnected(uint8_t mux)
624 sendAT(GF(
"+CIPSTATUS="), mux);
625 int res = waitResponse(GF(
",\"CONNECTED\""), GF(
",\"CLOSED\""), GF(
",\"CLOSING\""),
631 String dnsIpQuery(
const char* host)
633 sendAT(GF(
"+DNS=\""), host, GF(
"\""));
634 if (waitResponse(10000L, GF(GSM_NL
"+DNS:")) != 1) {
637 String res = stream.readStringUntil(
'\n');
638 waitResponse(GF(
"+DNS:OK" GSM_NL));
648 void streamWrite(T
last)
653 template<
typename T,
typename... Args>
654 void streamWrite(T head, Args... tail)
657 streamWrite(tail...);
660 bool streamSkipUntil(
char c)
663 while (!stream.available()) {
666 if (stream.read() == c) {
673 template<
typename... Args>
674 void sendAT(Args... cmd)
676 streamWrite(
"AT", cmd..., GSM_NL);
683 uint8_t waitResponse(uint32_t timeout, String&
data,
684 GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
685 GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
695 unsigned long startMillis = millis();
698 while (stream.available() > 0) {
699 int a = stream.read();
704 if (r1 &&
data.endsWith(r1)) {
707 }
else if (r2 &&
data.endsWith(r2)) {
710 }
else if (r3 &&
data.endsWith(r3)) {
713 }
else if (r4 &&
data.endsWith(r4)) {
716 }
else if (r5 &&
data.endsWith(r5)) {
719 }
else if (
data.endsWith(GF(
"+TCPRECV:"))) {
720 int mux = stream.readStringUntil(
',').toInt();
721 int len = stream.readStringUntil(
',').toInt();
723 if (len > sockets[mux]->rx.free()) {
724 DBG(
"### Buffer overflow: ", len,
"->", sockets[mux]->rx.free());
726 DBG(
"### Got: ", len,
"->", sockets[mux]->rx.free());
729 while (!stream.available()) {
732 sockets[mux]->rx.put(stream.read());
734 if (len_orig > sockets[mux]->available()) {
735 DBG(
"### Fewer characters received than expected: ", sockets[mux]->available(),
" vs ", len_orig);
738 }
else if (
data.endsWith(GF(
"+TCPCLOSE:"))) {
739 int mux = stream.readStringUntil(
',').toInt();
740 stream.readStringUntil(
'\n');
741 if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
742 sockets[mux]->sock_connected =
false;
745 DBG(
"### Closed: ", mux);
748 }
while (millis() - startMillis < timeout);
753 DBG(
"### Unhandled:",
data);
760 uint8_t waitResponse(uint32_t timeout,
761 GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
762 GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
765 return waitResponse(timeout,
data, r1, r2, r3, r4, r5);
768 uint8_t waitResponse(GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
769 GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
771 return waitResponse(1000, r1, r2, r3, r4, r5);
778 GsmClient* sockets[TINY_GSM_MUX_COUNT];