diff --git a/src/TinyGsmClientA6.h b/src/TinyGsmClientA6.h index 5cb0e34..42760d4 100644 --- a/src/TinyGsmClientA6.h +++ b/src/TinyGsmClientA6.h @@ -457,6 +457,88 @@ public: return res; } + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callAnswer() { + sendAT(GF("A")); + return waitResponse() == 1; + } + + // Returns true on pick-up, false on error/busy + bool callNumber(const String& number) { + if (number == GF("last")) { + sendAT(GF("DLST")); + } else { + sendAT(GF("D\""), number, "\";"); + } + + if (waitResponse(5000L) != 1) { + return false; + } + + if (waitResponse(60000L, + GF(GSM_NL "+CIEV: \"CALL\",1"), + GF(GSM_NL "+CIEV: \"CALL\",0"), + GFP(GSM_ERROR)) != 1) + { + return false; + } + + int rsp = waitResponse(60000L, + GF(GSM_NL "+CIEV: \"SOUNDER\",0"), + GF(GSM_NL "+CIEV: \"CALL\",0")); + + int rsp2 = waitResponse(300L, GF(GSM_NL "BUSY" GSM_NL), GF(GSM_NL "NO ANSWER" GSM_NL)); + + return rsp == 1 && rsp2 == 0; + } + + bool callHangup() { + sendAT(GF("H")); + return waitResponse() == 1; + } + + // 0-9,*,#,A,B,C,D + bool dtmfSend(char cmd, unsigned duration_ms = 100) { + duration_ms = constrain(duration_ms, 100, 1000); + + // The duration parameter is not working, so we simulate it using delay.. + // TODO: Maybe there's another way... + + //sendAT(GF("+VTD="), duration_ms / 100); + //waitResponse(); + + sendAT(GF("+VTS="), cmd); + if (waitResponse(10000L) == 1) { + delay(duration_ms); + return true; + } + return false; + } + + /* + * Audio functions + */ + + bool audioSetHeadphones() { + sendAT(GF("+SNFS=0")); + return waitResponse() == 1; + } + + bool audioSetSpeaker() { + sendAT(GF("+SNFS=1")); + return waitResponse() == 1; + } + + bool audioMuteMic(bool mute) { + sendAT(GF("+CMUT="), mute); + return waitResponse() == 1; + } + /* * Messaging functions */ diff --git a/src/TinyGsmClientBG96.h b/src/TinyGsmClientBG96.h index be7e7aa..ac76365 100644 --- a/src/TinyGsmClientBG96.h +++ b/src/TinyGsmClientBG96.h @@ -474,6 +474,36 @@ public: return res; } + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callAnswer() { + sendAT(GF("A")); + return waitResponse() == 1; + } + + // Returns true on pick-up, false on error/busy + bool callNumber(const String& number) TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool callHangup() { + sendAT(GF("H")); + return waitResponse() == 1; + } + + // 0-9,*,#,A,B,C,D + bool dtmfSend(char cmd, int duration_ms = 100) { // TODO: check + duration_ms = constrain(duration_ms, 100, 1000); + + sendAT(GF("+VTD="), duration_ms / 100); // VTD accepts in 1/10 of a second + waitResponse(); + + sendAT(GF("+VTS="), cmd); + return waitResponse(10000L) == 1; + } + /* * Messaging functions */ diff --git a/src/TinyGsmClientM590.h b/src/TinyGsmClientM590.h index d56f319..d919a17 100644 --- a/src/TinyGsmClientM590.h +++ b/src/TinyGsmClientM590.h @@ -458,6 +458,18 @@ public: return res; } + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE; + /* * Messaging functions */ diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index 085ddae..6b01da1 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -593,6 +593,14 @@ public: return false; } + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE; + bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE; + bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE; /* * Location functions diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index e58f6f5..e34020d 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -40,6 +40,11 @@ enum RegStatus { REG_UNKNOWN = 4, }; +enum TinyGSMDateTimeFormat { + DATE_FULL = 0, + DATE_TIME = 1, + DATE_DATE = 2 +}; class TinyGsmSim800 : public TinyGsmModem { @@ -605,6 +610,57 @@ public: return res; } + + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) { + sendAT(GF("+GSMBUSY="), busy ? 1 : 0); + return waitResponse() == 1; + } + + bool callAnswer() { + sendAT(GF("A")); + return waitResponse() == 1; + } + + // Returns true on pick-up, false on error/busy + bool callNumber(const String& number) { + if (number == GF("last")) { + sendAT(GF("DL")); + } else { + sendAT(GF("D"), number, ";"); + } + int status = waitResponse(60000L, + GFP(GSM_OK), + GF("BUSY" GSM_NL), + GF("NO ANSWER" GSM_NL), + GF("NO CARRIER" GSM_NL)); + switch (status) { + case 1: return true; + case 2: + case 3: return false; + default: return false; + } + } + + bool callHangup() { + sendAT(GF("H")); + return waitResponse() == 1; + } + + // 0-9,*,#,A,B,C,D + bool dtmfSend(char cmd, int duration_ms = 100) { + duration_ms = constrain(duration_ms, 100, 1000); + + sendAT(GF("+VTD="), duration_ms / 100); // VTD accepts in 1/10 of a second + waitResponse(); + + sendAT(GF("+VTS="), cmd); + return waitResponse(10000L) == 1; + } + /* * Messaging functions */ @@ -694,6 +750,32 @@ public: return res; } + /* + * Time functions + */ + String getGSMDateTime(TinyGSMDateTimeFormat format) { + sendAT(GF("+CCLK?")); + if (waitResponse(2000L, GF(GSM_NL "+CCLK: \"")) != 1) { + return ""; + } + + String res; + + switch(format) { + case DATE_FULL: + res = stream.readStringUntil('"'); + break; + case DATE_TIME: + streamSkipUntil(','); + res = stream.readStringUntil('"'); + break; + case DATE_DATE: + res = stream.readStringUntil(','); + break; + } + return res; + } + /* * Battery functions */ diff --git a/src/TinyGsmClientUBLOX.h b/src/TinyGsmClientUBLOX.h index a37eb7c..48556d5 100644 --- a/src/TinyGsmClientUBLOX.h +++ b/src/TinyGsmClientUBLOX.h @@ -494,6 +494,18 @@ public: return res; } + /* + * Phone Call functions + */ + + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callAnswer() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool callNumber(const String& number) TINY_GSM_ATTR_NOT_IMPLEMENTED; + + bool callHangup() TINY_GSM_ATTR_NOT_IMPLEMENTED; + /* * Messaging functions */