Browse Source

Merge branch 'master' into v_master

v_master
Sara Damiano 5 years ago
parent
commit
f0dd33ffe3
9 changed files with 932 additions and 41 deletions
  1. +1
    -1
      .github/ISSUE_TEMPLATE.md
  2. +2
    -1
      .travis.yml
  3. +1
    -1
      library.json
  4. +1
    -1
      library.properties
  5. +8
    -2
      src/TinyGsmClient.h
  6. +42
    -31
      src/TinyGsmClientSIM5360.h
  7. +873
    -0
      src/TinyGsmClientSIM7600.h
  8. +3
    -3
      src/TinyGsmClientSaraR4.h
  9. +1
    -1
      src/TinyGsmCommon.h

+ 1
- 1
.github/ISSUE_TEMPLATE.md View File

@ -23,7 +23,7 @@ with your board before submitting any issues.
Main processor board: <!-- Uno, Zero, ESP32, Particle, etc --> Main processor board: <!-- Uno, Zero, ESP32, Particle, etc -->
Modem: <!-- Brand, model, variant, firmware version --> Modem: <!-- Brand, model, variant, firmware version -->
TinyGSM version: <!-- always try to use the latest (0.9.6) -->
TinyGSM version: <!-- always try to use the latest (0.9.7) -->
Code: <!-- Example name or paste in your code --> Code: <!-- Example name or paste in your code -->
### Scenario, steps to reproduce ### Scenario, steps to reproduce


+ 2
- 1
.travis.yml View File

@ -26,7 +26,8 @@ env:
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_MC60' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_MC60' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM800' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM800' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM808' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM808' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM5360' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM5360' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM7600' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM7000' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SIM7000' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_UBLOX' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_UBLOX' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"
- PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SARAR4' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev" - PLATFORMIO_CI_SRC=tools/test_build PLATFORMIO_CI_ARGS="--project-option='build_flags=-D TINY_GSM_MODEM_SARAR4' --project-option='framework=arduino' --board=uno --board=leonardo --board=yun --board=megaatmega2560 --board=genuino101 --board=mkr1000USB --board=zero --board=teensy31 --board=bluepill_f103c8 --board=uno_pic32 --board=esp01 --board=nodemcuv2 --board=esp32dev"


+ 1
- 1
library.json View File

@ -1,6 +1,6 @@
{ {
"name": "TinyGSM", "name": "TinyGSM",
"version": "0.9.6",
"version": "0.9.7",
"description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports many GSM, LTE, and WiFi modules with AT command interfaces.", "description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports many GSM, LTE, and WiFi modules with AT command interfaces.",
"keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM7000, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968, M95, MC60, MC60E, BG96, ublox, Quectel, SIMCOM, AI Thinker, LTE, LTE-M", "keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM7000, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968, M95, MC60, MC60E, BG96, ublox, Quectel, SIMCOM, AI Thinker, LTE, LTE-M",
"authors": "authors":


+ 1
- 1
library.properties View File

@ -1,5 +1,5 @@
name=TinyGSM name=TinyGSM
version=0.9.6
version=0.9.7
author=Volodymyr Shymanskyy author=Volodymyr Shymanskyy
maintainer=Volodymyr Shymanskyy maintainer=Volodymyr Shymanskyy
sentence=A small Arduino library for GPRS modules, that just works. sentence=A small Arduino library for GPRS modules, that just works.


+ 8
- 2
src/TinyGsmClient.h View File

@ -41,13 +41,19 @@
// typedef TinyGsmSim7000::GsmClientSecure TinyGsmClientSecure; TODO! // typedef TinyGsmSim7000::GsmClientSecure TinyGsmClientSecure; TODO!
#elif defined(TINY_GSM_MODEM_SIM5320) || defined(TINY_GSM_MODEM_SIM5360) || \ #elif defined(TINY_GSM_MODEM_SIM5320) || defined(TINY_GSM_MODEM_SIM5360) || \
defined(TINY_GSM_MODEM_SIM5300) || defined(TINY_GSM_MODEM_SIM7100) || \
defined(TINY_GSM_MODEM_SIM7500) || defined(TINY_GSM_MODEM_SIM7600)
defined(TINY_GSM_MODEM_SIM5300) || defined(TINY_GSM_MODEM_SIM7100)
#define TINY_GSM_MODEM_HAS_GPRS #define TINY_GSM_MODEM_HAS_GPRS
#include <TinyGsmClientSIM5360.h> #include <TinyGsmClientSIM5360.h>
typedef TinyGsmSim5360 TinyGsm; typedef TinyGsmSim5360 TinyGsm;
typedef TinyGsmSim5360::GsmClient TinyGsmClient; typedef TinyGsmSim5360::GsmClient TinyGsmClient;
#elif defined(TINY_GSM_MODEM_SIM7600) || defined(TINY_GSM_MODEM_SIM7800) || \
defined(TINY_GSM_MODEM_SIM7500)
#define TINY_GSM_MODEM_HAS_GPRS
#include <TinyGsmClientSIM7600.h>
typedef TinyGsmSim7600 TinyGsm;
typedef TinyGsmSim7600::GsmClient TinyGsmClient;
#elif defined(TINY_GSM_MODEM_UBLOX) #elif defined(TINY_GSM_MODEM_UBLOX)
#define TINY_GSM_MODEM_HAS_GPRS #define TINY_GSM_MODEM_HAS_GPRS
#define TINY_GSM_MODEM_HAS_SSL #define TINY_GSM_MODEM_HAS_SSL


+ 42
- 31
src/TinyGsmClientSIM5360.h View File

@ -58,13 +58,13 @@ class GsmClient : public Client
public: public:
GsmClient() {} GsmClient() {}
GsmClient(TinyGsmSim5360& modem, uint8_t mux = 1) {
GsmClient(TinyGsmSim5360& modem, uint8_t mux = 0) {
init(&modem, mux); init(&modem, mux);
} }
virtual ~GsmClient(){} virtual ~GsmClient(){}
bool init(TinyGsmSim5360* modem, uint8_t mux = 1) {
bool init(TinyGsmSim5360* modem, uint8_t mux = 0) {
this->at = modem; this->at = modem;
this->mux = mux; this->mux = mux;
sock_available = 0; sock_available = 0;
@ -324,7 +324,7 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
waitResponse(); waitResponse();
} }
// Define PDP context 1
// Define external PDP context 1
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"',",\"0.0.0.0\",0,0"); sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"',",\"0.0.0.0\",0,0");
waitResponse(); waitResponse();
@ -399,24 +399,12 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
} }
// Stop the socket service // Stop the socket service
// Note: all sockets should be closed first
// Note: all sockets should be closed first - on 3G/4G models the sockets must be closed manually
sendAT(GF("+NETCLOSE")); sendAT(GF("+NETCLOSE"));
if (waitResponse(60000L, GF(GSM_NL "+NETCLOSE: 0")) != 1) { if (waitResponse(60000L, GF(GSM_NL "+NETCLOSE: 0")) != 1) {
return false; return false;
} }
// Deactivate PDP context 1
sendAT(GF("+CGACT=1,0"));
if (waitResponse(40000L) != 1) {
return false;
}
// Detach from GPRS
sendAT(GF("+CGATT=0"));
if (waitResponse(360000L) != 1) {
return false;
}
return true; return true;
} }
@ -473,8 +461,10 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
*/ */
String sendUSSD(const String& code) { String sendUSSD(const String& code) {
// Select message format (1=text)
sendAT(GF("+CMGF=1")); sendAT(GF("+CMGF=1"));
waitResponse(); waitResponse();
// Select TE character set
sendAT(GF("+CSCS=\"HEX\"")); sendAT(GF("+CSCS=\"HEX\""));
waitResponse(); waitResponse();
sendAT(GF("+CUSD=1,\""), code, GF("\"")); sendAT(GF("+CUSD=1,\""), code, GF("\""));
@ -499,14 +489,16 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
} }
bool sendSMS(const String& number, const String& text) { bool sendSMS(const String& number, const String& text) {
// Get SMS service centre address
sendAT(GF("+AT+CSCA?")); sendAT(GF("+AT+CSCA?"));
waitResponse(); waitResponse();
// Select message format (1=text)
sendAT(GF("+CMGF=1")); sendAT(GF("+CMGF=1"));
waitResponse(); waitResponse();
//Set GSM 7 bit default alphabet (3GPP TS 23.038) //Set GSM 7 bit default alphabet (3GPP TS 23.038)
sendAT(GF("+CSCS=\"GSM\"")); sendAT(GF("+CSCS=\"GSM\""));
waitResponse(); waitResponse();
// Send the message!
sendAT(GF("+CMGS=\""), number, GF("\"")); sendAT(GF("+CMGS=\""), number, GF("\""));
if (waitResponse(GF(">")) != 1) { if (waitResponse(GF(">")) != 1) {
return false; return false;
@ -518,13 +510,16 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
} }
bool sendSMS_UTF16(const String& number, const void* text, size_t len) { bool sendSMS_UTF16(const String& number, const void* text, size_t len) {
// Select message format (1=text)
sendAT(GF("+CMGF=1")); sendAT(GF("+CMGF=1"));
waitResponse(); waitResponse();
// Select TE character set
sendAT(GF("+CSCS=\"HEX\"")); sendAT(GF("+CSCS=\"HEX\""));
waitResponse(); waitResponse();
// Set text mode parameters
sendAT(GF("+CSMP=17,167,0,8")); sendAT(GF("+CSMP=17,167,0,8"));
waitResponse(); waitResponse();
// Send the message
sendAT(GF("+CMGS=\""), number, GF("\"")); sendAT(GF("+CMGS=\""), number, GF("\""));
if (waitResponse(GF(">")) != 1) { if (waitResponse(GF(">")) != 1) {
return false; return false;
@ -571,10 +566,12 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
} }
streamSkipUntil(','); // Skip battery charge status streamSkipUntil(','); // Skip battery charge status
streamSkipUntil(','); // Skip battery charge level streamSkipUntil(','); // Skip battery charge level
// return voltage in mV
uint16_t res = stream.readStringUntil(',').toInt();
// get voltage in VOLTS
float voltage = stream.readStringUntil('\n').toFloat();
// Wait for final OK // Wait for final OK
waitResponse(); waitResponse();
// Return millivolts
uint16_t res = voltage*1000;
return res; return res;
} }
@ -610,17 +607,31 @@ TINY_GSM_MODEM_WAIT_FOR_NETWORK()
} }
chargeState = stream.readStringUntil(',').toInt(); chargeState = stream.readStringUntil(',').toInt();
percent = stream.readStringUntil(',').toInt(); percent = stream.readStringUntil(',').toInt();
milliVolts = stream.readStringUntil('\n').toInt();
// get voltage in VOLTS
float voltage = stream.readStringUntil('\n').toFloat();
milliVolts = voltage*1000;
// Wait for final OK // Wait for final OK
waitResponse(); waitResponse();
return true; return true;
} }
float getTemperature() TINY_GSM_ATTR_NOT_AVAILABLE;
// ToDo:
// # Enable Temparature Reading:
//AT+CMTE=1
//AT+CMTE?
// get temperature in degree celsius
float getTemperature() {
// Enable Temparature Reading
sendAT(GF("+CMTE=1"));
if (waitResponse() != 1) {
return 0;
}
// Get Temparature Value
sendAT(GF("+CMTE?"));
if (waitResponse(GF(GSM_NL "+CMTE:")) != 1) {
return false;
}
float res = stream.readStringUntil('\n').toFloat();
// Wait for final OK
waitResponse();
return res;
}
/* /*
* Client related functions * Client related functions
@ -636,9 +647,9 @@ protected:
return false; return false;
} }
// Establish a connection in multi-socket mode
// Establish a connection in multi-socket mode
sendAT(GF("+CIPOPEN="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port); sendAT(GF("+CIPOPEN="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
// The reply is +CIPOPEN: ## of socket created
// The reply is +CIPOPEN: ## of socket created
if (waitResponse(15000L, GF(GSM_NL "+CIPOPEN:")) != 1) { if (waitResponse(15000L, GF(GSM_NL "+CIPOPEN:")) != 1) {
return false; return false;
} }
@ -693,7 +704,6 @@ protected:
#endif #endif
sockets[mux]->rx.put(c); sockets[mux]->rx.put(c);
} }
DBG("### READ:", len_requested, "from", mux); DBG("### READ:", len_requested, "from", mux);
// sockets[mux]->sock_available = modemGetAvailable(mux); // sockets[mux]->sock_available = modemGetAvailable(mux);
sockets[mux]->sock_available = len_confirmed; sockets[mux]->sock_available = len_confirmed;
@ -719,9 +729,10 @@ protected:
bool modemGetConnected(uint8_t mux) { bool modemGetConnected(uint8_t mux) {
// Read the status of all sockets at once // Read the status of all sockets at once
sendAT(GF("+CIPCLOSE?"), mux);
if (waitResponse(GFP(GSM_OK), GF("+CIPCLOSE: ")) != 2)
sendAT(GF("+CIPCLOSE?"));
if (waitResponse(GF("+CIPCLOSE:")) != 1) {
return false; return false;
}
for (int muxNo = 0; muxNo <= TINY_GSM_MUX_COUNT; muxNo++) { for (int muxNo = 0; muxNo <= TINY_GSM_MUX_COUNT; muxNo++) {
// +CIPCLOSE:<link0_state>,<link1_state>,...,<link9_state> // +CIPCLOSE:<link0_state>,<link1_state>,...,<link9_state>
sockets[muxNo]->sock_connected = stream.parseInt(); sockets[muxNo]->sock_connected = stream.parseInt();


+ 873
- 0
src/TinyGsmClientSIM7600.h View File

@ -0,0 +1,873 @@
/**
* @file TinyGsmClientSIM7600.h
* @author Volodymyr Shymanskyy
* @license LGPL-3.0
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
* @date Nov 2016
*/
#ifndef TinyGsmClientSIM7600_h
#define TinyGsmClientSIM7600_h
// #define TINY_GSM_DEBUG Serial
//#define TINY_GSM_USE_HEX
#if !defined(TINY_GSM_RX_BUFFER)
#define TINY_GSM_RX_BUFFER 64
#endif
#define TINY_GSM_MUX_COUNT 10
#include <TinyGsmCommon.h>
#define GSM_NL "\r\n"
static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL;
static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;
enum SimStatus {
SIM_ERROR = 0,
SIM_READY = 1,
SIM_LOCKED = 2,
};
enum RegStatus {
REG_UNREGISTERED = 0,
REG_SEARCHING = 2,
REG_DENIED = 3,
REG_OK_HOME = 1,
REG_OK_ROAMING = 5,
REG_UNKNOWN = 4,
};
enum TinyGSMDateTimeFormat {
DATE_FULL = 0,
DATE_TIME = 1,
DATE_DATE = 2
};
class TinyGsmSim7600
{
public:
class GsmClient : public Client
{
friend class TinyGsmSim7600;
typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
public:
GsmClient() {}
GsmClient(TinyGsmSim7600& modem, uint8_t mux = 0) {
init(&modem, mux);
}
virtual ~GsmClient(){}
bool init(TinyGsmSim7600* modem, uint8_t mux = 0) {
this->at = modem;
this->mux = mux;
sock_available = 0;
prev_check = 0;
sock_connected = false;
got_data = false;
at->sockets[mux] = this;
return true;
}
public:
virtual int connect(const char *host, uint16_t port, int timeout_s) {
stop();
TINY_GSM_YIELD();
rx.clear();
sock_connected = at->modemConnect(host, port, mux, false, timeout_s);
return sock_connected;
}
TINY_GSM_CLIENT_CONNECT_OVERLOADS()
virtual void stop(uint32_t maxWaitMs) {
TINY_GSM_CLIENT_DUMP_MODEM_BUFFER()
at->sendAT(GF("+CIPCLOSE="), mux);
sock_connected = false;
at->waitResponse();
}
virtual void stop() { stop(15000L); }
TINY_GSM_CLIENT_WRITE()
TINY_GSM_CLIENT_AVAILABLE_WITH_BUFFER_CHECK()
TINY_GSM_CLIENT_READ_WITH_BUFFER_CHECK()
TINY_GSM_CLIENT_PEEK_FLUSH_CONNECTED()
/*
* Extended API
*/
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
private:
TinyGsmSim7600* at;
uint8_t mux;
uint16_t sock_available;
uint32_t prev_check;
bool sock_connected;
bool got_data;
RxFifo rx;
};
public:
TinyGsmSim7600(Stream& stream)
: stream(stream)
{
memset(sockets, 0, sizeof(sockets));
}
virtual ~TinyGsmSim7600(){}
/*
* Basic functions
*/
bool begin(const char* pin = NULL) {
return init(pin);
}
bool init(const char* pin = NULL) {
DBG(GF("### TinyGSM Version:"), TINYGSM_VERSION);
if (!testAT()) {
return false;
}
sendAT(GF("E0")); // Echo Off
if (waitResponse() != 1) {
return false;
}
DBG(GF("### Modem:"), getModemName());
getSimStatus();
return true;
}
String getModemName() {
String name = "SIMCom SIM7600";
sendAT(GF("+CGMM"));
String res2;
if (waitResponse(1000L, res2) != 1) {
return name;
}
res2.replace(GSM_NL "OK" GSM_NL, "");
res2.replace("_", " ");
res2.trim();
name = res2;
DBG("### Modem:", name);
return name;
}
TINY_GSM_MODEM_SET_BAUD_IPR()
TINY_GSM_MODEM_TEST_AT()
TINY_GSM_MODEM_MAINTAIN_CHECK_SOCKS()
bool factoryDefault() { // these commands aren't supported
return false;
}
TINY_GSM_MODEM_GET_INFO_ATI()
bool hasSSL() {
return false; // TODO: Module supports SSL, but not yet implemented
}
bool hasWifi() {
return false;
}
bool hasGPRS() {
return true;
}
/*
* Power functions
*/
bool restart() {
if (!testAT()) {
return false;
}
sendAT(GF("+CRESET"));
if (waitResponse(10000L) != 1) {
return false;
}
delay(5000L); // TODO: Test this delay!
return init();
}
bool poweroff() {
sendAT(GF("+CPOF"));
return waitResponse() == 1;
}
bool radioOff() {
sendAT(GF("+CFUN=4"));
if (waitResponse(10000L) != 1) {
return false;
}
delay(3000);
return true;
}
bool sleepEnable(bool enable = true) {
sendAT(GF("+CSCLK="), enable);
return waitResponse() == 1;
}
/*
* SIM card functions
*/
TINY_GSM_MODEM_SIM_UNLOCK_CPIN()
// Gets the CCID of a sim card via AT+CCID
String getSimCCID() {
sendAT(GF("+CICCID"));
if (waitResponse(GF(GSM_NL "+ICCID:")) != 1) {
return "";
}
String res = stream.readStringUntil('\n');
waitResponse();
res.trim();
return res;
}
TINY_GSM_MODEM_GET_IMEI_GSN()
SimStatus getSimStatus(unsigned long timeout_ms = 10000L) {
for (unsigned long start = millis(); millis() - start < timeout_ms; ) {
sendAT(GF("+CPIN?"));
if (waitResponse(GF(GSM_NL "+CPIN:")) != 1) {
delay(1000);
continue;
}
int status = waitResponse(GF("READY"), GF("SIM PIN"), GF("SIM PUK"));
waitResponse();
switch (status) {
case 2:
case 3: return SIM_LOCKED;
case 1: return SIM_READY;
default: return SIM_ERROR;
}
}
return SIM_ERROR;
}
TINY_GSM_MODEM_GET_REGISTRATION_XREG(CGREG)
TINY_GSM_MODEM_GET_OPERATOR_COPS()
/*
* Generic network functions
*/
TINY_GSM_MODEM_GET_CSQ()
bool isNetworkConnected() {
RegStatus s = getRegistrationStatus();
return (s == REG_OK_HOME || s == REG_OK_ROAMING);
}
String getNetworkModes() {
sendAT(GF("+CNMP=?"));
if (waitResponse(GF(GSM_NL "+CNMP:")) != 1) {
return "";
}
String res = stream.readStringUntil('\n');
waitResponse();
return res;
}
TINY_GSM_MODEM_WAIT_FOR_NETWORK()
String setNetworkMode(uint8_t mode) {
sendAT(GF("+CNMP="), mode);
if (waitResponse(GF(GSM_NL "+CNMP:")) != 1) {
return "OK";
}
String res = stream.readStringUntil('\n');
waitResponse();
return res;
}
/*
* GPRS functions
*/
bool gprsConnect(const char* apn, const char* user = NULL, const char* pwd = NULL) {
gprsDisconnect(); // Make sure we're not connected first
// Define the PDP context
// The CGDCONT commands set up the "external" PDP context
// Set the external authentication
if (user && strlen(user) > 0) {
sendAT(GF("+CGAUTH=1,0,\""), user, GF("\",\""), pwd, '"');
waitResponse();
}
// Define external PDP context 1
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"',",\"0.0.0.0\",0,0");
waitResponse();
// Configure TCP parameters
// Select TCP/IP application mode (command mode)
sendAT(GF("+CIPMODE=0"));
waitResponse();
// Set Sending Mode - send without waiting for peer TCP ACK
sendAT(GF("+CIPSENDMODE=0"));
waitResponse();
// Configure socket parameters
//AT+CIPCCFG= [<NmRetry>][,[<DelayTm>][,[<Ack>][,[<errMode>][,]<HeaderType>][,[[<AsyncMode>][,[<TimeoutVal>]]]]]]]]
// NmRetry = number of retransmission to be made for an IP packet = 10 (default)
// DelayTm = number of milliseconds to delay to output data of Receiving = 0 (default)
// Ack = sets whether reporting a string Send ok = 0 (don't report)
// errMode = mode of reporting error result code = 0 (numberic values)
// HeaderType = which data header of receiving data in multi-client mode = 1 (+RECEIVE,<link num>,<data length>)
// AsyncMode = sets mode of executing commands = 0 (synchronous command executing)
// TimeoutVal = minimum retransmission timeout in milliseconds = 75000
sendAT(GF("+CIPCCFG=10,0,0,0,1,0,75000"));
if (waitResponse() != 1) {
return false;
}
// Configure timeouts for opening and closing sockets
// AT+CIPTIMEOUT=[<netopen_timeout>][, [<cipopen_timeout>][, [<cipsend_timeout>]]]
sendAT(GF("+CIPTIMEOUT="), 75000, ',', 15000, ',', 15000);
waitResponse();
// Start the socket service
// This activates and attaches to the external PDP context that is tied
// to the embedded context for TCP/IP (ie AT+CGACT=1,1 and AT+CGATT=1)
// Response may be an immediate "OK" followed later by "+NETOPEN: 0".
// We to ignore any immediate response and wait for the
// URC to show it's really connected.
sendAT(GF("+NETOPEN"));
if (waitResponse(75000L, GF(GSM_NL "+NETOPEN: 0")) != 1) {
return false;
}
return true;
}
bool gprsDisconnect() {
// Close all sockets and stop the socket service
// Note: On the LTE models, this single command closes all sockets and the service
sendAT(GF("+NETCLOSE"));
if (waitResponse(60000L, GF(GSM_NL "+NETCLOSE: 0")) != 1) {
return false;
}
return true;
}
bool isGprsConnected() {
sendAT(GF("+NETOPEN?"));
// May return +NETOPEN: 1, 0. We just confirm that the first number is 1
if (waitResponse(GF(GSM_NL "+NETOPEN: 1")) != 1) {
return false;
}
waitResponse();
sendAT(GF("+IPADDR")); // Inquire Socket PDP address
// sendAT(GF("+CGPADDR=1")); // Show PDP address
if (waitResponse() != 1) {
return false;
}
return true;
}
/*
* IP Address functions
*/
String getLocalIP() {
sendAT(GF("+IPADDR")); // Inquire Socket PDP address
// sendAT(GF("+CGPADDR=1")); // Show PDP address
String res;
if (waitResponse(10000L, res) != 1) {
return "";
}
res.replace(GSM_NL "OK" GSM_NL, "");
res.replace(GSM_NL, "");
res.trim();
return res;
}
IPAddress localIP() {
return TinyGsmIpFromString(getLocalIP());
}
/*
* Phone Call functions
*/
bool setGsmBusy() TINY_GSM_ATTR_NOT_IMPLEMENTED;
bool callAnswer() TINY_GSM_ATTR_NOT_IMPLEMENTED;
bool callNumber() TINY_GSM_ATTR_NOT_IMPLEMENTED;
bool callHangup() TINY_GSM_ATTR_NOT_IMPLEMENTED;
bool dtmfSend() TINY_GSM_ATTR_NOT_IMPLEMENTED;
/*
* Messaging functions
*/
String sendUSSD(const String& code) {
// Select message format (1=text)
sendAT(GF("+CMGF=1"));
waitResponse();
// Select TE character set
sendAT(GF("+CSCS=\"HEX\""));
waitResponse();
sendAT(GF("+CUSD=1,\""), code, GF("\""));
if (waitResponse() != 1) {
return "";
}
if (waitResponse(10000L, GF(GSM_NL "+CUSD:")) != 1) {
return "";
}
stream.readStringUntil('"');
String hex = stream.readStringUntil('"');
stream.readStringUntil(',');
int dcs = stream.readStringUntil('\n').toInt();
if (dcs == 15) {
return TinyGsmDecodeHex8bit(hex);
} else if (dcs == 72) {
return TinyGsmDecodeHex16bit(hex);
} else {
return hex;
}
}
bool sendSMS(const String& number, const String& text) {
// Get SMS service centre address
sendAT(GF("+AT+CSCA?"));
waitResponse();
// Select message format (1=text)
sendAT(GF("+CMGF=1"));
waitResponse();
//Set GSM 7 bit default alphabet (3GPP TS 23.038)
sendAT(GF("+CSCS=\"GSM\""));
waitResponse();
// Send the message!
sendAT(GF("+CMGS=\""), number, GF("\""));
if (waitResponse(GF(">")) != 1) {
return false;
}
stream.print(text);
stream.write((char)0x1A);
stream.flush();
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<len; i++) {
uint8_t c = t[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
*/
String getGsmLocation() TINY_GSM_ATTR_NOT_IMPLEMENTED;
/*
* GPS location functions
*/
// enable GPS
bool enableGPS() {
sendAT(GF("+CGPS=1"));
if (waitResponse() != 1) {
return false;
}
return true;
}
bool disableGPS() {
sendAT(GF("+CGPS=0"));
if (waitResponse() != 1) {
return false;
}
return true;
}
// get the RAW GPS output
String getGPSraw() {
sendAT(GF("+CGNSSINFO=32"));
if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) {
return "";
}
String res = stream.readStringUntil('\n');
waitResponse();
res.trim();
return res;
}
// get GPS informations
bool getGPS(float *lat, float *lon, float *speed=0, int *alt=0, int *vsat=0, int *usat=0) {
//String buffer = "";
bool fix = false;
sendAT(GF("+CGNSSINFO"));
if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) {
return false;
}
//stream.readStringUntil(','); // mode
if ( stream.readStringUntil(',').toInt() == 1 ) fix = true;
stream.readStringUntil(','); //gps
stream.readStringUntil(','); // glonass
stream.readStringUntil(','); // beidu
*lat = stream.readStringUntil(',').toFloat(); //lat
stream.readStringUntil(','); // N/S
*lon = stream.readStringUntil(',').toFloat(); //lon
stream.readStringUntil(','); // E/W
stream.readStringUntil(','); // date
stream.readStringUntil(','); // UTC time
if (alt != NULL) *alt = stream.readStringUntil(',').toFloat(); //alt
if (speed != NULL) *speed = stream.readStringUntil(',').toFloat(); //speed
stream.readStringUntil(','); //course
stream.readStringUntil(','); //time
stream.readStringUntil(',');//PDOP
stream.readStringUntil(',');//HDOP
stream.readStringUntil(',');//VDOP
//if (vsat != NULL) *vsat = stream.readStringUntil(',').toInt(); //viewed satelites
//if (usat != NULL) *usat = stream.readStringUntil(',').toInt(); //used satelites
stream.readStringUntil('\n');
waitResponse();
return fix;
}
/*
* Time functions
*/
/*
* Battery & temperature functions
*/
// Use: float vBatt = modem.getBattVoltage() / 1000.0;
uint16_t getBattVoltage() {
sendAT(GF("+CBC"));
if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
return 0;
}
// get voltage in VOLTS
float voltage = stream.readStringUntil('\n').toFloat();
// Wait for final OK
waitResponse();
// Return millivolts
uint16_t res = voltage*1000;
return res;
}
int8_t getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
uint8_t getBattChargeState() TINY_GSM_ATTR_NOT_AVAILABLE;
bool getBattStats(uint8_t &chargeState, int8_t &percent, uint16_t &milliVolts) {
sendAT(GF("+CBC?"));
if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
return false;
}
// get voltage in VOLTS
float voltage = stream.readStringUntil('\n').toFloat();
milliVolts = voltage*1000;
// Wait for final OK
waitResponse();
return true;
}
// get temperature in degree celsius
uint16_t getTemperature() {
sendAT(GF("+CPMUTEMP"));
if (waitResponse(GF(GSM_NL "+CPMUTEMP:")) != 1) {
return 0;
}
// return temperature in C
uint16_t res = stream.readStringUntil('\n').toInt();
// Wait for final OK
waitResponse();
return res;
}
/*
* Client related functions
*/
protected:
bool modemConnect(const char* host, uint16_t port, uint8_t mux,
bool ssl = false, int timeout_s = 75) {
// Make sure we'll be getting data manually on this connection
sendAT(GF("+CIPRXGET=1"));
if (waitResponse() != 1) {
return false;
}
// Establish a connection in multi-socket mode
sendAT(GF("+CIPOPEN="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
// The reply is +CIPOPEN: ## of socket created
if (waitResponse(15000L, GF(GSM_NL "+CIPOPEN:")) != 1) {
return false;
}
return true;
}
int16_t modemSend(const void* buff, size_t len, uint8_t mux) {
sendAT(GF("+CIPSEND="), mux, ',', len);
if (waitResponse(GF(">")) != 1) {
return 0;
}
stream.write((uint8_t*)buff, len);
stream.flush();
if (waitResponse(GF(GSM_NL "+CIPSEND:")) != 1) {
return 0;
}
streamSkipUntil(','); // Skip mux
streamSkipUntil(','); // Skip requested bytes to send
// TODO: make sure requested and confirmed bytes match
return stream.readStringUntil('\n').toInt();
}
size_t modemRead(size_t size, uint8_t mux) {
#ifdef TINY_GSM_USE_HEX
sendAT(GF("+CIPRXGET=3,"), mux, ',', size);
if (waitResponse(GF("+CIPRXGET:")) != 1) {
return 0;
}
#else
sendAT(GF("+CIPRXGET=2,"), mux, ',', size);
if (waitResponse(GF("+CIPRXGET:")) != 1) {
return 0;
}
#endif
streamSkipUntil(','); // Skip Rx mode 2/normal or 3/HEX
streamSkipUntil(','); // Skip mux/cid (connecion id)
size_t len_requested = stream.readStringUntil(',').toInt();
// ^^ Requested number of data bytes (1-1460 bytes)to be read
size_t len_confirmed = stream.readStringUntil('\n').toInt();
// ^^ The data length which not read in the buffer
for (size_t i=0; i<len_requested; i++) {
uint32_t startMillis = millis();
#ifdef TINY_GSM_USE_HEX
while (stream.available() < 2 && (millis() - startMillis < sockets[mux]->_timeout)) { TINY_GSM_YIELD(); }
char buf[4] = { 0, };
buf[0] = stream.read();
buf[1] = stream.read();
char c = strtol(buf, NULL, 16);
#else
while (!stream.available() && (millis() - startMillis < sockets[mux]->_timeout)) { TINY_GSM_YIELD(); }
char c = stream.read();
#endif
sockets[mux]->rx.put(c);
}
DBG("### READ:", len_requested, "from", mux);
// sockets[mux]->sock_available = modemGetAvailable(mux);
sockets[mux]->sock_available = len_confirmed;
waitResponse();
return len_requested;
}
size_t modemGetAvailable(uint8_t mux) {
sendAT(GF("+CIPRXGET=4,"), mux);
size_t result = 0;
if (waitResponse(GF("+CIPRXGET:")) == 1) {
streamSkipUntil(','); // Skip mode 4
streamSkipUntil(','); // Skip mux
result = stream.readStringUntil('\n').toInt();
waitResponse();
}
DBG("### Available:", result, "on", mux);
if (!result) {
sockets[mux]->sock_connected = modemGetConnected(mux);
}
return result;
}
bool modemGetConnected(uint8_t mux) {
// Read the status of all sockets at once
sendAT(GF("+CIPCLOSE?"));
if (waitResponse(GF("+CIPCLOSE:")) != 1) {
// return false; // TODO: Why does this not read correctly?
}
for (int muxNo = 0; muxNo <= TINY_GSM_MUX_COUNT; muxNo++) {
// +CIPCLOSE:<link0_state>,<link1_state>,...,<link9_state>
sockets[muxNo]->sock_connected = stream.parseInt();
}
waitResponse(); // Should be an OK at the end
return sockets[mux]->sock_connected;
}
public:
/*
Utilities
*/
TINY_GSM_MODEM_STREAM_UTILITIES()
// TODO: Optimize this!
uint8_t waitResponse(uint32_t timeout_ms, String& data,
GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
{
/*String r1s(r1); r1s.trim();
String r2s(r2); r2s.trim();
String r3s(r3); r3s.trim();
String r4s(r4); r4s.trim();
String r5s(r5); r5s.trim();
DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
data.reserve(64);
int index = 0;
unsigned long startMillis = millis();
do {
TINY_GSM_YIELD();
while (stream.available() > 0) {
TINY_GSM_YIELD();
int a = stream.read();
if (a <= 0) continue; // Skip 0x00 bytes, just in case
data += (char)a;
if (r1 && data.endsWith(r1)) {
index = 1;
goto finish;
} else if (r2 && data.endsWith(r2)) {
index = 2;
goto finish;
} else if (r3 && data.endsWith(r3)) {
index = 3;
goto finish;
} else if (r4 && data.endsWith(r4)) {
index = 4;
goto finish;
} else if (r5 && data.endsWith(r5)) {
index = 5;
goto finish;
} else if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) {
String mode = stream.readStringUntil(',');
if (mode.toInt() == 1) {
int mux = stream.readStringUntil('\n').toInt();
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
sockets[mux]->got_data = true;
}
data = "";
DBG("### Got Data:", mux);
} else {
data += mode;
}
} else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) {
int mux = stream.readStringUntil(',').toInt();
int len = stream.readStringUntil('\n').toInt();
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
sockets[mux]->got_data = true;
sockets[mux]->sock_available = len;
}
data = "";
DBG("### Got Data:", len, "on", mux);
} else if (data.endsWith(GF("+IPCLOSE:"))) {
int mux = stream.readStringUntil(',').toInt();
streamSkipUntil('\n'); // Skip the reason code
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
sockets[mux]->sock_connected = false;
}
data = "";
DBG("### Closed: ", mux);
} else if (data.endsWith(GF("+CIPEVENT:"))) {
// Need to close all open sockets and release the network library.
// User will then need to reconnect.
DBG("### Network error!");
if (!isGprsConnected()) {
gprsDisconnect();
}
data = "";
}
}
} while (millis() - startMillis < timeout_ms);
finish:
if (!index) {
data.trim();
if (data.length()) {
DBG("### Unhandled:", data);
}
data = "";
}
//data.replace(GSM_NL, "/");
//DBG('<', index, '>', data);
return index;
}
uint8_t waitResponse(uint32_t timeout_ms,
GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
{
String data;
return waitResponse(timeout_ms, data, r1, r2, r3, r4, r5);
}
uint8_t waitResponse(GsmConstStr r1=GFP(GSM_OK), GsmConstStr r2=GFP(GSM_ERROR),
GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL)
{
return waitResponse(1000, r1, r2, r3, r4, r5);
}
public:
Stream& stream;
protected:
GsmClient* sockets[TINY_GSM_MUX_COUNT];
};
#endif

+ 3
- 3
src/TinyGsmClientSaraR4.h View File

@ -326,7 +326,7 @@ TINY_GSM_MODEM_GET_SIMCCID_CCID()
return SIM_ERROR; return SIM_ERROR;
} }
TINY_GSM_MODEM_GET_REGISTRATION_XREG(CEREG)
TINY_GSM_MODEM_GET_REGISTRATION_XREG(CREG)
TINY_GSM_MODEM_GET_OPERATOR_COPS() TINY_GSM_MODEM_GET_OPERATOR_COPS()
@ -340,8 +340,8 @@ TINY_GSM_MODEM_GET_CSQ()
RegStatus s = getRegistrationStatus(); RegStatus s = getRegistrationStatus();
if (s == REG_OK_HOME || s == REG_OK_ROAMING) if (s == REG_OK_HOME || s == REG_OK_ROAMING)
return true; return true;
else if (s == REG_UNKNOWN) // for some reason, it can hang at unknown..
return isGprsConnected();
// else if (s == REG_UNKNOWN) // for some reason, it can hang at unknown..
// return isGprsConnected();
else return false; else return false;
} }


+ 1
- 1
src/TinyGsmCommon.h View File

@ -10,7 +10,7 @@
#define TinyGsmCommon_h #define TinyGsmCommon_h
// The current library version number // The current library version number
#define TINYGSM_VERSION "0.9.6"
#define TINYGSM_VERSION "0.9.7"
#if defined(SPARK) || defined(PARTICLE) #if defined(SPARK) || defined(PARTICLE)
#include "Particle.h" #include "Particle.h"


Loading…
Cancel
Save