arduino-libraries / MKRGSM

GNU Lesser General Public License v2.1
54 stars 51 forks source link

Bug in GsmSSLWebClient - proposed fix, though not elegant #147

Open johnedstone opened 2 years ago

johnedstone commented 2 years ago

There are two bugs in the GsmSSLWebClient sketch First: If one uploads this sketch, it never finishes, never gets to lines 91 and 92:

    Serial.println();
    Serial.println("disconnecting.");

Second: If one uses a different server than arduino.cc, e.g google.com, the sketch ends at lines 76-77:

    // if you didn't get a connection to the server:
    Serial.println("connection failed");

The following sketch, Working sketch, which is a modification of the original sketch, fixes both of these bugs, though not in an elegant way. Is this a bug that you can fix? Thank you and thanks for this library. This library has been very helpful and compared to some others is awesome Note: Using a Hologram SIM.

Working sketch

/*
  Web client

 This sketch connects to a website using SSL through a MKR GSM 1400 board. Specifically,
 this example downloads the URL "http://www.arduino.cc/asciilogo.txt" and
 prints it to the Serial monitor.

 Circuit:
 * MKR GSM 1400 board
 * Antenna
 * SIM card with a data plan

 created 8 Mar 2012
 by Tom Igoe

 Modified by johnedstone@gmail.com, 26-Dec-2021
 See: https://github.com/johnedstone/mkrgsm1400-post-json-ssl
 Two changes:
    * See SSL hack below
    * Update the file libraries/MKRGSM/src/GSMClient.cpp
      comment out line 125, add line 126
      code:
      #file: libraries/MKRGSM/src/GSMClient.cpp
124     case CLIENT_STATE_MANAGE_SSL_PROFILE: {
125       // MODEM.sendf("AT+USECPRF=0,0,%d",_sslprofile);
126       MODEM.sendf("AT+USECPRF=0");

*/

// libraries
#include <MKRGSM.h>

#include "arduino_secrets.h" 
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = SECRET_PINNUMBER;
// APN data
const char GPRS_APN[]      = SECRET_GPRS_APN;
const char GPRS_LOGIN[]    = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;

// initialize the library instance
GSMSSLClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path and port (for example: arduino.cc)
char server[] = "google.com";
char path[] = "/";
int port = 443; // port 443 is the default for HTTPS

void setup() {
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Starting Arduino web client.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // SSL hack: if there is just one byte left, force a stop
  // For SSL client.connected() will not go to false - bug?
  // "A client is considered connected if the connection
  // has been closed but there is still unread data"
  static bool force_client_stop = false;
  if (client.available() == 1 && client.connected()) {
    force_client_stop = true;
  }
  if (force_client_stop && client.available() == 0) {
    client.stop();
  }

  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    for (;;)
      ;
  }
}