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

Client sent an HTTP request to an HTTPS server Issue #538

Closed mlrochaa23 closed 3 years ago

mlrochaa23 commented 3 years ago

I'm working on a project to send data to Elasticsearch.

I was already able to send the data via wifi. When I try to do the same via GSM, I'm receiving " Client sent an HTTP request to an HTTPS server" message.

Below is part of the code:

TinyGsmClient client(modem);

client.print(String("POST ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: esp8266temp\r\n" + "WWW-Authenticate: Basic realm=\"security\"\r\n" + "Authorization: Basic " + userpass + "\r\n" + "Connection: close\r\n" + "Content-Type: application/json\r\n" + "Content-Length: " + doc.length() + "\r\n\r\n" + doc + "\r\n");

// Serial.println("request sent"); while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { SerialMon.println("headers received"); break; } } String line = client.readStringUntil('\n'); SerialMon.println("reply was:"); SerialMon.println(line); delay(refresh_seconds * 10); } else { delay(10); }

Any tip to solve this issue?

SRGDamia1 commented 3 years ago

You need to use TinyGsmClientSecure secureClient(modem); not TinyGsmClient client(modem); SSL isn't supported for all of the modules; check the ReadMe.

mlrochaa23 commented 3 years ago

I tried that, but I had not success. When I use TinyGSMCLientSecure, I can't connect to elasticsearch server. I'm using the SIM800l module.

SRGDamia1 commented 3 years ago

I'm sorry, I can't say any more without more detail (ie, an AT log) on what's failing.

If you search through, there are probably dozen's of issues here related to SSL on the SIM800. Whether it works or not depends on your specific module version, firmware revision, SIM provider, the current pollution level in New York City, and maybe the weather in San Francisco.

mlrochaa23 commented 3 years ago

The module is on firmware 14.18. I tried to run the simple example HTTPSClient to test the SSL but I had not success too. The module is able to connect to SIM provider, but when the module try to run the GET request, I'm receving "failed to connect" message.

SRGDamia1 commented 3 years ago

Your module probably just doesn't support SSL. Search through the issues; others have had success using a standard (not-secured) TCP connection on the SIM800 with a secondary SSL library supplying the security layer.

mlrochaa23 commented 3 years ago

I will investigate that. Thank you for your support.

woodlist commented 3 years ago

I tried that, but I had not success. When I use TinyGSMCLientSecure, I can't connect to elasticsearch server. I'm using the SIM800l module.

Try to use https://github.com/OPEnSLab-OSU/SSLClient You can eliminate the usage of TinyGSMCLientSecure

ashwanisihag commented 3 years ago

It supports SSL

Here is full code

/* @file TinyGsmClientSIM7600.h @author Volodymyr Shymanskyy @license LGPL-3.0 @copyright Copyright (c) 2016 Volodymyr Shymanskyy @date Nov 2016 /

ifndef SRC_TINYGSMCLIENTSIM7600H

define SRC_TINYGSMCLIENTSIM7600H

// #define TINY_GSM_DEBUG Serial // #define TINY_GSM_USE_HEX

define TINY_GSM_MUX_COUNT 10

define TINY_GSM_BUFFER_READ_AND_CHECK_SIZE

include "TinyGsmBattery.tpp"

include "TinyGsmGPRS.tpp"

include "TinyGsmGPS.tpp"

include "TinyGsmGSMLocation.tpp"

include "TinyGsmModem.tpp"

include "TinyGsmSMS.tpp"

include "TinyGsmTCP.tpp"

include "TinyGsmTemperature.tpp"

include "TinyGsmTime.tpp"

define GSM_NL "\r\n"

static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL; static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;

if defined TINY_GSM_DEBUG

static const char GSM_CME_ERROR[] TINY_GSM_PROGMEM = GSM_NL "+CME ERROR:"; static const char GSM_CMS_ERROR[] TINY_GSM_PROGMEM = GSM_NL "+CMS ERROR:";

endif

enum RegStatus { REG_NO_RESULT = -1, REG_UNREGISTERED = 0, REG_SEARCHING = 2, REG_DENIED = 3, REG_OK_HOME = 1, REG_OK_ROAMING = 5, REG_UNKNOWN = 4, };

class TinyGsmSim7600 : public TinyGsmModem, public TinyGsmGPRS, public TinyGsmTCP<TinyGsmSim7600, TINY_GSM_MUX_COUNT>, public TinyGsmSMS, public TinyGsmGSMLocation, public TinyGsmGPS, public TinyGsmTime, public TinyGsmBattery, public TinyGsmTemperature { friend class TinyGsmModem; friend class TinyGsmGPRS; friend class TinyGsmTCP<TinyGsmSim7600, TINY_GSM_MUX_COUNT>; friend class TinyGsmSMS; friend class TinyGsmGPS; friend class TinyGsmGSMLocation; friend class TinyGsmTime; friend class TinyGsmBattery; friend class TinyGsmTemperature;

/*
   Inner Client
*/

public: class GsmClientSim7600 : public GsmClient { friend class TinyGsmSim7600;

  public:
    GsmClientSim7600() {}

    explicit GsmClientSim7600(TinyGsmSim7600& modem, uint8_t mux = 0) {
      init(&modem, mux);
    }

    bool init(TinyGsmSim7600* modem, uint8_t mux = 0) {
      this->at       = modem;
      sock_available = 0;
      prev_check     = 0;
      sock_connected = false;
      got_data       = false;

      if (mux < TINY_GSM_MUX_COUNT) {
        this->mux = mux;
      } else {
        this->mux = (mux % TINY_GSM_MUX_COUNT);
      }
      at->sockets[this->mux] = this;

      return true;
    }

  public:
    virtual int connect(const char* host, uint16_t port, int timeout_s) {
      DBG("connect called");
      stop();
      TINY_GSM_YIELD();
      rx.clear();
      sock_connected = at->modemConnect(host, port, mux, false, timeout_s);
      return sock_connected;
    }
    TINY_GSM_CLIENT_CONNECT_OVERRIDES

    void stop(uint32_t maxWaitMs) {
        DBG("stop called");
      dumpModemBuffer(maxWaitMs);
      // at->sendAT(GF("+CIPCLOSE="), mux);
      at->sendAT(GF("+CCHCLOSE=0"));//todo
      // at->sendAT(GF("+CCHSTOP=0"));//todo
      sock_connected = false;
      DBG("stop waitResponse called");
      at->waitResponse();
    }
    void stop() override {
      stop(15000L);
    }

    /*
       Extended API
    */

    String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
};

public: explicit TinyGsmSim7600(Stream& stream) : stream(stream) { memset(sockets, 0, sizeof(sockets)); }

/*
   Basic functions
*/

protected: bool initImpl(const char* pin = NULL) { DBG(GF("### TinyGSM Version:"), TINYGSM_VERSION); DBG(GF("### TinyGSM Compiled Module: TinyGsmClientSIM7600"));

  if (!testAT()) {
    return false;
  }

  sendAT(GF("E0"));  // Echo Off
  if (waitResponse() != 1) {
    return false;
  }

ifdef TINY_GSM_DEBUG

  sendAT(GF("+CMEE=2"));  // turn on verbose error codes

else

  sendAT(GF("+CMEE=0"));  // turn off error codes

endif

  waitResponse();

  DBG(GF("### Modem:"), getModemName());

  // Disable time and time zone URC's
  sendAT(GF("+CTZR=0"));
  if (waitResponse(10000L) != 1) {
    return false;
  }

  // Enable automatic time zome update
  sendAT(GF("+CTZU=1"));
  if (waitResponse(10000L) != 1) {
    return false;
  }

  SimStatus ret = getSimStatus();
  // if the sim isn't ready and a pin has been provided, try to unlock the sim
  if (ret != SIM_READY && pin != NULL && strlen(pin) > 0) {
    simUnlock(pin);
    return (getSimStatus() == SIM_READY);
  } else {
    // if the sim is ready, or it's locked but no pin has been provided,
    // return true
    return (ret == SIM_READY || ret == SIM_LOCKED);
  }
}

String getModemNameImpl() {
  String name = "SIMCom SIM7600";

  sendAT(GF("+CGMM"));
  String res2;
  if (waitResponse(1000L, res2) != 1) {
    return name;
  }
  res2.replace(GSM_NL "OK" GSM_NL, "");
  res2.replace("_", " ");
  res2.trim();

  name = res2;
  DBG("### Modem:", name);
  return name;
}

bool factoryDefaultImpl() {  // these commands aren't supported
  return false;
}

/*
   Power functions
*/

protected: bool restartImpl(const char* pin = NULL) { if (!testAT()) { return false; } sendAT(GF("+CRESET")); if (waitResponse(10000L) != 1) { return false; } delay(5000L); // TODO(?): Test this delay! return init(pin); }

bool powerOffImpl() {
  sendAT(GF("+CPOF"));
  return waitResponse() == 1;
}

bool radioOffImpl() {
  if (!setPhoneFunctionality(4)) {
    return false;
  }
  delay(5000L);
  return true;
}

bool sleepEnableImpl(bool enable = true) {
  sendAT(GF("+CSCLK="), enable);
  return waitResponse() == 1;
}

bool setPhoneFunctionalityImpl(uint8_t fun, bool reset = false) {
  sendAT(GF("+CFUN="), fun, reset ? ",1" : "");
  return waitResponse(10000L) == 1;
}

/*
   Generic network functions
*/

public: RegStatus getRegistrationStatus() { return (RegStatus)getRegistrationStatusXREG("CGREG"); }

protected: bool isNetworkConnectedImpl() { RegStatus s = getRegistrationStatus(); return (s == REG_OK_HOME || s == REG_OK_ROAMING); }

public: String getNetworkModes() { sendAT(GF("+CNMP=?")); if (waitResponse(GF(GSM_NL "+CNMP:")) != 1) { return ""; } String res = stream.readStringUntil('\n'); waitResponse(); return res; }

String setNetworkMode(uint8_t mode) {
  sendAT(GF("+CNMP="), mode);
  if (waitResponse(GF(GSM_NL "+CNMP:")) != 1) {
    return "OK";
  }
  String res = stream.readStringUntil('\n');
  waitResponse();
  return res;
}

String getLocalIPImpl() {
  sendAT(GF("+IPADDR"));  // Inquire Socket PDP address
  // sendAT(GF("+CGPADDR=1"));  // Show PDP address
  String res;
  if (waitResponse(10000L, res) != 1) {
    return "";
  }
  res.replace(GSM_NL "OK" GSM_NL, "");
  res.replace(GSM_NL, "");
  res.trim();
  return res;
}

/*
   GPRS functions
*/

protected: bool gprsConnectImpl(const char apn, const char user = NULL, const char* pwd = NULL) { gprsDisconnect(); // Make sure we're not connected first

  sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
  waitResponse();

  sendAT(GF("+CGPADDR"));
  waitResponse();

  sendAT(GF("+CIPMODE=0"));
  waitResponse();

  sendAT(GF("+CIPSENDMODE=0"));
  waitResponse();

  sendAT(GF("+CIPCCFG=10,0,0,0,1,0,30000"));
  waitResponse();

  sendAT(GF("+CIPTIMEOUT="), 30000, ',', 30000, ',', 30000);
  waitResponse();

  sendAT(GF("+NETOPEN"));
  if (waitResponse(75000L,GF(GSM_NL "+NETOPEN: 0")) != 1)
  {
      DBG("+NETOPEN: 0 not found");
    sendAT(GF("+NETOPEN"));
    if (waitResponse(75000L,GF("+IP ERROR: Network is already opened")) != 1)
    {
          DBG("+IP ERROR: Network is already opened not found");
      sendAT(GF(GSM_NL "+NETOPEN"));
      if (waitResponse(75000L,GF("+IP ERROR: 4")) == 1)
      {
          DBG("+IP ERROR: 4 not found");
        DBG("NET DEACTIVATED");
        return false;
      }
    }
  }
  DBG("NET ACTIVATED");
  delay(1000);

  /*sendAT(GF("+IPADDR"));  // Inquire Socket PDP address
     if (waitResponse(120000L,GF(GSM_NL "+IP ERROR:")) == 1) {
    DBG("IPADDRESS NOT FOUND");
    return false;
    }
    DBG("IPADDRESS FOUND"); */
  return true;
}

bool isGprsConnectedImpl() {
  //AT+NETOPEN?
  sendAT(GF("+NETOPEN?"));

  if (waitResponse((GSM_NL "+NETOPEN: 1")) != 1) {
    DBG("CHECK NET FAIL");
    return false;
  }
  DBG("CHECK NET SUCCESS");
  return true;
}

bool gprsDisconnectImpl() {

  sendAT(GF("+NETCLOSE"));
  if (waitResponse(GF(GSM_NL "+NETCLOSE: 0")) != 1) {
    DBG("GPRS CLOSED");
    return false;
  }
  DBG("GPRS OPENED");
  return true;
}

/*
   SIM card functions
*/

protected: // Gets the CCID of a sim card via AT+CCID String getSimCCIDImpl() { sendAT(GF("+CICCID")); if (waitResponse(GF(GSM_NL "+ICCID:")) != 1) { return ""; } String res = stream.readStringUntil('\n'); waitResponse(); res.trim(); return res; }

/*
   Phone Call functions
*/

protected: bool callAnswerImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; bool callNumberImpl(const String& number) TINY_GSM_ATTR_NOT_IMPLEMENTED; bool callHangupImpl() TINY_GSM_ATTR_NOT_IMPLEMENTED; bool dtmfSendImpl(char cmd, int duration_ms = 100) TINY_GSM_ATTR_NOT_IMPLEMENTED;

/*
   Messaging functions
*/

protected: // Follows all messaging functions per template

/*
   GSM Location functions
*/

protected: // Can return a GSM-based location from CLBS as per the template

/*
   GPS/GNSS/GLONASS location functions
*/

protected: // enable GPS bool enableGPSImpl() { sendAT(GF("+CGPS=1")); if (waitResponse() != 1) { return false; } return true; }

bool disableGPSImpl() {
  sendAT(GF("+CGPS=0"));
  if (waitResponse() != 1) {
    return false;
  }
  return true;
}

// get the RAW GPS output
String getGPSrawImpl() {
  sendAT(GF("+CGNSSINFO"));
  if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) {
    return "";
  }
  String res = stream.readStringUntil('\n');
  waitResponse();
  res.trim();
  return res;
}

// get GPS informations
bool getGPSImpl(float* lat, float* lon, float* speed = 0, float* alt = 0,
                int* vsat = 0, int* usat = 0, float* accuracy = 0,
                int* year = 0, int* month = 0, int* day = 0, int* hour = 0,
                int* minute = 0, int* second = 0) {
  sendAT(GF("+CGNSSINFO"));
  if (waitResponse(GF(GSM_NL "+CGNSSINFO:")) != 1) {
    return false;
  }

  uint8_t fixMode = streamGetIntBefore(',');  // mode 2=2D Fix or 3=3DFix
  // TODO(?) Can 1 be returned
  if (fixMode == 1 || fixMode == 2 || fixMode == 3) {
    // init variables
    float ilat = 0;
    char  north;
    float ilon = 0;
    char  east;
    float ispeed       = 0;
    float ialt         = 0;
    int   ivsat        = 0;
    int   iusat        = 0;
    float iaccuracy    = 0;
    int   iyear        = 0;
    int   imonth       = 0;
    int   iday         = 0;
    int   ihour        = 0;
    int   imin         = 0;
    float secondWithSS = 0;

    streamSkipUntil(',');               // GPS satellite valid numbers
    streamSkipUntil(',');               // GLONASS satellite valid numbers
    streamSkipUntil(',');               // BEIDOU satellite valid numbers
    ilat  = streamGetFloatBefore(',');  // Latitude in ddmm.mmmmmm
    north = stream.read();              // N/S Indicator, N=north or S=south
    streamSkipUntil(',');
    ilon = streamGetFloatBefore(',');  // Longitude in ddmm.mmmmmm
    east = stream.read();              // E/W Indicator, E=east or W=west
    streamSkipUntil(',');

    // Date. Output format is ddmmyy
    iday   = streamGetIntLength(2);    // Two digit day
    imonth = streamGetIntLength(2);    // Two digit month
    iyear  = streamGetIntBefore(',');  // Two digit year

    // UTC Time. Output format is hhmmss.s
    ihour = streamGetIntLength(2);  // Two digit hour
    imin  = streamGetIntLength(2);  // Two digit minute
    secondWithSS =
      streamGetFloatBefore(',');  // 4 digit second with subseconds

    ialt   = streamGetFloatBefore(',');  // MSL Altitude. Unit is meters
    ispeed = streamGetFloatBefore(',');  // Speed Over Ground. Unit is knots.
    streamSkipUntil(',');                // Course Over Ground. Degrees.
    streamSkipUntil(',');  // After set, will report GPS every x seconds
    iaccuracy = streamGetFloatBefore(',');  // Position Dilution Of Precision
    streamSkipUntil(',');   // Horizontal Dilution Of Precision
    streamSkipUntil(',');   // Vertical Dilution Of Precision
    streamSkipUntil('\n');  // TODO(?) is one more field reported??

    // Set pointers
    if (lat != NULL)
      *lat = (floor(ilat / 100) + fmod(ilat, 100.) / 60) *
             (north == 'N' ? 1 : -1);
    if (lon != NULL)
      *lon = (floor(ilon / 100) + fmod(ilon, 100.) / 60) *
             (east == 'E' ? 1 : -1);
    if (speed != NULL) *speed = ispeed;
    if (alt != NULL) *alt = ialt;
    if (vsat != NULL) *vsat = ivsat;
    if (usat != NULL) *usat = iusat;
    if (accuracy != NULL) *accuracy = iaccuracy;
    if (iyear < 2000) iyear += 2000;
    if (year != NULL) *year = iyear;
    if (month != NULL) *month = imonth;
    if (day != NULL) *day = iday;
    if (hour != NULL) *hour = ihour;
    if (minute != NULL) *minute = imin;
    if (second != NULL) *second = static_cast<int>(secondWithSS);

DBG("getGPSImpl waitResponse called true"); waitResponse(); return true; } DBG("getGPSImpl waitResponse called false"); waitResponse(); return false; }

/**
    CGNSSMODE: <gnss_mode>,<dpo_mode>
    This command is used to configure GPS, GLONASS, BEIDOU and QZSS support
   mode. 0 : GLONASS 1 : BEIDOU 2 : GALILEO 3 : QZSS dpo_mode: 1 enable , 0
   disable
*/
String setGNSSModeImpl(uint8_t mode, bool dpo) {
  String res;
  sendAT(GF("+CGNSSMODE="), mode, ",", dpo);
  if (waitResponse(10000L, res) != 1) {
    return "";
  }
  res.replace(GSM_NL, "");
  res.trim();
  return res;
}

uint8_t getGNSSModeImpl() {
  sendAT(GF("+CGNSSMODE?"));
  if (waitResponse(GF(GSM_NL "+CGNSSMODE:")) != 1) {
    return 0;
  }
  return stream.readStringUntil(',').toInt();
}

/*
   Time functions
*/

protected: // Can follow the standard CCLK function in the template

/*
   Battery functions
*/

protected: // returns volts, multiply by 1000 to get mV uint16_t getBattVoltageImpl() { sendAT(GF("+CBC")); if (waitResponse(GF(GSM_NL "+CBC:")) != 1) { return 0; }

  // get voltage in VOLTS
  float voltage = streamGetFloatBefore('\n');
  // Wait for final OK
  waitResponse();
  // Return millivolts
  uint16_t res = voltage * 1000;
  return res;
}

int8_t getBattPercentImpl() TINY_GSM_ATTR_NOT_AVAILABLE;

uint8_t getBattChargeStateImpl() TINY_GSM_ATTR_NOT_AVAILABLE;

bool getBattStatsImpl(uint8_t& chargeState, int8_t& percent,
                      uint16_t& milliVolts) {
  chargeState = 0;
  percent     = 0;
  milliVolts  = getBattVoltage();
  return true;
}

/*
   Temperature functions
*/

protected: // get temperature in degree celsius uint16_t getTemperatureImpl() { sendAT(GF("+CPMUTEMP")); if (waitResponse(GF(GSM_NL "+CPMUTEMP:")) != 1) { return 0; } // return temperature in C uint16_t res = streamGetIntBefore('\n'); // Wait for final OK waitResponse(); return res; }

/*
   Client related functions
*/
/*  byte NTPServerSync(String server = "pool.ntp.org", byte TimeZone = 3) {
  // Set GPRS bearer profile to associate with NTP sync
  // sendAT(GF("+CNTPCID=1"));
  // if (waitResponse(10000L) != 1) { return -1; }

  // Set NTP server and timezone
  sendAT(GF("+CNTP="), server, ',', String(TimeZone));
  if (waitResponse(10000L) != 1) { return -1; }

  // Request network synchronization
  sendAT(GF("+CNTP"));
  if (waitResponse(10000L, GF(GSM_NL "+CNTP:"))) {
    String result = stream.readStringUntil('\n');
    result.trim();
    if (isValidNumber(result)) { return result.toInt(); }
  } else {
    return -1;
  }
  return -1;
  } */

protected: bool _ssl = true; bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = true, int timeout_s = 15) {

  if (_ssl) {
    sendAT(GF("+CSSLCFG=\"sslversion\",0,4"));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"authmode\",0,2"));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"ignorelocaltime\",0,1"));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"negotiatetime\",0,25"));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"cacert\",0,\"ca_cert.pem\""));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"clientcert\",0,\"cert.pem\""));
    waitResponse();
    sendAT(GF("+CSSLCFG=\"clientkey\",0,\"key_cert.pem\""));
    waitResponse();
    sendAT(GF("+CCHSET=1,1"));
    waitResponse();
    sendAT(GF("+CCHSTART"));
    waitResponse();
    sendAT(GF("+CCHSSLCFG=0,0"));
    waitResponse();
  }
  // Make sure we'll be getting data manually on this connection

  // waitResponse();
  // Establish a connection in multi-socket mode
  uint32_t timeout_ms = ((uint32_t)timeout_s) * 1000;
  if (!_ssl) {
       sendAT(GF("+CIPRXGET=1"));
  if (waitResponse() != 1) { return false; }
    sendAT(GF("+CIPOPEN="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
  }
  else { 
    sendAT(GF("+CCHOPEN=0,"), GF("\""), host, GF("\","), port, GF(",2"));
  }
  // The reply is OK followed by +CIPOPEN: <link_num>,<err> where <link_num>
  // is the mux number and <err> should be 0 if there's no error

  if (!_ssl) {
    if (waitResponse(timeout_ms, GF(GSM_NL "+CIPOPEN:")) != 1) {
      return false;
    }
  }
  else {
    if (waitResponse(timeout_ms,GF(GSM_NL "+CCHOPEN: 0,0")) != 1) {
      return false;
    }
    else{
         return true;
    }
  }

/*   uint8_t opened_mux    = streamGetIntBefore(',');
  uint8_t opened_result = streamGetIntBefore('\n');
  if (opened_mux != mux || opened_result != 0)
  {
      DBG("return false;");
    return false;
  }
  else
  {
        DBG("return TRUE;");
    return true;
  } */
}

int16_t modemSend(const void* buff, size_t len, uint8_t mux) {
     DBG("modemSend called ");
  if (!_ssl) {
    sendAT(GF("+CIPSEND="), mux, ',', (uint16_t)len);
  }
  else {
    sendAT(GF("+CCHSEND="), mux, ',', (uint16_t)len);
  }

DBG("modemSend waitResponse> called "); if (waitResponse(GF(">")) != 1) { return 0; } SerialMon.print((const int )buff); stream.write(reinterpret_cast<const uint8_t*>(buff), len); stream.flush(); if (!_ssl) { if (waitResponse(GF(GSM_NL "+CIPSEND:")) != 1) { return 0; } } else { DBG("modemSend waitResponse CCHSEND called "); if (waitResponse(GF(GSM_NL "+CCHSEND:")) != 1) { return 0; } }

  streamSkipUntil(',');  // Skip mux
  streamSkipUntil(',');  // Skip requested bytes to send
  // TODO(?):  make sure requested and confirmed bytes match
  return streamGetIntBefore('\n');
}

size_t modemRead(size_t size, uint8_t mux) {
    DBG("modemRead  called ");
  int16_t len_requested = 0;
  int16_t len_confirmed = 0;
  if (!sockets[mux]) return 0;
  if (!_ssl)
  {

ifdef TINY_GSM_USE_HEX

    sendAT(GF("+CIPRXGET=3,"), mux, ',', (uint16_t)size);
    if (waitResponse(GF("+CIPRXGET:")) != 1) {
      return 0;
    }

else

    sendAT(GF("+CIPRXGET=2,"), mux, ',', (uint16_t)size);
    if (waitResponse(GF("+CIPRXGET:")) != 1) {
      return 0;
    }

endif

    //+CIPRXGET: 2,1,5,11
    streamSkipUntil(',');  // Skip Rx mode 2/normal or 3/HEX 2,
    streamSkipUntil(',');  // Skip mux/cid (1,)
    len_requested = streamGetIntBefore(',');//5,
    //  ^^ Requested number of data bytes (1-1460 bytes)to be read
    len_confirmed = streamGetIntBefore('\n');//,11
  }
  else {
    sendAT(GF("+CCHRECV="), mux, ',', (uint16_t)size);
    DBG("modemRead  CCHRECV called ");
    if (waitResponse(GF("+CCHRECV:")) != 1) {
      return 0;
    }
    // DATA,0,4
    streamSkipUntil(',');  //DATA,
    streamSkipUntil(',');  // Skip mux/cid (0,)
    len_requested = streamGetIntBefore('\n');
    // DBG("###len_requested", len_requested);

    len_confirmed = len_requested;
  }

  // ^^ The data length which not read in the buffer
  for (int i = 0; i < len_requested; i++) {
    uint32_t startMillis = millis();

ifdef TINY_GSM_USE_HEX

    while (stream.available() < 2 &&
           (millis() - startMillis < sockets[mux]->_timeout)) {
      TINY_GSM_YIELD();
    }
    char buf[4] = {
      0,
    };
    buf[0] = stream.read();
    buf[1] = stream.read();
    char c = strtol(buf, NULL, 16);

else

    while (!stream.available() &&
           (millis() - startMillis < sockets[mux]->_timeout)) {
      TINY_GSM_YIELD();
    }
    char c = stream.read();
    SerialMon.print(c);

endif

    sockets[mux]->rx.put(c);
  }
  // DBG("### READ:", len_requested, "from", mux);
  sockets[mux]->sock_available = modemGetAvailable(mux);
  // sockets[mux]->sock_available = len_confirmed;
  if (!_ssl)
  {
    waitResponse();
  }
  return len_requested;
}

size_t modemGetAvailable(uint8_t mux) {
    DBG("modemGetAvailable   called ");
  if (!sockets[mux]) return 0;
  size_t result = 0;
  if (!_ssl)
  {
    sendAT(GF("+CIPRXGET=4,"), mux);

    if (waitResponse(GF("+CIPRXGET:")) == 1) {
      streamSkipUntil(',');  // Skip mode 4
      streamSkipUntil(',');  // Skip mux
      result = streamGetIntBefore('\n');
      waitResponse();
    }
  }
  else
  {
    // AT+CCHRECV? +CCHRECV: LEN,<cache_len_0>,<cache_len_1>
    sendAT(GF("+CCHRECV?"));
    DBG("modemGetAvailable  +CCHRECV? called ");
    if (waitResponse(GF("+CCHRECV:")) == 1) {
      streamSkipUntil(',');  // Skip mode 4
      result = streamGetIntBefore(',');
      DBG("modemGetAvailable  +CCHRECV?2 called ");
      waitResponse();
    }
  }
   DBG("### Available:", result, "on", mux);
  if (!result) {
    sockets[mux]->sock_connected = modemGetConnected(mux);
  }
  return result;
}

bool modemGetConnected(uint8_t mux) {
    DBG("modemGetConnected called ");
  // Read the status of all sockets at once
  if (!_ssl)
  {
    sendAT(GF("+CIPCLOSE?"));
    if (waitResponse(GF("+CIPCLOSE:")) != 1) {
      return false;  // TODO:  Why does this not read correctly?
    }
    for (int muxNo = 0; muxNo < TINY_GSM_MUX_COUNT; muxNo++) {
      // +CIPCLOSE:<link0_state>,<link1_state>,...,<link9_state>
      bool muxState = stream.parseInt();
      if (sockets[muxNo]) {
        sockets[muxNo]->sock_connected = muxState;
      }
    }
    waitResponse();  // Should be an OK at the end
    if (!sockets[mux])
      return false;
    return sockets[mux]->sock_connected;
  }
  else {
    sendAT(GF("+CCHOPEN?"));
    DBG("modemGetConnected +CCHOPEN? waitResponsecalled ");
    if (waitResponse(GF("+CCHOPEN:")) != 1) {
        DBG("Modem not connectedXXXXXXXXXXXXXXXXX CCHOPEN Not Found");
        return false;
        }
      //+CCHOPEN: 0,"",,,
      streamSkipUntil(',');
      String res = stream.readStringUntil(',');
      if (res == "\"\"")
      {
            DBG("Modem not connectedXXXXXXXXXXXXXXXXX empty +CCHOPEN: 0,"",,, Found");
        return false;
      }
      else {
          DBG("************Modem is connected Found in sim7600 Library****************");
          DBG("Dats is",res);
           sockets[mux]->sock_connected = true;
            waitResponse();  // Should be an OK at the end
           sockets[mux]->sock_connected;
        return true;
      }
    }

  return false;
}

/*
   Utilities
*/

public: // TODO(vshymanskyy): Optimize this! int8_t waitResponse(uint32_t timeout_ms, String& data, GsmConstStr r1 = GFP(GSM_OK), GsmConstStr r2 = GFP(GSM_ERROR),

if defined TINY_GSM_DEBUG

                    GsmConstStr r3 = GFP(GSM_CME_ERROR),
                    GsmConstStr r4 = GFP(GSM_CMS_ERROR),

else

                    GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,

endif

                    GsmConstStr r5 = NULL) {
   /*   String r1s(r1); r1s.trim();
     String r2s(r2); r2s.trim();
     String r3s(r3); r3s.trim();
     String r4s(r4); r4s.trim();
     String r5s(r5); r5s.trim();
     DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s); */
  data.reserve(64);
  uint8_t  index       = 0;
  uint32_t startMillis = millis();
  do {
    TINY_GSM_YIELD();
    while (stream.available() > 0) {
      TINY_GSM_YIELD();
      int8_t a = stream.read();
      if (a <= 0) continue;  // Skip 0x00 bytes, just in case
      data += static_cast<char>(a);

      if (r1 && data.endsWith(r1)) {
        index = 1;
        goto finish;
      } else if (r2 && data.endsWith(r2)) {
        index = 2;
        goto finish;
      } else if (r3 && data.endsWith(r3)) {

if defined TINY_GSM_DEBUG

        if (r3 == GFP(GSM_CME_ERROR)) {
          streamSkipUntil('\n');  // Read out the error
        }

endif

        index = 3;
        goto finish;
      } else if (r4 && data.endsWith(r4)) {
        index = 4;
        goto finish;
      } else if (r5 && data.endsWith(r5)) {
        index = 5;
        goto finish;
      } else if (data.endsWith(GF(GSM_NL "+CIPRXGET:"))) {
        int8_t mode = streamGetIntBefore(',');
        if (mode == 1) {
          int8_t mux = streamGetIntBefore('\n');
          if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
            sockets[mux]->got_data = true;
          }
          data = "";
          // DBG("### Got Data:", mux);
        } else {
          // DBG("data += mode");
          data += mode;
        }
      } else if (data.endsWith(GF(GSM_NL "+RECEIVE:"))) {
        int8_t  mux = streamGetIntBefore(',');
        int16_t len = streamGetIntBefore('\n');
        if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
          sockets[mux]->got_data = true;
          if (len >= 0 && len <= 1024) {
            sockets[mux]->sock_available = len;
          }
        }
        data = "";
        // DBG("### Got Data:", len, "on", mux);
      }
      else if (data.endsWith(GF(GSM_NL "+CCHRECV:"))) //+CCHRECV: DATA,0,4
      {
        DBG("*************data start**************");
        //+CCHRECV: DATA, <session_id>,<len>
        streamSkipUntil(',');  // Skip DATA,
        int8_t  mux = streamGetIntBefore(',');//Skip 0,
        int16_t len = streamGetIntBefore('\n');//Skip ,4
        if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
        DBG("### Got_data = true");
          sockets[mux]->got_data = true;
          if (len >= 0 && len <= 1024) {
            sockets[mux]->sock_available = len;
          }
        }
        data = "";
        DBG("### Got Data:", len, "on", mux);
        DBG("**************data end*************");
      }
      else if (data.endsWith(GF("+IPCLOSE:"))) {
        int8_t mux = streamGetIntBefore(',');
        streamSkipUntil('\n');  // Skip the reason code
        if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
          sockets[mux]->sock_connected = false;
        }
        data = "";
        // DBG("### Closed: ", mux);
      } else if (data.endsWith(GF("+CIPEVENT:"))) {
        // Need to close all open sockets and release the network library.
        // User will then need to reconnect.
        // DBG("### Network error!");
        if (!isGprsConnected()) {
          gprsDisconnect();
        }
        data = "";
      }
    }
  } while (millis() - startMillis < timeout_ms);

finish: if (!index) { data.trim(); if (data.length()) { DBG("*Unhandled**"); DBG(data); DBG("*Unhandled end**"); } } // DBG("###############data start2#################"); ////data.replace(GSM_NL, "/"); // DBG('<', index, '>', data); // data = ""; // DBG("##############data end2####################"); return index; }

int8_t waitResponse(uint32_t timeout_ms, GsmConstStr r1 = GFP(GSM_OK),
                    GsmConstStr r2 = GFP(GSM_ERROR),

if defined TINY_GSM_DEBUG

                    GsmConstStr r3 = GFP(GSM_CME_ERROR),
                    GsmConstStr r4 = GFP(GSM_CMS_ERROR),

else

                    GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,

endif

                    GsmConstStr r5 = NULL) {
  String data;
  return waitResponse(timeout_ms, data, r1, r2, r3, r4, r5);
}

int8_t waitResponse(GsmConstStr r1 = GFP(GSM_OK),
                    GsmConstStr r2 = GFP(GSM_ERROR),

if defined TINY_GSM_DEBUG

                    GsmConstStr r3 = GFP(GSM_CME_ERROR),
                    GsmConstStr r4 = GFP(GSM_CMS_ERROR),

else

                    GsmConstStr r3 = NULL, GsmConstStr r4 = NULL,

endif

                    GsmConstStr r5 = NULL) {
  return waitResponse(1000, r1, r2, r3, r4, r5);
}

public: Stream& stream;

protected: GsmClientSim7600 sockets[TINY_GSM_MUX_COUNT]; const char gsmNL = GSM_NL; };

endif // SRC_TINYGSMCLIENTSIM7600H

ashwanisihag commented 3 years ago

I have tried with both AWS as well as azute iot...i got success in connecting both as TLS1.2 See the code above. Regards

mlrochaa23 commented 3 years ago

I tried that, but I had not success. When I use TinyGSMCLientSecure, I can't connect to elasticsearch server. I'm using the SIM800l module.

Try to use https://github.com/OPEnSLab-OSU/SSLClient You can eliminate the usage of TinyGSMCLientSecure

Hi woodlist. Many thanks for your tip. I tried that and worked fine!!

SRGDamia1 commented 3 years ago

If this is working for you now, could you please close the issue?

ramonpaolo commented 6 months ago

@mlrochaa23 share please