diff --git a/src/TinyGsmClientBG96.h b/src/TinyGsmClientBG96.h index 9f17776..33143d6 100644 --- a/src/TinyGsmClientBG96.h +++ b/src/TinyGsmClientBG96.h @@ -40,7 +40,7 @@ enum RegStatus { }; -class TinyGsmBG96 +class TinyGsmBG96: public TinyGsmUTFSMS { public: @@ -409,33 +409,6 @@ TINY_GSM_MODEM_GET_GPRS_IP_CONNECTED() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - sendAT(GF("+CMGF=1")); - waitResponse(); - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /* * Location functions diff --git a/src/TinyGsmClientM95.h b/src/TinyGsmClientM95.h index 4cfdfca..d3e37d7 100644 --- a/src/TinyGsmClientM95.h +++ b/src/TinyGsmClientM95.h @@ -40,7 +40,7 @@ enum RegStatus { }; -class TinyGsmM95 +class TinyGsmM95: public TinyGsmUTFSMS { public: @@ -474,33 +474,6 @@ TINY_GSM_MODEM_GET_GPRS_IP_CONNECTED() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - sendAT(GF("+CMGF=1")); - waitResponse(); - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /** Delete all SMS */ bool deleteAllSMS() { sendAT(GF("+QMGDA=6")); diff --git a/src/TinyGsmClientMC60.h b/src/TinyGsmClientMC60.h index 8257ea0..5a5251f 100644 --- a/src/TinyGsmClientMC60.h +++ b/src/TinyGsmClientMC60.h @@ -44,7 +44,7 @@ enum RegStatus { }; -class TinyGsmMC60 +class TinyGsmMC60: public TinyGsmUTFSMS { public: @@ -458,33 +458,6 @@ TINY_GSM_MODEM_GET_GPRS_IP_CONNECTED() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - sendAT(GF("+CMGF=1")); - waitResponse(); - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /** Delete all SMS */ bool deleteAllSMS() { sendAT(GF("+QMGDA=6")); diff --git a/src/TinyGsmClientSIM5360.h b/src/TinyGsmClientSIM5360.h index bac8ee1..e306a2e 100644 --- a/src/TinyGsmClientSIM5360.h +++ b/src/TinyGsmClientSIM5360.h @@ -45,7 +45,7 @@ enum TinyGSMDateTimeFormat { DATE_DATE = 2 }; -class TinyGsmSim5360 +class TinyGsmSim5360: public TinyGsmUTFSMS { public: @@ -520,36 +520,6 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - // Select message format (1=text) - sendAT(GF("+CMGF=1")); - waitResponse(); - // Select TE character set - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - // Set text mode parameters - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - // Send the message - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /* * Location functions diff --git a/src/TinyGsmClientSIM7000.h b/src/TinyGsmClientSIM7000.h index 21c1623..5f56091 100644 --- a/src/TinyGsmClientSIM7000.h +++ b/src/TinyGsmClientSIM7000.h @@ -45,7 +45,7 @@ enum TinyGSMDateTimeFormat { DATE_DATE = 2 }; -class TinyGsmSim7000 +class TinyGsmSim7000: public TinyGsmUTFSMS { public: @@ -562,33 +562,6 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - sendAT(GF("+CMGF=1")); - waitResponse(); - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /* * Location functions diff --git a/src/TinyGsmClientSIM7600.h b/src/TinyGsmClientSIM7600.h index e6fa461..c1ec12f 100644 --- a/src/TinyGsmClientSIM7600.h +++ b/src/TinyGsmClientSIM7600.h @@ -45,7 +45,7 @@ enum TinyGSMDateTimeFormat { DATE_DATE = 2 }; -class TinyGsmSim7600 +class TinyGsmSim7600: public TinyGsmUTFSMS { public: @@ -496,36 +496,6 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - // Select message format (1=text) - sendAT(GF("+CMGF=1")); - waitResponse(); - // Select TE character set - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - // Set text mode parameters - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - // Send the message - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - /* * Location functions diff --git a/src/TinyGsmClientSIM800.h b/src/TinyGsmClientSIM800.h index f3a1206..d91e5d7 100644 --- a/src/TinyGsmClientSIM800.h +++ b/src/TinyGsmClientSIM800.h @@ -46,7 +46,7 @@ enum TinyGSMDateTimeFormat { DATE_DATE = 2 }; -class TinyGsmSim800 +class TinyGsmSim800 : public TinyGsmUTFSMS { public: @@ -593,34 +593,6 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK() return waitResponse(60000L) == 1; } - bool sendSMS_UTF16(const String& number, const void* text, size_t len) { - sendAT(GF("+CMGF=1")); - waitResponse(); - sendAT(GF("+CSCS=\"HEX\"")); - waitResponse(); - sendAT(GF("+CSMP=17,167,0,8")); - waitResponse(); - - sendAT(GF("+CMGS=\""), number, GF("\"")); - if (waitResponse(GF(">")) != 1) { - return false; - } - - uint16_t* t = (uint16_t*)text; - for (size_t i=0; i> 8; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - c = t[i] & 0xFF; - if (c < 0x10) { stream.print('0'); } - stream.print(c, HEX); - } - stream.write((char)0x1A); - stream.flush(); - return waitResponse(60000L) == 1; - } - - /* * Location functions */ diff --git a/src/TinyGsmCommon.h b/src/TinyGsmCommon.h index bb2e541..9803bb2 100644 --- a/src/TinyGsmCommon.h +++ b/src/TinyGsmCommon.h @@ -645,4 +645,77 @@ String TinyGsmDecodeHex16bit(String &instr) { } +//Common methods for UTF8/UTF16 SMS. +//Supported by: BG96, M95, MC60, SIM5360, SIM7000, SIM7600, SIM800 +template +class TinyGsmUTFSMS { +public: + + class UTF8Print : public Print { + public: + UTF8Print(Print& p) : p(p) {} + virtual size_t write(const uint8_t c) override { + if(prv < 0xC0) { + if(c < 0xC0) printHex(c); + prv = c; + } else { + uint16_t v = uint16_t(prv)<<8 | c; + v -= (v>>8 == 0xD0)? 0xCC80 : 0xCD40; + printHex(v); + prv = 0; + } + return 1; + } + private: + Print& p; + uint8_t prv = 0; + void printHex(const uint16_t v) { + uint8_t c = v >> 8; + if (c < 0x10) p.print('0'); + p.print(c, HEX); + c = v & 0xFF; + if (c < 0x10) p.print('0'); + p.print(c, HEX); + } + }; + + bool sendSMS_UTF8_begin(const char* const number) { + static_cast(this)->sendAT(GF("+CMGF=1")); + static_cast(this)->waitResponse(); + static_cast(this)->sendAT(GF("+CSCS=\"HEX\"")); + static_cast(this)->waitResponse(); + static_cast(this)->sendAT(GF("+CSMP=17,167,0,8")); + static_cast(this)->waitResponse(); + + static_cast(this)->sendAT(GF("+CMGS=\""), number, GF("\"")); + return static_cast(this)->waitResponse(GF(">")) == 1; + } + bool sendSMS_UTF8_end() { + static_cast(this)->stream.write((char)0x1A); + static_cast(this)->stream.flush(); + return static_cast(this)->waitResponse(60000L) == 1; + } + UTF8Print sendSMS_UTF8_stream() { + return UTF8Print(static_cast(this)->stream); + } + + bool sendSMS_UTF16(const char* const number, const void* text, size_t len) { + if (!sendSMS_UTF8_begin(number)) { + return false; + } + + uint16_t* t = (uint16_t*)text; + for (size_t i=0; i> 8; + if (c < 0x10) { static_cast(this)->stream.print('0'); } + static_cast(this)->stream.print(c, HEX); + c = t[i] & 0xFF; + if (c < 0x10) { static_cast(this)->stream.print('0'); } + static_cast(this)->stream.print(c, HEX); + } + + return sendSMS_UTF8_end(); + } +}; + #endif