// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1
#define TINY_GSM_MODEM_SIM7000SSL
#define TINY_GSM_RX_BUFFER 512 // Set RX buffer to 1Kb
#define SerialAT Serial1
// See all AT commands, if wanted
#define DUMP_AT_COMMANDS
// set GSM PIN, if any
#define GSM_PIN ""
// Your GPRS credentials, if any
const char apn[] = ""; //SET TO YOUR APN
const char gprsUser[] = "";
const char gprsPass[] = "";
#include <TinyGsmClient.h>
#include <SPI.h>
#include <SD.h>
#include <Ticker.h>
#include <PubSubClient.h>
#include <Preferences.h>
#include "GSMFOTAUpdate.h"
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 60 // Time ESP32 will go to sleep (in seconds)
#define UART_BAUD 9600
#define PIN_DTR 25
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS 13
#define LED_PIN 12
#define PIN_BAT 35 /* read battery voltage, Disabled when using USB - ONLY INPUT PIN */
#define SerialMon Serial
// MQTT details
const char *broker = "";
TinyGsmClientSecure client(modem, 0);
TinyGsmClient clientOta(modem, 1);
PubSubClient mqtt(client);
// OTA STUFF
const int port = 80; // Non https. For HTTPS 443. As of today, HTTPS doesn't work.
// const char otaUrl[] = "/testbin.ino.bin"; // Host => bucket-name.s3.region.amazonaws.com
const char otaServer[] = "*.amazonaws.com";
long contentLength; // How many bytes of data the .bin is
bool isValidContentType = false;
boolean mqttConnect()
{
SerialMon.print("Connecting to ");
SerialMon.print(broker);
// Connect to MQTT Broker
boolean status = mqtt.connect(id.c_str(), id.c_str(), pwd.c_str());
if (status == false)
{
SerialMon.println(" fail");
return false;
}
SerialMon.println(" success");
mqtt.publish(topicConnection, hubId);
return mqtt.connected();
}
void enableGPS(void)
{
Serial.println("Turning on GPS power");
modem.sendAT("+SGPIO=0,4,1,1");
delay(2000);
Serial.println("Enabling GPS");
modem.enableGPS();
}
void disableGPS(void)
{
modem.sendAT("+SGPIO=0,4,1,0");
modem.disableGPS();
}
void modemPowerOn()
{
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, LOW);
delay(1000); //Datasheet Ton mintues = 1S
digitalWrite(PWR_PIN, HIGH);
}
void modemPowerOff()
{
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, LOW);
delay(1500); //Datasheet Ton mintues = 1.2S
digitalWrite(PWR_PIN, HIGH);
}
void modemRestart()
{
modemPowerOff();
delay(1000);
modemPowerOn();
}
void init()
{
modemRestart();
SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
pinMode(LED_PIN, OUTPUT);
delay(10000);
String res;
Serial.println("========INIT========");
if (!modem.init())
{
modemRestart();
delay(2000);
Serial.println("Failed to restart modem, attempting to continue without restarting");
return;
}
Serial.println("========SIMCOMATI======");
modem.sendAT("+SIMCOMATI");
modem.waitResponse(1000L, res);
res.replace(GSM_NL "OK" GSM_NL, "");
Serial.println(res);
res = "";
Serial.println("=======================");
Serial.println("=====Preferred mode selection=====");
modem.sendAT("+CNMP?");
if (modem.waitResponse(1000L, res) == 1)
{
res.replace(GSM_NL "OK" GSM_NL, "");
Serial.println(res);
}
res = "";
Serial.println("=======================");
Serial.println("=====Preferred selection between CAT-M and NB-IoT=====");
modem.sendAT("+CMNB?");
if (modem.waitResponse(1000L, res) == 1)
{
res.replace(GSM_NL "OK" GSM_NL, "");
Serial.println(res);
}
res = "";
Serial.println("=======================");
String name = modem.getModemName();
Serial.println("Modem Name: " + name);
String modemInfo = modem.getModemInfo();
Serial.println("Modem Info: " + modemInfo);
// Unlock your SIM card with a PIN if needed
if (GSM_PIN && modem.getSimStatus() != 3)
{
modem.simUnlock(GSM_PIN);
}
modem.gprsConnect(apn, gprsUser, gprsPass);
/*
2 Automatic
13 GSM only
38 LTE only
51 GSM and LTE only
* * * */
bool response;
do
{
response = modem.setNetworkMode(38);
delay(500);
} while (!response);
/*
1 CAT-M
2 NB-Iot
3 CAT-M and NB-IoT
* * */
do
{
response = modem.setPreferredMode(3);
delay(500);
} while (!response);
digitalWrite(LED_PIN, HIGH);
Serial.println();
Serial.println("Device is connected .");
Serial.println();
// Serial.println("=====Inquiring UE system information=====");
// modem.sendAT("+CPSI?");
// if (modem.waitResponse(1000L, res) == 1) {
// res.replace(GSM_NL "OK" GSM_NL, "");
// Serial.println(res);
// }
SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork())
{
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
// MQTT Broker setup
mqtt.setServer(broker, 8883);
mqtt.setKeepAlive(90);
mqtt.setCallback(mqttCallback);
enableGPS();
}
// used to extract header value from headers for ota update
String getHeaderValue(String header, String headerName) {
return header.substring(strlen(headerName.c_str()));
}
void GSMOTA() {
Serial.println("\n♦ ♦ UPDATE AVALIBLE ♦ ♦\n");
Serial.println("Connecting to: " + String(otaServer));
while (!clientOta.connect(otaServer, port)) {
Serial.print("*");
}
Serial.print("Connected to OTA server: ");
Serial.println(clientOta.connect(otaServer, port));
Serial.println("Fetching bin file at: " + String(otaUrl)); // tells where its going to get the .bin and the name its looking for
// Get the contents of the bin file
clientOta.print(String("GET ") + otaUrl + " HTTP/1.1\r\n" +
"Host: " + String(otaServer) + "\r\n" +
"Cache-Control: no-cache\r\n" +
"Connection: keep-alive\r\n\r\n");
unsigned long timeout = millis();
while (clientOta.available() == 0) {
if (millis() - timeout > 120000) {
Serial.println("clientOta Timeout !");
clientOta.stop();
return;
}
}
// Once the response is available start reading reply
while (clientOta.available()) {
// read line till /n
String line = clientOta.readStringUntil('\n');
// remove space, to check if the line is end of headers
line.trim();
// if the the line is empty, this is end of headers
// break the while and feed the remaining clientOta to the Update.writeStream();
if (!line.length()) {
// headers ended
break; // and get the OTA update started
}
// Check if the HTTP Response is 200 if not break and Exit Update
if (line.startsWith("HTTP/1.1")) {
if (line.indexOf("200") < 0) {
Serial.println("Got a non 200 status code from otaServer. Exiting OTA Update.");
break;
}
}
// extracting headers starting with content length
if (line.startsWith("Content-Length: ")) {
contentLength = atol((getHeaderValue(line, "Content-Length: ")).c_str());
Serial.println("Got " + String(contentLength) + " bytes from otaServer");
}
// Next, the content type
if (line.startsWith("Content-Type: ")) {
String contentType = getHeaderValue(line, "Content-Type: ");
Serial.println("Got " + contentType + " payload.");
if (contentType == "application/octet-stream") {
isValidContentType = true;
}
}
}
// Check what is the contentLength and if content type is `application/octet-stream`
Serial.println("contentLength : " + String(contentLength) + ", isValidContentType : " + String(isValidContentType));
// check contentLength and content type
if (contentLength && isValidContentType) {
// Check if there is enough to OTA Update
bool canBegin = Update.begin(contentLength);
// If yes, begin
if (canBegin) {
Serial.println("Begin GSMFOTA update. This may take 2 - 25 minutes to complete depending on the connection and file size. Patience!!!");
Serial.println("Firmware updating...");
size_t written = Update.writeStream(clientOta);
if (written == contentLength) {
Serial.println("Written : " + String(written) + " successfully");
} else {
Serial.println("Written only : " + String(written) + "/" + String(contentLength));
}
if (Update.end()) {
Serial.println("OTA done!");
if (Update.isFinished()) {
Serial.println("Update successfully completed. Rebooting to activate.");
ESP.restart();
} else {
Serial.println("Update not finished... Something went wrong!");
ESP.restart();
}
} else {
Serial.println("Error Occurred! \nError: " + String(Update.getError()) + " " + String(Update.errorString()) );
Serial.println("Will try to update again at a different time.\n");
clientOta.flush();
ESP.restart();
}
} else {
// not enough space to begin OTA, check .bin size
Serial.println("Not enough space to begin OTA\n");
clientOta.flush();
ESP.restart();
}
} else {
Serial.println("There was no content in the response\n");
clientOta.flush();
ESP.restart();
}
}
void setup()
{
// Set console baud rate
SerialMon.begin(115200);
delay(500);
// Set LED OFF
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(PIN_BAT, INPUT);
init();
delay(5000);
GSMOTA();
}
void loop()
{
}
Scenario, steps to reproduce
I'm trying to run OTA through http and not https. My MQTT connection via SSL works perfectly fine, but using a separate TinyGsmClient for the OTA connection fails while attempting to connect to the server. However, if I instead define TINY_GSM_MODEM_SIM7000 the get request for the binary succeeds without issue, but then I will have no way of having MQTT connection with SSL...
Expected result
I'm expecting both TinyGsmClientSecure and TinyGsmClient to work together.
Actual result
clientOta fails to even connect to the server and clientOta.connect(otaServer, port) returns 0
Debug and AT command log
♦ ♦ UPDATE AVALIBLE ♦ ♦
Connecting to: *.amazonaws.com
OK
AT+CACLOSE=1
ERROR
AT+CACID=1
OK
AT+CASSLCFG=1,ssl,0
OK
AT+CAOPEN=1,"*.amazonaws.com",80
*AT+CACLOSE=1
AT+CACID=1
[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: SIM7000 Main processor board: TTGO ESP32 TinyGSM version: 0.11.4 Code:
Scenario, steps to reproduce
I'm trying to run OTA through
http
and nothttps
. My MQTT connection via SSL works perfectly fine, but using a separateTinyGsmClient
for the OTA connection fails while attempting to connect to the server. However, if I instead defineTINY_GSM_MODEM_SIM7000
the get request for the binary succeeds without issue, but then I will have no way of having MQTT connection with SSL...Expected result
I'm expecting both
TinyGsmClientSecure
andTinyGsmClient
to work together.Actual result
clientOta
fails to even connect to the server andclientOta.connect(otaServer, port)
returns0
Debug and AT command log