Browse Source

update for Digi WiFi s6b https://github.com/EnviroDIY/ModularSensors/issues/347

dependabot/github_actions/actions/checkout-4
neilh20 1 year ago
parent
commit
191b3b1209
1 changed files with 79 additions and 28 deletions
  1. +79
    -28
      src/TinyGsmClientXBee.h

+ 79
- 28
src/TinyGsmClientXBee.h View File

@ -11,7 +11,9 @@
#define SRC_TINYGSMCLIENTXBEE_H_ #define SRC_TINYGSMCLIENTXBEE_H_
// #pragma message("TinyGSM: TinyGsmClientXBee") // #pragma message("TinyGSM: TinyGsmClientXBee")
// #define TINY_GSM_DEBUG Serial
#ifdef TinyGsmClientXbee_DBG
#define TINY_GSM_DEBUG Serial
#endif //TinyGsmClientXbee_DBG
// XBee's do not support multi-plexing in transparent/command mode // XBee's do not support multi-plexing in transparent/command mode
// The much more complicated API mode is needed for multi-plexing // The much more complicated API mode is needed for multi-plexing
@ -108,9 +110,10 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
} }
public: public:
// NOTE: The XBee saves all connection information (ssid/pwd or apn AND
// last used IP address) in flash (NVM). When you turn it on it immediately
// prepares to re-connect to whatever was last set. The TCP connection
// NOTE: The XBee saves all connection information (ssid/pwd etc) except
// IP address and port number, in flash (NVM).
// The NVM is be updated only when it is initialized.
// The TCP connection
// itself is not opened until you attempt to send data. Because all settings // itself is not opened until you attempt to send data. Because all settings
// are saved to flash, it is possible (or likely) that you could send data // are saved to flash, it is possible (or likely) that you could send data
// even if you haven't "made" any connection. // even if you haven't "made" any connection.
@ -242,7 +245,10 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
* Extended API * Extended API
*/ */
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
String remoteIP() {
IPAddress savedIP = at->savedIP;
return TinyGsmStringFromIp(savedIP);
}
}; };
/* /*
@ -487,7 +493,7 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
case XBEE_3G: return "Digi XBee Cellular 3G"; case XBEE_3G: return "Digi XBee Cellular 3G";
case XBEE3_LTE1_ATT: return "Digi XBee3 Cellular LTE CAT 1"; case XBEE3_LTE1_ATT: return "Digi XBee3 Cellular LTE CAT 1";
case XBEE3_LTEM_ATT: return "Digi XBee3 Cellular LTE-M"; case XBEE3_LTEM_ATT: return "Digi XBee3 Cellular LTE-M";
default: return "Digi XBee";
default: return "Digi XBee Unknown";
} }
} }
@ -503,13 +509,20 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
digitalWrite(resetPin, LOW); digitalWrite(resetPin, LOW);
delay(1); delay(1);
digitalWrite(resetPin, HIGH); digitalWrite(resetPin, HIGH);
} else {
DBG("pinReset - using software restart");
restartImpl();
} }
} }
bool restartImpl(const char* pin = NULL) { bool restartImpl(const char* pin = NULL) {
if (!commandMode()) { return false; } // Return immediately
if (!commandMode()) {
DBG("restartImpl not in commandMode. Exit");
return false;
} // Return immediately
if (beeType == XBEE_UNKNOWN) getSeries(); // how we restart depends on this if (beeType == XBEE_UNKNOWN) getSeries(); // how we restart depends on this
DBG("restartImpl",beeType );
if (beeType != XBEE_S6B_WIFI) { if (beeType != XBEE_S6B_WIFI) {
sendAT(GF("AM1")); // Digi suggests putting cellular modules into sendAT(GF("AM1")); // Digi suggests putting cellular modules into
@ -647,6 +660,7 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
break; break;
default: stat = REG_UNKNOWN; break; default: stat = REG_UNKNOWN; break;
} }
DBG("Digi WiFi regStatus",stat,",",intRes);
break; break;
} }
default: { // Cellular XBee's default: { // Cellular XBee's
@ -1123,16 +1137,26 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
// Put in TCP mode // Put in TCP mode
changesMade |= changeSettingIfNeeded(GF("IP"), 0x1); changesMade |= changeSettingIfNeeded(GF("IP"), 0x1);
} }
bool changesMadeCpy=changesMade;
changesMade |= changeSettingIfNeeded( changesMade |= changeSettingIfNeeded(
GF("DL"), String(host)); // Set the "Destination Address Low" GF("DL"), String(host)); // Set the "Destination Address Low"
changesMade |= changeSettingIfNeeded( changesMade |= changeSettingIfNeeded(
GF("DE"), String(port, HEX)); // Set the destination port GF("DE"), String(port, HEX)); // Set the destination port
if (beeType == XBEE_S6B_WIFI) {
DBG("modemConnect IP changes not saved");
changesMade = changesMadeCpy;
}
if (changesMade) { success &= writeChanges(); } if (changesMade) { success &= writeChanges(); }
} }
// we'll accept either unknown or connected // we'll accept either unknown or connected
if (XBEE_UNKNOWN == beeType ) {
getSeries();
DBG("BeeType modemConnect refresh",XBEE_S6B_WIFI,"=", beeType);
}
if (beeType != XBEE_S6B_WIFI) { if (beeType != XBEE_S6B_WIFI) {
uint16_t ci = getConnectionIndicator(); uint16_t ci = getConnectionIndicator();
success &= (ci == 0x00 || ci == 0xFF || ci == 0x28); success &= (ci == 0x00 || ci == 0xFF || ci == 0x28);
@ -1146,31 +1170,28 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
} }
bool modemStop(uint32_t maxWaitMs) { bool modemStop(uint32_t maxWaitMs) {
DBG("modemStop WaitMs=",maxWaitMs);
streamClear(); // Empty anything in the buffer streamClear(); // Empty anything in the buffer
// empty the saved currently-in-use destination address // empty the saved currently-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)
// Get the current socket timeout
sendAT(GF("TM"));
String timeoutUsed = readResponseString(5000L);
// For WiFi models, there's no direct way to close the socket. This is a
// This is a
// hack to shut the socket by setting the timeout to zero. // hack to shut the socket by setting the timeout to zero.
if (beeType == XBEE_S6B_WIFI) {
sendAT(GF("TM0")); // Set socket timeout to 0
// For WiFi use DigiXBeeWifi::disconnectInternet(void)
if (beeType != XBEE_S6B_WIFI) {
// Get the current socket timeout
sendAT(GF("TM"));
String timeoutUsed = readResponseString(5000L);
// For cellular models, per documentation: If you write the TM (socket
// timeout) value while in Transparent Mode, the current connection is
// immediately closed - this works even if the TM values is unchanged
sendAT(GF("TM"), timeoutUsed); // Re-set socket timeout
waitResponse(maxWaitMs); // This response can be slow waitResponse(maxWaitMs); // This response can be slow
writeChanges();
} }
// For cellular models, per documentation: If you write the TM (socket
// timeout) value while in Transparent Mode, the current connection is
// immediately closed - this works even if the TM values is unchanged
sendAT(GF("TM"), timeoutUsed); // Re-set socket timeout
waitResponse(maxWaitMs); // This response can be slow
writeChanges();
XBEE_COMMAND_END_DECORATOR XBEE_COMMAND_END_DECORATOR
return true; return true;
} }
@ -1386,9 +1407,9 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
data.replace(GSM_NL GSM_NL, GSM_NL); data.replace(GSM_NL GSM_NL, GSM_NL);
data.replace(GSM_NL, "\r\n "); data.replace(GSM_NL, "\r\n ");
if (data.length()) { if (data.length()) {
DBG("### Unhandled:", data, "\r\n");
DBG("### waitResponse ms=",timeout_ms," Unhandled:", data.c_str(), "\r\n");
} else { } else {
DBG("### NO RESPONSE FROM MODEM!\r\n");
DBG("### waitResponse ms=",timeout_ms," NO RESPONSE FROM MODEM!\r\n");
} }
} else { } else {
data.trim(); data.trim();
@ -1419,8 +1440,12 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
return true; return true;
uint8_t triesMade = 0; uint8_t triesMade = 0;
uint8_t triesUntilReset = 4; // only reset after 4 failures
uint8_t triesUntilReset = 4; // reset after number of tries
int8_t res ;
bool success = false; bool success = false;
if (beeType == XBEE_S6B_WIFI) {
triesUntilReset=9;
}
streamClear(); // Empty everything in the buffer before starting streamClear(); // Empty everything in the buffer before starting
while (!success && triesMade < retries) { while (!success && triesMade < retries) {
@ -1428,16 +1453,27 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
// Default guard time is 1s, but the init fxn decreases it to 100 ms // Default guard time is 1s, but the init fxn decreases it to 100 ms
delay(guardTime + 10); delay(guardTime + 10);
streamWrite(GF("+++")); // enter command mode streamWrite(GF("+++")); // enter command mode
int8_t res = waitResponse(guardTime * 2);
if (beeType != XBEE_S6B_WIFI) {
res = waitResponse(guardTime * 2);
} else {
//S6B used longer guard time, to allow to recover
res = waitResponse();
}
success = (1 == res); success = (1 == res);
if (0 == res) { if (0 == res) {
triesUntilReset--; triesUntilReset--;
if (triesUntilReset == 0) { if (triesUntilReset == 0) {
DBG("commandMode Module PinReset");
triesUntilReset = 4; triesUntilReset = 4;
pinReset(); // if it's unresponsive, reset pinReset(); // if it's unresponsive, reset
delay(250); // a short delay to allow it to come back up delay(250); // a short delay to allow it to come back up
// TODO(SRGDamia1) optimize this // TODO(SRGDamia1) optimize this
} }
if (beeType == XBEE_S6B_WIFI) {
delay(5000); // WiFi module frozen, wait longer
}
} }
triesMade++; triesMade++;
} }
@ -1473,8 +1509,17 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
void getSeries(void) { void getSeries(void) {
sendAT(GF("HS")); // Get the "Hardware Series"; sendAT(GF("HS")); // Get the "Hardware Series";
int16_t intRes = readResponseInt(); int16_t intRes = readResponseInt();
// if no response from module, then try again
if (0xff == intRes) {
sendAT(GF("HS")); // Get the "Hardware Series";
intRes = readResponseInt();
if (0xff == intRes) {
//Still no response, leave a known value - should reset
intRes = XBEE_UNKNOWN;
}
}
beeType = (XBeeType)intRes; beeType = (XBeeType)intRes;
DBG(GF("### Modem: "), getModemName());
DBG(GF("### Modem: "), getModemName(), beeType);
} }
String readResponseString(uint32_t timeout_ms = 1000) { String readResponseString(uint32_t timeout_ms = 1000) {
@ -1528,7 +1573,13 @@ class TinyGsmXBee : public TinyGsmModem<TinyGsmXBee>,
sendAT(cmd, newValue); sendAT(cmd, newValue);
// return false if we attempted to change but failed // return false if we attempted to change but failed
if (waitResponse(timeout_ms) != 1) { return false; } if (waitResponse(timeout_ms) != 1) { return false; }
// return true if we succeeded in staging a change
// check if we succeeded in staging a change
sendAT(cmd);
if (readResponseString() != newValue) {
sendAT(cmd, newValue);
if (waitResponse(timeout_ms) != 1) { return false; }
DBG("changeSettingIfNeeded try2",cmd,newValue);
}
return true; return true;
} }
// return false if no change is needed // return false if no change is needed


Loading…
Cancel
Save