re-write some of xbee to minimize flash writes

Signed-off-by: Sara Damiano <sdamiano@stroudcenter.org>
This commit is contained in:
Sara Damiano
2021-04-29 14:32:41 -04:00
parent 68a03b3ba0
commit 459106a854

View File

@@ -329,25 +329,43 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
digitalWrite(resetPin, HIGH); digitalWrite(resetPin, HIGH);
} }
if (pin && strlen(pin) > 0) {
DBG("XBee's do not support SIMs that require an unlock pin!");
}
XBEE_COMMAND_START_DECORATOR(10, false) XBEE_COMMAND_START_DECORATOR(10, false)
sendAT(GF("AP0")); // Put in transparent mode bool changesMade = false;
bool ret_val = waitResponse() == 1; bool ret_val = true;
sendAT(GF("GT64")); // shorten the guard time to 100ms // if there's a pin, we need to re-write to flash each time
if (pin && strlen(pin) > 0) {
sendAT(GF("PN"), pin);
if (waitResponse() != 1) {
ret_val = false;
} else {
changesMade = true;
}
}
// Put in transparent mode, if it isn't already
changesMade |= changeSettingIfNeeded(GF("AP"), 0);
// shorten the guard time to 100ms, if it was anything else
sendAT(GF("GT"));
if (readResponseInt() != 64) {
sendAT(GF("GT"), 64);
ret_val &= waitResponse() == 1; ret_val &= waitResponse() == 1;
if (ret_val) guardTime = 110; if (ret_val) {
guardTime = 110;
changesMade = true;
}
} else {
guardTime = 110;
}
// Make sure the command mode drop-out time is long enough that we won't // Make sure the command mode drop-out time is long enough that we won't
// fall out of command mode without intentionally leaving it. This is the // fall out of command mode without intentionally leaving it. This is the
// default drop out time of 0x64 x 100ms (10 seconds) // default drop out time of 0x64 x 100ms (10 seconds)
sendAT(GF("CT64")); changesMade |= changeSettingIfNeeded(GF("CT"), 64);
ret_val &= waitResponse() == 1;
ret_val &= writeChanges(); if (changesMade) { ret_val &= writeChanges(); }
getSeries(); // Get the "Hardware Series"; getSeries(); // Get the "Hardware Series";
@@ -362,25 +380,28 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
void setBaudImpl(uint32_t baud) { void setBaudImpl(uint32_t baud) {
XBEE_COMMAND_START_DECORATOR(5, ) XBEE_COMMAND_START_DECORATOR(5, )
bool changesMade = false;
switch (baud) { switch (baud) {
case 2400: sendAT(GF("BD1")); break; case 2400: changesMade |= changeSettingIfNeeded(GF("BD"), 1); break;
case 4800: sendAT(GF("BD2")); break; case 4800: changesMade |= changeSettingIfNeeded(GF("BD"), 2); break;
case 9600: sendAT(GF("BD3")); break; case 9600: changesMade |= changeSettingIfNeeded(GF("BD"), 3); break;
case 19200: sendAT(GF("BD4")); break; case 19200: changesMade |= changeSettingIfNeeded(GF("BD"), 4); break;
case 38400: sendAT(GF("BD5")); break; case 38400: changesMade |= changeSettingIfNeeded(GF("BD"), 5); break;
case 57600: sendAT(GF("BD6")); break; case 57600: changesMade |= changeSettingIfNeeded(GF("BD"), 6); break;
case 115200: sendAT(GF("BD7")); break; case 115200: changesMade |= changeSettingIfNeeded(GF("BD"), 7); break;
case 230400: sendAT(GF("BD8")); break; case 230400: changesMade |= changeSettingIfNeeded(GF("BD"), 8); break;
case 460800: sendAT(GF("BD9")); break; case 460800: changesMade |= changeSettingIfNeeded(GF("BD"), 9); break;
case 921600: sendAT(GF("BDA")); break; case 921600:
changesMade |= changeSettingIfNeeded(GF("BD"), String("A"));
break;
default: { default: {
DBG(GF("Specified baud rate is unsupported! Setting to 9600 baud.")); DBG(GF("Specified baud rate is unsupported! Setting to 9600 baud."));
sendAT(GF("BD3")); // Set to default of 9600 changesMade |= changeSettingIfNeeded(GF("BD"),
3); // Set to default of 9600
break; break;
} }
} }
waitResponse(); if (changesMade) { writeChanges(); }
writeChanges();
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
} }
@@ -533,20 +554,21 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
if (beeType == XBEE_UNKNOWN) getSeries(); // Command depends on series if (beeType == XBEE_UNKNOWN) getSeries(); // Command depends on series
sendAT(GF("SM"), 1); // Pin sleep bool changesMade = false;
waitResponse();
// Pin sleep
changesMade |= changeSettingIfNeeded(GF("SM"), 1);
if (beeType == XBEE_S6B_WIFI && !maintainAssociation) { if (beeType == XBEE_S6B_WIFI && !maintainAssociation) {
sendAT(GF("SO"), 200); // For lowest power, dissassociated deep sleep // For lowest power, dissassociated deep sleep
waitResponse(); changesMade |= changeSettingIfNeeded(GF("SO"), 200);
} else if (!maintainAssociation) { } else if (!maintainAssociation) {
sendAT(GF("SO"), // For supported cellular modules, maintain association
1); // For supported cellular modules, maintain association
// Not supported by all modules, will return "ERROR" // Not supported by all modules, will return "ERROR"
waitResponse(); changesMade |= changeSettingIfNeeded(GF("SO"), 1);
} }
writeChanges(); if (changesMade) { writeChanges(); }
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
} }
@@ -555,6 +577,7 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
XBEE_COMMAND_START_DECORATOR(5, false) XBEE_COMMAND_START_DECORATOR(5, false)
sendAT(GF("SD")); sendAT(GF("SD"));
bool ret_val = waitResponse(120000L) == 1; bool ret_val = waitResponse(120000L) == 1;
// make sure we're really shut down
if (ret_val) { ret_val &= (sendATGetString(GF("AI")) == "2D"); } if (ret_val) { ret_val &= (sendATGetString(GF("AI")) == "2D"); }
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
return ret_val; return ret_val;
@@ -562,12 +585,13 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
// Enable airplane mode // Enable airplane mode
bool radioOffImpl() { bool radioOffImpl() {
bool success = true;
bool changesMade = false;
XBEE_COMMAND_START_DECORATOR(5, false) XBEE_COMMAND_START_DECORATOR(5, false)
sendAT(GF("AM1")); changesMade = changeSettingIfNeeded(GF("AM"), 1, 5000L);
int8_t res = (1 == waitResponse(5000)); if (changesMade) { success = writeChanges(); }
writeChanges();
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
return res; return success;
} }
bool sleepEnableImpl(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED; bool sleepEnableImpl(bool enable = true) TINY_GSM_ATTR_NOT_IMPLEMENTED;
@@ -742,25 +766,33 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
*/ */
protected: protected:
bool networkConnectImpl(const char* ssid, const char* pwd) { bool networkConnectImpl(const char* ssid, const char* pwd) {
bool changesMade = false;
bool retVal = true; bool retVal = true;
XBEE_COMMAND_START_DECORATOR(5, false) XBEE_COMMAND_START_DECORATOR(5, false)
// nh For no pwd don't set set security or pwd
if (ssid == NULL) retVal = false; if (ssid == NULL) retVal = false;
changesMade |= changeSettingIfNeeded(GF("ID"), ssid);
if (pwd && strlen(pwd) > 0) { if (pwd && strlen(pwd) > 0) {
sendAT(GF("EE"), 2); // Set security to WPA2 // Set security to WPA2
if (waitResponse() != 1) retVal = false; changesMade |= changeSettingIfNeeded(GF("EE"), 2);
// set the password
// the wifi bee will NOT return the previously set password,
// so we have no way of knowing if the passwords has changed
// and must re-write to flash each time
sendAT(GF("PK"), pwd); sendAT(GF("PK"), pwd);
if (waitResponse() != 1) {
retVal = false;
} else { } else {
sendAT(GF("EE"), 0); // Set No security changesMade = true;
}
} else {
changesMade |= changeSettingIfNeeded(GF("EE"), 0); // Set No security
} }
if (waitResponse() != 1) retVal = false;
sendAT(GF("ID"), ssid); if (changesMade) { retVal &= writeChanges(); }
if (waitResponse() != 1) retVal = false;
if (!writeChanges()) retVal = false;
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
@@ -785,35 +817,47 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
bool gprsConnectImpl(const char* apn, const char* user = NULL, bool gprsConnectImpl(const char* apn, const char* user = NULL,
const char* pwd = NULL) { const char* pwd = NULL) {
bool success = true; bool success = true;
bool changesMade = false;
XBEE_COMMAND_START_DECORATOR(5, false)
// the cellular bees will NOT return the previously set username or
// password, so we have no way of knowing if they have changed
// and must re-write to flash each time
if (user && strlen(user) > 0) { if (user && strlen(user) > 0) {
sendAT(GF("CU"), user); // Set the user for the APN sendAT(GF("CU"), user); // Set the user for the APN
success &= waitResponse() == 1; if (waitResponse() != 1) {
success = false;
} else {
changesMade = true;
}
} }
if (pwd && strlen(pwd) > 0) { if (pwd && strlen(pwd) > 0) {
sendAT(GF("CW"), pwd); // Set the password for the APN sendAT(GF("CW"), pwd); // Set the password for the APN
success &= waitResponse() == 1; if (waitResponse() != 1) {
success = false;
} else {
changesMade = true;
} }
XBEE_COMMAND_START_DECORATOR(5, false) }
sendAT(GF("AN"), apn); // Set the APN changesMade |= changeSettingIfNeeded(GF("AN"), String(apn)); // Set the APN
success &= waitResponse() == 1;
sendAT(GF("AM0")); // Airplane mode off changesMade |= changeSettingIfNeeded(GF("AM"), 0,
waitResponse(5000); 5000L); // Airplane mode off
writeChanges();
if (changesMade) { success = writeChanges(); }
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
return success; return success;
} }
bool gprsDisconnectImpl() { bool gprsDisconnectImpl() {
bool success = true;
XBEE_COMMAND_START_DECORATOR(5, false) XBEE_COMMAND_START_DECORATOR(5, false)
sendAT( // Cheating and disconnecting by turning on airplane mode
GF("AM1")); // Cheating and disconnecting by turning on airplane mode bool changesMade = changeSettingIfNeeded(GF("AM"), 1, 5000L);
int8_t res = (1 == waitResponse(5000));
writeChanges(); if (changesMade) { success = writeChanges(); }
// sendAT(GF("AM0")); // Airplane mode off
// waitResponse(5000);
// writeChanges();
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
return res; return success;
} }
bool isGprsConnectedImpl() { bool isGprsConnectedImpl() {
@@ -828,7 +872,7 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
* SIM card functions * SIM card functions
*/ */
protected: protected:
bool simUnlockImpl(const char* pin) { // Not supported bool simUnlockImpl(const char* pin) {
if (pin && strlen(pin) > 0) { if (pin && strlen(pin) > 0) {
sendAT(GF("PN"), pin); sendAT(GF("PN"), pin);
return waitResponse() == 1; return waitResponse() == 1;
@@ -859,17 +903,44 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
String sendUSSDImpl(const String& code) TINY_GSM_ATTR_NOT_AVAILABLE; String sendUSSDImpl(const String& code) TINY_GSM_ATTR_NOT_AVAILABLE;
bool sendSMSImpl(const String& number, const String& text) { bool sendSMSImpl(const String& number, const String& text) {
bool ret_val = true;
bool changesMade = false;
if (!commandMode()) { return false; } // Return immediately if (!commandMode()) { return false; } // Return immediately
sendAT(GF("IP")); // check mode
if (readResponseInt() != 2) {
sendAT(GF("IP"), 2); // Put in text messaging mode sendAT(GF("IP"), 2); // Put in text messaging mode
if (waitResponse() != 1) return exitAndFail(); if (waitResponse() != 1) {
sendAT(GF("PH"), number); // Set the phone number return exitAndFail();
if (waitResponse() != 1) return exitAndFail(); } else {
sendAT(GF("TDD")); // Set the text delimiter to the standard 0x0D (carriage changesMade = true;
// return) }
if (waitResponse() != 1) return exitAndFail(); }
sendAT(GF("PH")); // check last number
if (readResponseString() != String(number)) {
sendAT(GF("PH"), number); // Set the phone number
if (waitResponse() != 1) {
return exitAndFail();
} else {
changesMade = true;
}
}
sendAT(GF("TD")); // check the text delimiter
if (readResponseString() != String("D")) {
sendAT(GF("TDD")); // Set the text delimiter to the standard 0x0D
//(carriage return)
if (waitResponse() != 1) {
return exitAndFail();
} else {
changesMade = true;
}
}
if (changesMade) {
if (!writeChanges()) return exitAndFail(); if (!writeChanges()) return exitAndFail();
}
// Get out of command mode to actually send the text // Get out of command mode to actually send the text
exitCommand(); exitCommand();
@@ -1022,12 +1093,13 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
bool modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0,
bool ssl = false) { bool ssl = false) {
bool success = true; bool success = true;
bool changesMade = false;
if (mux != 0) { if (mux != 0) {
DBG("XBee only supports 1 IP channel in transparent mode!"); DBG("XBee only supports 1 IP channel in transparent mode!");
} }
// empty the saved currelty-in-use destination address // empty the saved currenty-in-use destination address
savedOperatingIP = IPAddress(0, 0, 0, 0); savedOperatingIP = IPAddress(0, 0, 0, 0);
XBEE_COMMAND_START_DECORATOR(5, false) XBEE_COMMAND_START_DECORATOR(5, false)
@@ -1046,19 +1118,19 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
host += ip[3]; host += ip[3];
if (ssl) { if (ssl) {
sendAT(GF("IP"), 4); // Put in SSL over TCP communication mode // Put in SSL over TCP communication mode
success &= (1 == waitResponse()); changesMade |= changeSettingIfNeeded(GF("IP"), 4);
} else { } else {
sendAT(GF("IP"), 1); // Put in TCP mode // Put in TCP mode
success &= (1 == waitResponse()); changesMade |= changeSettingIfNeeded(GF("IP"), 1);
} }
sendAT(GF("DL"), host); // Set the "Destination Address Low" changesMade |= changeSettingIfNeeded(
success &= (1 == waitResponse()); GF("DL"), host); // Set the "Destination Address Low"
sendAT(GF("DE"), String(port, HEX)); // Set the destination port changesMade |= changeSettingIfNeeded(
success &= (1 == waitResponse()); GF("DE"), String(port, HEX)); // Set the destination port
success &= writeChanges(); if (changesMade) { success &= writeChanges(); }
} }
// we'll accept either unknown or connected // we'll accept either unknown or connected
@@ -1114,11 +1186,11 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
if (beeType != XBEE_S6B_WIFI) { if (beeType != XBEE_S6B_WIFI) {
// After a send, verify the outgoing ip if it isn't set // After a send, verify the outgoing ip if it isn't set
if (savedOperatingIP == IPAddress(0, 0, 0, 0)) { if (savedOperatingIP == IPAddress(0, 0, 0, 0)) {
modemGetConnected(); modemGetConnected(0);
} else if (len > 5) { } else if (len > 5) {
// After sending several characters, also re-check // After sending several characters, also re-check
// NOTE: I'm intentionally not checking after every single character! // NOTE: I'm intentionally not checking after every single character!
modemGetConnected(); modemGetConnected(0);
} }
} }
@@ -1436,6 +1508,34 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
return res; return res;
} }
bool changeSettingIfNeeded(GsmConstStr cmd, uint16_t newValue,
uint32_t timeout_ms = 1000L) {
sendAT(cmd);
if (readResponseInt() != newValue) {
sendAT(cmd, newValue);
// return false if we attempted to change but failed
if (waitResponse(timeout_ms) != 1) { return false; }
// return true if we succeeded in staging a change
return true;
}
// return false if no change is needed
return false;
}
bool changeSettingIfNeeded(GsmConstStr cmd, String newValue,
uint32_t timeout_ms = 1000L) {
sendAT(cmd);
if (readResponseString() != newValue) {
sendAT(cmd, newValue);
// return false if we attempted to change but failed
if (waitResponse(timeout_ms) != 1) { return false; }
// return true if we succeeded in staging a change
return true;
}
// return false if no change is needed
return false;
}
bool gotIPforSavedHost() { bool gotIPforSavedHost() {
if (savedHost != "" && savedHostIP != IPAddress(0, 0, 0, 0)) if (savedHost != "" && savedHostIP != IPAddress(0, 0, 0, 0))
return true; return true;