Split out SARAR4

This commit is contained in:
Sara Damiano
2019-05-17 11:11:10 -04:00
parent 99a5b3938c
commit 4c8104dfb6
2 changed files with 997 additions and 166 deletions

View File

@@ -70,22 +70,6 @@ public:
public:
virtual int connect(const char *host, uint16_t port) {
stop();
// If we're creating a new connection on the same client, we need to wait
// until the async close has finished on Cat-M modems.
// After close has completed, the +UUSOCL should appear.
// Without this wait, there might be unexpected behaviors when the same
// client instance attempts to move from one socket to another.
// This is only a problem for the LTE-M modules that take painfully long
// to open and close sockets. For those modules, when connecting to multple
// locations, remember to create multiple clients with different mux numbers.
// TODO: Re-evaluate this!
if (at->isCatM && at->modemGetConnected(mux)) {
DBG("Waiting for +UUSOCL URC on", mux);
for (unsigned long start = millis(); millis() - start < 120000L; ) {
at->maintain();
if (!sock_connected) break;
}
}
TINY_GSM_YIELD();
rx.clear();
@@ -97,6 +81,7 @@ public:
}
at->sockets[mux] = this;
at->maintain();
return sock_connected;
}
@@ -255,7 +240,6 @@ public:
: stream(stream)
{
memset(sockets, 0, sizeof(sockets));
isCatM = false; // For SARA R4 and N4 series
}
/*
@@ -313,12 +297,11 @@ public:
}
res2.replace(GSM_NL "OK" GSM_NL, "");
res2.trim();
String name = res1 + String(' ') + res2;
DBG("### Modem:", name);
if (name.startsWith("u-blox SARA-R4") or name.startsWith("u-blox SARA-N4")) {
DBG("### This is an LTE-M modem!");
isCatM = true;
if (name.startsWith("u-blox SARA-R4") || name.startsWith("u-blox SARA-N4")) {
DBG("### WARNING: You are using the wrong TinyGSM modem!");
}
else if (name.startsWith("u-blox SARA-N2")) {
DBG("### SARA N2 NB-IoT modems not supported!");
@@ -354,16 +337,10 @@ public:
}
bool factoryDefault() {
if (!isCatM) {
sendAT(GF("+UFACTORY=0,1")); // No factory restore, erase NVM
waitResponse();
sendAT(GF("+CFUN=16")); // Reset
return waitResponse() == 1;
}
else {
sendAT(GF("&F")); // Resets the current profile, other NVM not affected
return waitResponse() == 1;
}
sendAT(GF("+UFACTORY=0,1")); // No factory restore, erase NVM
waitResponse();
sendAT(GF("+CFUN=16")); // Reset
return waitResponse() == 1;
}
String getModemInfo() {
@@ -398,14 +375,7 @@ public:
if (!testAT()) {
return false;
}
if (!isCatM)
{
sendAT(GF("+CFUN=16"));
}
else
{
sendAT(GF("+CFUN=15"));
}
sendAT(GF("+CFUN=16"));
if (waitResponse(10000L) != 1) {
return false;
}
@@ -480,17 +450,10 @@ public:
}
RegStatus getRegistrationStatus() {
if (isCatM) { // Check EPS registration for LTE modules
sendAT(GF("+CEREG?"));
if (waitResponse(GF(GSM_NL "+CEREG:")) != 1) {
return REG_UNKNOWN;
}
}
else {
sendAT(GF("+CGREG?")); // Check GPRS registration for others
if (waitResponse(GF(GSM_NL "+CGREG:")) != 1) {
return REG_UNKNOWN;
}
// Check GPRS registration
sendAT(GF("+CGREG?"));
if (waitResponse(GF(GSM_NL "+CGREG:")) != 1) {
return REG_UNKNOWN;
}
streamSkipUntil(','); // Skip format (0)
int status = stream.readStringUntil('\n').toInt();
@@ -542,27 +505,10 @@ public:
return false;
}
bool setURAT( uint8_t urat ) {
// AT+URAT=<SelectedAcT>[,<PreferredAct>[,<2ndPreferredAct>]]
sendAT(GF("+COPS=2")); // Deregister from network
if (waitResponse() != 1) {
return false;
}
sendAT(GF("+URAT="), urat); // Radio Access Technology (RAT) selection
if (waitResponse() != 1) {
return false;
}
sendAT(GF("+COPS=0")); // Auto-register to the network
if (waitResponse() != 1) {
return false;
}
return restart();
}
/*
* GPRS functions
*/
bool gprsConnect(const char* apn, const char* user = NULL, const char* pwd = NULL) {
gprsDisconnect();
@@ -571,83 +517,49 @@ public:
return false;
}
// Using CGDCONT sets up an "external" PCP context, i.e. a data connection
// using the external IP stack (e.g. Windows dial up) and PPP link over the
// serial interface. This is the only command set supported by the LTE-M
// and LTE NB-IoT modules (SARA-R4xx, SARA-N4xx)
// Setting up the PSD profile/PDP context with the UPSD commands sets up an
// "internal" PDP context, i.e. a data connection using the internal IP
// stack and related AT commands for sockets. This is what we're using for
// all of the other modules.
// stack and related AT commands for sockets.
if (isCatM) {
if (user && strlen(user) > 0) {
sendAT(GF("+CGAUTH=1,0,\""), user, GF("\",\""), pwd, '"'); // Set the authentication
waitResponse();
}
sendAT(GF("+UPSD=0,1,\""), apn, '"'); // Set APN for PSD profile 0
waitResponse();
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"'); // Define PDP context 1
if (user && strlen(user) > 0) {
sendAT(GF("+UPSD=0,2,\""), user, '"'); // Set user for PSD profile 0
waitResponse();
}
if (pwd && strlen(pwd) > 0) {
sendAT(GF("+UPSD=0,3,\""), pwd, '"'); // Set password for PSD profile 0
waitResponse();
sendAT(GF("+CGACT=1,1")); // activate PDP profile/context 1
if (waitResponse(150000L) != 1) {
return false;
}
return true;
}
else {
sendAT(GF("+UPSD=0,1,\""), apn, '"'); // Set APN for PSD profile 0
waitResponse();
sendAT(GF("+UPSD=0,7,\"0.0.0.0\"")); // Dynamic IP on PSD profile 0
waitResponse();
if (user && strlen(user) > 0) {
sendAT(GF("+UPSD=0,2,\""), user, '"'); // Set user for PSD profile 0
waitResponse();
}
if (pwd && strlen(pwd) > 0) {
sendAT(GF("+UPSD=0,3,\""), pwd, '"'); // Set password for PSD profile 0
waitResponse();
}
sendAT(GF("+UPSD=0,7,\"0.0.0.0\"")); // Dynamic IP on PSD profile 0
waitResponse();
sendAT(GF("+UPSDA=0,3")); // Activate the PDP context associated with profile 0
if (waitResponse(360000L) != 1) {
return false;
}
sendAT(GF("+UPSND=0,8")); // Activate PSD profile 0
if (waitResponse(GF(",8,1")) != 1) {
return false;
}
waitResponse();
return true;
sendAT(GF("+UPSDA=0,3")); // Activate the PDP context associated with profile 0
if (waitResponse(360000L) != 1) {
return false;
}
sendAT(GF("+UPSND=0,8")); // Activate PSD profile 0
if (waitResponse(GF(",8,1")) != 1) {
return false;
}
waitResponse();
return true;
}
bool gprsDisconnect() {
// LTE-M and NB-IoT modules do not support UPSx commands
if (isCatM) {
sendAT(GF("+CGACT=1,0")); // Deactivate PDP context 1
if (waitResponse(40000L) != 1) {
return false;
}
}
else {
sendAT(GF("+UPSDA=0,4")); // Deactivate the PDP context associated with profile 0
if (waitResponse(360000L) != 1)
return false;
sendAT(GF("+UPSDA=0,4")); // Deactivate the PDP context associated with profile 0
if (waitResponse(360000L) != 1) {
return false;
}
sendAT(GF("+CGATT=0")); // detach from GPRS
if (waitResponse(360000L) != 1)
if (waitResponse(360000L) != 1) {
return false;
}
return true;
}
@@ -670,32 +582,17 @@ public:
*/
String getLocalIP() {
// LTE-M and NB-IoT modules do not support UPSx commands
if (isCatM) {
sendAT(GF("+CGPADDR"));
if (waitResponse(GF(GSM_NL "+CGPADDR:")) != 1) {
return "";
}
streamSkipUntil(','); // Skip context id
String res = stream.readStringUntil('\r');
if (waitResponse() != 1) {
return "";
}
return res;
sendAT(GF("+UPSND=0,0"));
if (waitResponse(GF(GSM_NL "+UPSND:")) != 1) {
return "";
}
else {
sendAT(GF("+UPSND=0,0"));
if (waitResponse(GF(GSM_NL "+UPSND:")) != 1) {
return "";
}
streamSkipUntil(','); // Skip PSD profile
streamSkipUntil('\"'); // Skip request type
String res = stream.readStringUntil('\"');
if (waitResponse() != 1) {
return "";
}
return res;
streamSkipUntil(','); // Skip PSD profile
streamSkipUntil('\"'); // Skip request type
String res = stream.readStringUntil('\"');
if (waitResponse() != 1) {
return "";
}
return res;
}
IPAddress localIP() {
@@ -756,6 +653,7 @@ public:
/*
* Battery functions
*/
uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
int8_t getBattPercent() {
@@ -811,17 +709,10 @@ protected:
return true;
}
bool success;
if (isCatM) { // These modems allow a faster "asynchronous" close
sendAT(GF("+USOCL="), mux, GF(",1"));
success = 1 == waitResponse(120000L); // but it still can take up to 120s to get a response
// TODO: Evaluate whether the speed bump by allowing the async close is worth it
}
else { // no async close
sendAT(GF("+USOCL="), mux);
success = 1 == waitResponse(); // others should return within 1s
if (success) {
sockets[mux]->sock_connected = false;
}
sendAT(GF("+USOCL="), mux);
success = 1 == waitResponse(); // should return within 1s
if (success) {
sockets[mux]->sock_connected = false;
}
return success;
}
@@ -874,7 +765,7 @@ protected:
if (res == 1) {
streamSkipUntil(','); // Skip mux
result = stream.readStringUntil('\n').toInt();
if (result) DBG("### DATA AVAILABLE:", result, "on", mux);
// if (result) DBG("### DATA AVAILABLE:", result, "on", mux);
waitResponse();
}
if (!result && res != 2 && res != 3) { // Don't check modemGetConnected after an error
@@ -1031,7 +922,6 @@ public:
protected:
GsmClient* sockets[TINY_GSM_MUX_COUNT];
bool isCatM;
};
#endif