vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.93k stars 715 forks source link

TinyGSMClient - second web request fails during connection state #519

Open SunboX opened 3 years ago

SunboX commented 3 years ago

[ x] I have read the Troubleshooting section of the ReadMe

What type of issues is this?

[ x] Bug or issue with library functionality (ie, sending data over TCP/IP) [ x] Question or request for help

What are you working with?

Modem: A6 Main processor board: ESP32 TinyGSM version: latest

Baud rate is set to 9600 already (fixed) and 2ms yield is also defined! External stable power source (5V / 2A) is connected.

Code:

 if (!_client.connected()) {
    Serial.print("Connecting to ");
    Serial.print(host);
    Serial.print(":");
    Serial.println(port);
    if (!_client.connect(host, port))
    {
      Serial.println(" fail");
      delay(10000);
      return false;
    }
    Serial.println(" success");
  } else {
    Serial.println("Still connected.");
  }

  // Make a HTTP GET request:    
  Serial.println("Performing HTTP GET request...");

  client.print("GET / HTTP/1.1\r\n");
  client.print("Host: " + String(host) + "\r\n");
  client.print("User-Agent: NtripClient v1.0\r\n");
  client.print("Connection: close\r\n\r\n");

  // Wait for data to arrive    
  uint32t timeout = millis();
  while (client.connected() && !_client.available() && millis() - timeout < 30000 L) {
    delay(100);
  }

  String buffer;
  timeout = millis();
  while (client.connected() && millis() - timeout < 10000 L) {

    // Print available data       
    while (client.available()) {
      char c = _client.read();
      buffer += c;

      if (buffer.indexOf(F("SOURCETABLE 200 OK")) >= 0) {
        _client.stop();
        return true;
      }
      timeout = millis();
    }
  }
  _client.stop();
  Serial.println("Sourcetable not found! Buffer contains: ");
  Serial.println(buffer);
  return false;

Scenario, steps to reproduce

try to execute the code twice

Expected result

both requests work

Actual result

second code execute fails (see logs below)

Debug and AT command log

First connection:

Connecting to www.ntrip.sachsen.de:2101

AT+CIPCLOSE=255

+CME ERROR:parameters are invalid

AT+CIPSTART="TCP","www.ntrip.sachsen.de",2101

+CIPNUM:0

CONNECT OK

OK

Second connection:

Connecting to www.ntrip.sachsen.de:2101

AT+CIPCLOSE=0

+CME ERROR:Excute command failure

AT+CIPSTART="TCP","www.ntrip.sachsen.de",2101

����������

+CME ERROR:Excute command failure
SunboX commented 3 years ago

I tried the same code using a TTGO T-Call 1.4 and it works perfectly. Seems only to be related to the A6 Modem.

SRGDamia1 commented 3 years ago

I don't have an A6, so I'm guessing here.

It might be incorrectly reporting the socket state (ie, it's already closed) meaning that the close command fails. The module might just not recover well after the first command fails, leading to the second failure. In order to allow all characters to be read, the TinyGSM will report the socket as connected as long as there's anything available on the socket (even if the socket has been closed externally). Since your function short-cuts out as soon as it finds the table it's looking for, it's probably leaving stuff in the buffer. The stop function you're calling when you exit your loop should dump everything out of the buffer for you, but since the A6 is a slow talker, it might still be reporting out the message after it's been told to stop. Try re-writing your function to continue reading until there's nothing available and only then returning with the table in question.

amenoni commented 4 months ago

I'm Having a similar problem using:

Modem: SIM7000G Main processor board: ESP32 TinyGSM version: 0.11.7

I'm using this function:

 bool acknowledgeOrder(String token, String stat, String message){
 bool res=false;

    if (connectModem(false)) {
      ConsoleLog("Acknowledging order with status: " + stat); 

      String postData = "{\"status\":\""+ stat + "\", \"message\":\""+ message + "\"}";
      http.beginRequest();
      http.post(api_endpoint + "/sensur_order/" + token + "/");
      http.sendHeader("Content-Type", "application/json");
      http.sendHeader("Content-Length", postData.length());
      http.beginBody();
      http.print(postData);
      http.endRequest();  

      // read the status code and body of the response
      int statusCode = http.responseStatusCode();
      String response = http.responseBody();

      if (statusCode == 200){
        ConsoleLog("Acknowledge sent");
        res= true;
      }else{
        delay(500);
        ConsoleLog("Connect failed: " + String(statusCode));
        ConsoleLog("Response: " +  response);
      }

      while (http.available()){
        http.read(); //clean the buffer
      }

      http.flush();
      http.stop();
    }
    else {
      ConsoleLog("acknowledgeOrder: Modem connect fail");
    }
    return res;
 }

The first time I call it it works perfectly but the second time the connection fails giving me -3 response status code