Fixed pinReset and stop. Also notes on modemGetConnected
This commit is contained in:
@@ -87,24 +87,31 @@ public:
|
|||||||
virtual int connect(const char *host, uint16_t port) {
|
virtual int connect(const char *host, uint16_t port) {
|
||||||
at->streamClear(); // Empty anything in the buffer before starting
|
at->streamClear(); // Empty anything in the buffer before starting
|
||||||
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
||||||
sock_connected = at->modemConnect(host, port, mux, false);
|
at->modemConnect(host, port, mux, false);
|
||||||
at->writeChanges();
|
at->writeChanges();
|
||||||
at->exitCommand();
|
at->exitCommand();
|
||||||
}
|
}
|
||||||
// After setting connection information, check if we're actually connected
|
// After setting connection information, wait until we're at least not defintiely disconnected
|
||||||
|
uint32_t _startMillis = millis();
|
||||||
|
while (millis() - _startMillis < 10000 && !sock_connected) {
|
||||||
sock_connected = at->modemGetConnected();
|
sock_connected = at->modemGetConnected();
|
||||||
|
if (at->savedIP == IPAddress(0,0,0,0)) break; // if we never got an IP, give up
|
||||||
|
}
|
||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int connect(IPAddress ip, uint16_t port) {
|
virtual int connect(IPAddress ip, uint16_t port) {
|
||||||
at->streamClear(); // Empty anything in the buffer before starting
|
at->streamClear(); // Empty anything in the buffer before starting
|
||||||
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
||||||
sock_connected = at->modemConnect(ip, port, mux, false);
|
at->modemConnect(ip, port, mux, false);
|
||||||
at->writeChanges();
|
at->writeChanges();
|
||||||
at->exitCommand();
|
at->exitCommand();
|
||||||
}
|
}
|
||||||
// After setting connection information, check if we're actually connected
|
// After setting connection information, wait until we're at least not defintiely disconnected
|
||||||
|
uint32_t _startMillis = millis();
|
||||||
|
while (millis() - _startMillis < 10000 && !sock_connected) {
|
||||||
sock_connected = at->modemGetConnected();
|
sock_connected = at->modemGetConnected();
|
||||||
|
}
|
||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,20 +120,21 @@ public:
|
|||||||
virtual void stop() {
|
virtual void stop() {
|
||||||
at->streamClear(); // Empty anything in the buffer
|
at->streamClear(); // Empty anything in the buffer
|
||||||
at->commandMode();
|
at->commandMode();
|
||||||
at->sendAT(GF("TM0")); // Set socket timeout to 0;
|
// Per documentation: If you change the TM (socket timeout) value while in
|
||||||
// Per documentation: If you change the TM value while in Transparent Mode,
|
// Transparent Mode, the current connection is immediately closed.
|
||||||
// the current connection is immediately closed.
|
|
||||||
// NOTE: Above applies to all cellular models, uncertain if it applies
|
// NOTE: Above applies to all cellular models, uncertain if it applies
|
||||||
// to the WiFi models.
|
// to the WiFi models.
|
||||||
at->waitResponse();
|
at->sendAT(GF("TM64")); // Set socket timeout (using Digi default of 10 seconds)
|
||||||
at->writeChanges();
|
at->waitResponse(5000); // This response can be slow
|
||||||
at->sendAT(GF("TM64")); // Set socket timeout back to 10 seconds;
|
|
||||||
at->waitResponse();
|
|
||||||
at->writeChanges();
|
at->writeChanges();
|
||||||
at->exitCommand();
|
at->exitCommand();
|
||||||
at->streamClear(); // Empty anything remaining in the buffer
|
at->streamClear(); // Empty anything remaining in the buffer
|
||||||
// sock_connected = false;
|
sock_connected = false;
|
||||||
// Note: because settings are saved in flash, the XBEE may immediately attempt to reconnect
|
// Note: because settings are saved in flash, the XBEE will attempt to
|
||||||
|
// reconnect to the previous socket if it receives any outgoing data.
|
||||||
|
// Setting sock_connected to false after the stop ensures that connected()
|
||||||
|
// will return false after a stop has been ordered. This makes it play
|
||||||
|
// much more nicely with libraries like PubSubClient.
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t write(const uint8_t *buf, size_t size) {
|
virtual size_t write(const uint8_t *buf, size_t size) {
|
||||||
@@ -196,7 +204,12 @@ public:
|
|||||||
if (available()) {
|
if (available()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
sock_connected = at->modemGetConnected();
|
// Double check that we don't know it's closed
|
||||||
|
// NOTE: modemGetConnected() is likely to return a "false" true because
|
||||||
|
// it will return unknown until after data is sent over the connection.
|
||||||
|
// If the socket is definitely closed, modemGetConnected() will set
|
||||||
|
// sock_connected to false;
|
||||||
|
at->modemGetConnected();
|
||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
virtual operator bool() { return connected(); }
|
virtual operator bool() { return connected(); }
|
||||||
@@ -228,24 +241,31 @@ public:
|
|||||||
virtual int connect(const char *host, uint16_t port) {
|
virtual int connect(const char *host, uint16_t port) {
|
||||||
at->streamClear(); // Empty anything in the buffer before starting
|
at->streamClear(); // Empty anything in the buffer before starting
|
||||||
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
||||||
sock_connected = at->modemConnect(host, port, mux, true);
|
at->modemConnect(host, port, mux, true);
|
||||||
at->writeChanges();
|
at->writeChanges();
|
||||||
at->exitCommand();
|
at->exitCommand();
|
||||||
}
|
}
|
||||||
// After setting connection information, check if we're actually connected
|
// After setting connection information, wait until we're at least not defintiely disconnected
|
||||||
|
uint32_t _startMillis = millis();
|
||||||
|
while (millis() - _startMillis < 10000 && !sock_connected) {
|
||||||
sock_connected = at->modemGetConnected();
|
sock_connected = at->modemGetConnected();
|
||||||
|
if (at->savedIP == IPAddress(0,0,0,0)) break; // if we never got an IP, give up
|
||||||
|
}
|
||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int connect(IPAddress ip, uint16_t port) {
|
virtual int connect(IPAddress ip, uint16_t port) {
|
||||||
at->streamClear(); // Empty anything in the buffer before starting
|
at->streamClear(); // Empty anything in the buffer before starting
|
||||||
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
if (at->commandMode()) { // Don't try if we didn't successfully get into command mode
|
||||||
sock_connected = at->modemConnect(ip, port, mux, true);
|
at->modemConnect(ip, port, mux, false);
|
||||||
at->writeChanges();
|
at->writeChanges();
|
||||||
at->exitCommand();
|
at->exitCommand();
|
||||||
}
|
}
|
||||||
// After setting connection information, check if we're actually connected
|
// After setting connection information, wait until we're at least not defintiely disconnected
|
||||||
|
uint32_t _startMillis = millis();
|
||||||
|
while (millis() - _startMillis < 10000 && !sock_connected) {
|
||||||
sock_connected = at->modemGetConnected();
|
sock_connected = at->modemGetConnected();
|
||||||
|
}
|
||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -259,8 +279,8 @@ public:
|
|||||||
beeType = XBEE_UNKNOWN; // Start not knowing what kind of bee it is
|
beeType = XBEE_UNKNOWN; // Start not knowing what kind of bee it is
|
||||||
guardTime = TINY_GSM_XBEE_GUARD_TIME; // Start with the default guard time of 1 second
|
guardTime = TINY_GSM_XBEE_GUARD_TIME; // Start with the default guard time of 1 second
|
||||||
resetPin = -1;
|
resetPin = -1;
|
||||||
ipAddr = IPAddress(0,0,0,0);
|
savedIP = IPAddress(0,0,0,0);
|
||||||
host = "";
|
savedHost = "";
|
||||||
memset(sockets, 0, sizeof(sockets));
|
memset(sockets, 0, sizeof(sockets));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,8 +290,8 @@ public:
|
|||||||
beeType = XBEE_UNKNOWN; // Start not knowing what kind of bee it is
|
beeType = XBEE_UNKNOWN; // Start not knowing what kind of bee it is
|
||||||
guardTime = TINY_GSM_XBEE_GUARD_TIME; // Start with the default guard time of 1 second
|
guardTime = TINY_GSM_XBEE_GUARD_TIME; // Start with the default guard time of 1 second
|
||||||
this->resetPin = resetPin;
|
this->resetPin = resetPin;
|
||||||
ipAddr = IPAddress(0,0,0,0);
|
savedIP = IPAddress(0,0,0,0);
|
||||||
host = "";
|
savedHost = "";
|
||||||
memset(sockets, 0, sizeof(sockets));
|
memset(sockets, 0, sizeof(sockets));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,23 +804,23 @@ protected:
|
|||||||
bool modemConnect(const char* host, uint16_t port, uint8_t mux = 0, bool ssl = false) {
|
bool modemConnect(const char* host, uint16_t port, uint8_t mux = 0, bool ssl = false) {
|
||||||
// If requested host is the same as the previous one and we already
|
// If requested host is the same as the previous one and we already
|
||||||
// have a valid IP address, we don't have to do anything.
|
// have a valid IP address, we don't have to do anything.
|
||||||
if (this->host == String(host) && ipAddr != IPAddress(0,0,0,0)) {
|
if (this->savedHost == String(host) && savedIP != IPAddress(0,0,0,0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, set the new host and mark the IP as invalid
|
// Otherwise, set the new host and mark the IP as invalid
|
||||||
this->host = String(host);
|
this->savedHost = String(host);
|
||||||
ipAddr == getHostIP(host); // This will return 0.0.0.0 if lookup fails
|
savedIP = getHostIP(host); // This will return 0.0.0.0 if lookup fails
|
||||||
|
|
||||||
// If we now have a valid IP address, use it to connect
|
// If we now have a valid IP address, use it to connect
|
||||||
if (ipAddr != IPAddress(0,0,0,0)) { // Only re-set connection information if we have an IP address
|
if (savedIP != IPAddress(0,0,0,0)) { // Only re-set connection information if we have an IP address
|
||||||
return modemConnect(ipAddr, port, mux, ssl);
|
return modemConnect(savedIP, port, mux, ssl);
|
||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool ssl = false) {
|
bool modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool ssl = false) {
|
||||||
ipAddr = ip; // Set the newly requested IP address
|
savedIP = ip; // Set the newly requested IP address
|
||||||
bool success = true;
|
bool success = true;
|
||||||
String host; host.reserve(16);
|
String host; host.reserve(16);
|
||||||
host += ip[0];
|
host += ip[0];
|
||||||
@@ -830,12 +850,16 @@ protected:
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: The CI command returns the status of the TCP connection as open only
|
||||||
|
// after data has been sent on the socket. If it returns 0xFF the socket may
|
||||||
|
// really be open, but no data has yet been sent. We return this unknown value
|
||||||
|
// as true so there's a possibility it's wrong.
|
||||||
bool modemGetConnected() {
|
bool modemGetConnected() {
|
||||||
|
|
||||||
if (!commandMode()) return false; // Return immediately
|
if (!commandMode()) return false; // Return immediately
|
||||||
|
|
||||||
// If the IP address is 0, it's not valid so we can't be connected
|
// If the IP address is 0, it's not valid so we can't be connected
|
||||||
if (ipAddr == IPAddress(0,0,0,0)) return false;
|
if (savedIP == IPAddress(0,0,0,0)) return false;
|
||||||
|
|
||||||
// Verify that we're connected to the *right* IP address
|
// Verify that we're connected to the *right* IP address
|
||||||
// We might be connected - but to the wrong thing
|
// We might be connected - but to the wrong thing
|
||||||
@@ -843,7 +867,7 @@ protected:
|
|||||||
String strIP; strIP.reserve(16);
|
String strIP; strIP.reserve(16);
|
||||||
sendAT(GF("DL"));
|
sendAT(GF("DL"));
|
||||||
strIP = stream.readStringUntil('\r'); // read result
|
strIP = stream.readStringUntil('\r'); // read result
|
||||||
if (TinyGsmIpFromString(strIP) != ipAddr) return exitAndFail();
|
if (TinyGsmIpFromString(strIP) != savedIP) return exitAndFail();
|
||||||
|
|
||||||
if (beeType == XBEE_UNKNOWN) getSeries(); // Need to know the bee type to interpret response
|
if (beeType == XBEE_UNKNOWN) getSeries(); // Need to know the bee type to interpret response
|
||||||
|
|
||||||
@@ -859,10 +883,10 @@ protected:
|
|||||||
sendAT(GF("CI"));
|
sendAT(GF("CI"));
|
||||||
int16_t intRes = readResponseInt();
|
int16_t intRes = readResponseInt();
|
||||||
exitCommand();
|
exitCommand();
|
||||||
if (intRes != 0) {
|
if (intRes != 0 && intRes != 0xFF) { // If it's not one of these...
|
||||||
sockets[0]->sock_connected = false;
|
sockets[0]->sock_connected = false; // ...it's definitely NOT connected
|
||||||
}
|
}
|
||||||
return (0 == intRes);
|
return (0 == intRes || intRes == 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -966,6 +990,7 @@ finish:
|
|||||||
|
|
||||||
bool commandMode(uint8_t retries = 3) {
|
bool commandMode(uint8_t retries = 3) {
|
||||||
uint8_t triesMade = 0;
|
uint8_t triesMade = 0;
|
||||||
|
uint8_t triesUntilReset = 2; // only reset after 2 failures
|
||||||
bool success = false;
|
bool success = false;
|
||||||
streamClear(); // Empty everything in the buffer before starting
|
streamClear(); // Empty everything in the buffer before starting
|
||||||
while (!success and triesMade < retries) {
|
while (!success and triesMade < retries) {
|
||||||
@@ -975,9 +1000,13 @@ finish:
|
|||||||
streamWrite(GF("+++")); // enter command mode
|
streamWrite(GF("+++")); // enter command mode
|
||||||
int res = waitResponse(guardTime*2);
|
int res = waitResponse(guardTime*2);
|
||||||
success = (1 == res);
|
success = (1 == res);
|
||||||
if (0 == res && triesMade > 2) {
|
if (0 == res) {
|
||||||
|
triesUntilReset--;
|
||||||
|
if (triesUntilReset == 0) {
|
||||||
|
triesUntilReset = 2;
|
||||||
pinReset(); // if it's unresponsive, reset
|
pinReset(); // if it's unresponsive, reset
|
||||||
delay(100); // a short delay to allow it to come back up TODO-optimize this
|
delay(250); // a short delay to allow it to come back up TODO-optimize this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
triesMade ++;
|
triesMade ++;
|
||||||
}
|
}
|
||||||
@@ -1033,8 +1062,8 @@ protected:
|
|||||||
int16_t guardTime;
|
int16_t guardTime;
|
||||||
int8_t resetPin;
|
int8_t resetPin;
|
||||||
XBeeType beeType;
|
XBeeType beeType;
|
||||||
IPAddress ipAddr;
|
IPAddress savedIP;
|
||||||
String host;
|
String savedHost;
|
||||||
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user