I'm trying to send a SMS and read data from Firebase with my NodeMCU Amica V2. The code works fine when I either only send a SMS or only read data from Firebase. However, when I combine this two codes SMS isn't sent. I also added logging of the Connection failed error. I used getLastSSLError method and now it writes: Unable to allocate memory for SSL structures and buffers. I found a thread about this error on Reddit, however, I don't know how to troubleshoot it. This is the full error I get:
+ Connected.
+ Post an HTTP send SMS request.
+ Connection is closed.
+ Response:
31.0630+ Using fingerprint 'BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0'
+ Connecting to api.twilio.com
- Connection failed.
Last SSL error was:
Unable to allocate memory for SSL structures and buffers.
ERRCODE: -1000
And here is my code:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <base64.h>
#include "OneWire.h"
#include "DallasTemperature.h"
#include <ArduinoJson.h>
#include <string>
using namespace std;
#include <sstream>
#include <iostream>
#include "FirebaseArduino.h"
// Your network SSID and password
const char* ssid = "*****";
const char* password = "*****";
const char* account_sid = "*****";
const char* auth_token = "*****";
String to_number = "+*****";
String from_number = "+*****";
String message_body = "Hello from Twilio and the ESP8266!";
// Find the api.twilio.com SHA1 fingerprint using,
// echo | openssl s_client -connect api.twilio.com:443 | openssl x509 -fingerprint
const char fingerprint[] = "BC B0 1A 32 80 5D E6 E4 A2 29 66 2B 08 C8 E0 4C 45 29 3F D0";
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define FIREBASE_HOST "***.firebaseio.com"
#define FIREBASE_AUTH "*****"
float temp1 = 0;
//float temp2 = 0;
String b;
int c;
String urlencode(String str) {
String encodedString = "";
char c;
char code0;
char code1;
char code2;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (c == ' ') {
encodedString += '+';
} else if (isalnum(c)) {
encodedString += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) {
code1 = (c & 0xf) - 10 + 'A';
}
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) {
code0 = c - 10 + 'A';
}
code2 = '\0';
encodedString += '%';
encodedString += code0;
encodedString += code1;
}
yield();
}
return encodedString;
}
String get_auth_header(const String& user, const String& password) {
size_t toencodeLen = user.length() + password.length() + 2;
char toencode[toencodeLen];
memset(toencode, 0, toencodeLen);
snprintf(toencode, toencodeLen, "%s:%s", user.c_str(), password.c_str());
String encoded = base64::encode((uint8_t*)toencode, toencodeLen - 1);
String encoded_string = String(encoded);
std::string::size_type i = 0;
// Strip newlines (after every 72 characters in spec)
while (i < encoded_string.length()) {
i = encoded_string.indexOf('\n', i);
if (i == -1) {
break;
}
encoded_string.remove(i, 1);
}
return "Authorization: Basic " + encoded_string;
}
void setup() {
Serial.begin(115200); // 115200 or 9600
delay(1000); // Give the serial connection time to start before the first print.
Serial.println(""); // Newline after garbage characters.
Serial.println(F("+++ Setup."));
// ----------------------------------------------------
Serial.println("+ Connect to WiFi. ");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.print("+ Connected to WiFi, IP address: ");
Serial.println(WiFi.localIP());
// ----------------------------------------------------
sensors.begin();
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
}
void loop() {
sensors.requestTemperatures();
temp1 = sensors.getTempCByIndex(0);
Serial.print(temp1);
b = Firebase.getString("002/alarm");
c = b.toInt();
Serial.print(c);
if (temp1 > c) {
// Use WiFiClientSecure to create a TLS 1.2 connection.
// Note, using a cert fingerprint is required.
WiFiClientSecure client;
client.setFingerprint(fingerprint);
Serial.printf("+ Using fingerprint '%s'\n", fingerprint);
const char* host = "api.twilio.com";
const int httpsPort = 443;
Serial.print("+ Connecting to ");
Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("- Connection failed.");
char buf[200];
int err = client.getLastSSLError(buf, 199);
buf[199] = '\0';
Serial.println("Last SSL error was:");
Serial.println(buf);
Serial.print("ERRCODE: ");
Serial.println(err);
///* END snippet from pushdata-io project */
// return false;
}
Serial.println("+ Connected.");
Serial.println("+ Post an HTTP send SMS request.");
String post_data = "To=" + urlencode(to_number)
+ "&From=" + urlencode(from_number)
+ "&Body=" + urlencode(message_body);
String auth_header = get_auth_header(account_sid, auth_token);
String http_request = "POST /2010-04-01/Accounts/" + String(account_sid) + "/Messages HTTP/1.1\r\n"
+ auth_header + "\r\n"
+ "Host: " + host + "\r\n"
+ "Cache-control: no-cache\r\n"
+ "User-Agent: ESP8266 Twilio Example\r\n"
+ "Content-Type: application/x-www-form-urlencoded\r\n"
+ "Content-Length: " + post_data.length() + "\r\n"
+ "Connection: close\r\n"
+ "\r\n"
+ post_data
+ "\r\n";
client.println(http_request);
// Read the response.
String response = "";
while (client.connected()) {
String line = client.readStringUntil('\n');
response += (line);
response += ("\r\n");
}
Serial.println("+ Connection is closed.");
Serial.println("+ Response:");
Serial.println(response);
}
delay(5000);
}
Does that mean that the NodeMCU doesn't have enough memory? I also tried changing delay() to milis(), but that didn't solve the problem.
Any help would be appreciated!