vshymanskyy / TinyGSM

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

failure to open TCP socket when using SSL with SARA-410M #675

Open gasagna opened 1 year ago

gasagna commented 1 year ago

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

What type of issues is this?

[ ] Request to support a new module

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

What are you working with?

Modem: SARA-R410M-02B-00 Main processor board: MKR NB 1500 TinyGSM version: 0.11.3 Code: Here is the relevant code I am using. Read below for further info on the background

// enable http logging
#define LOGGING

// dump commands to serial port
#define DUMP_AT_COMMANDS true

// define sim module
#define TINY_GSM_MODEM_SARAR4

// Your GPRS credentials, if any
const char apn[]      = "em";
const char gprsUser[] = "";
const char gprsPass[] = "";

// import libraries
#include <ArduinoHttpClient.h>
#include <ArduinoLowPower.h>
#include <StreamDebugger.h>
#include <TinyGsmClient.h>
#include <MKRNB.h>

// influxdb parameters
#define INFLUXDB_TOKEN "Token ** YOU WILL NEED YOUR OWN TOKEN **"
#define INFLUXDB_ADDR  "europe-west1-1.gcp.cloud2.influxdata.com"
#define INFLUXDB_PORT 443
#define INFLUXDB_BUCKET "your-own-bucket"
#define INFLUXDB_ORG "your-own-org"

// send message to the cloud
int sendSample(const String& message, HttpClient& httpclient) {
    // create request string
    String request = "/api/v2/write?bucket=";
    request += INFLUXDB_BUCKET;
    request += "&org=" ;
    request += INFLUXDB_ORG ;
    request += "&precision=s";

    // send request
    httpclient.beginRequest();
    int httpCode = httpclient.post(request);
    httpclient.sendHeader("Authorization", INFLUXDB_TOKEN);
    httpclient.sendHeader("Content-Type", "text/plain; charset=utf-8");
    httpclient.sendHeader("Content-Length", message.length());
    httpclient.sendHeader("Accept", "application/json");
    httpclient.beginBody();
    httpclient.print(message);
    httpclient.endRequest();

    // read status code
    return httpclient.responseStatusCode();
}

/****************************************************/
/*    Global variables                              */
/****************************************************/

// tools to attach to the cellular network
#if DUMP_AT_COMMANDS
    StreamDebugger debugger(Serial2, Serial);
    TinyGsm        modem(debugger);
#else
    TinyGsm        modem(Serial2);
#endif

// gsm client
TinyGsmClientSecure client(modem);

// initialize the clients
HttpClient httpclient = HttpClient(client, INFLUXDB_ADDR, INFLUXDB_PORT);

// example data to be sent
String line = "test message";

/****************************************************/
/*    Main functions                                */
/****************************************************/
// setup function
void setup() {
    // initialize serial communications for monitoring via usb
    Serial.begin(115200);
    while (!Serial) {}

    // initialise connection with module SARA
    Serial2.begin(115200);
    while (!Serial2) {}

    Serial.print("Connecting to cellular network ... ");
    modem.restart();
    Serial.println("done");
    String modemInfo = modem.getModemInfo();
    Serial.print("Modem Info: ");
    Serial.println(modemInfo);
}

// loop function
void loop() {
    // begin loop
    Serial.println();

    Serial.print("Waiting for network ...");
    if (!modem.waitForNetwork()) {
        Serial.println(" fail");
        delay(10000);
        return;
    }
    Serial.println(" success");

    if (modem.isNetworkConnected()) { Serial.println("Network connected"); }

    // GPRS connection parameters are usually set after network registration
    Serial.print(F("Connecting to "));
    Serial.print(apn);
    Serial.print(" ... ");
    if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
        Serial.println(" fail");
        delay(10000);
        return;
    }
    Serial.println(" success");

    if (modem.isGprsConnected()) { Serial.println("GPRS connected"); }

    // Currently, this is needed for HTTPS (see TinyGSM lib examples)
    httpclient.connectionKeepAlive();  

    // send message
    Serial.println("Starting request ...");
    int httpResponseCode = sendSample(line, httpclient);

    // if all good
    if (httpCode == HTTP_SUCCESS) {
        Serial.println(" Sending POST request");
        if (httpResponseCode == 204) {
            Serial.println("  Sample sent correctly, got 204");
        } else {
            Serial.print("  Sample not sent, got  ");
            Serial.println(httpResponseCode); 
            Serial.print(" ");
            Serial.print(httpResponse);
        }
    } else { 
        Serial.print(" Post request not sent, got ");
        Serial.println(httpCode);
    }

    // disconnect
    modem.gprsDisconnect();
    Serial.println(F("GPRS disconnected"));

    // wait till next time
    LowPower.sleep(SAMPLING_TIME);
}

Scenario, steps to reproduce (with AT command log)

I am using the TinyGSM and ArduinoHTTPClient libraries to post data to my InfluxDB cloud account via SSL. The server is managed by google cloud and is located at "europe-west1-1.gcp.cloud2.influxdata.com", as described in the official InfluxDB docs. As can be seen from the code above, I am trying to open a secure connection at port 443. This does not seem to work, and here is the relevant excerpt from the AT command dump.

20:31:18.363 -> AT+USOCR=6
20:31:18.363 -> 
20:31:18.363 -> +USOCR: 0
20:31:18.363 -> 
20:31:18.363 -> OK
20:31:18.363 -> AT+USOSEC=0,1
20:31:18.396 -> 
20:31:18.396 -> OK
20:31:18.396 -> AT+USOCO=0,"europe-west1-1.gcp.cloud2.influxdata.com",443,1
20:31:18.396 -> 
20:31:18.396 -> OK
20:31:20.783 -> 
20:31:20.783 -> +UUSOCO: 0,255

The return code from the AT+USOCO command is +UUSOCO: 0,255. From the modem's docs this return code is not documented, so I am at a loss here, and can't proceed.

I have tried posting data on an private InfluxDB instance managed on my own server that does not use SSL (using a TinyGsmClient object), and I can successfully post data.

gasagna commented 1 year ago

This does not appear to be an issue with the InfluxDB website or my own code, but rather a general issue with some https websites and my gsm modem. I have also tried the HttpsClient example provided by this library, using other websites (e.g. discourse.julialang.org), and the same +UUSOCO: 0,255 code is returned.