mirror of
				https://github.com/KevinMidboe/TinyGSM.git
				synced 2025-10-29 18:00:18 +00:00 
			
		
		
		
	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