mobizt / ESP_SSLClient

The upgradable Secure Layer Networking (SSL/TLS) TCP Client for Arduino devices that support external networking interfaces e.g., WiFiClient, EthernetClient, and GSMClient.
MIT License
18 stars 2 forks source link

Issue connecting to AWS IOT (Arduino UNO R4 WiFi) #15

Closed RaymondReddingt0n closed 1 month ago

RaymondReddingt0n commented 1 month ago

Hey, I am having trouble using this library as well as a few others to connect to AWS IOT. These are the relevant parts of the code:

#include <WiFiS3.h>
#include "WiFiSSLClient.h"
#include <ArduinoJson.h>
#include <NTPClient.h>
#include "certs.h"
#include <MQTTClient.h>
#include <ESP_SSLClient.h>

// AWS
#define DEVICE_NAME "Arduino_1"
#define AWS_IOT_ENDPOINT "censored-ats.iot.eu-north-1.amazonaws.com"
#define AWS_IOT_TOPIC_1 "arduino/logs"
#define AWS_IOT_TOPIC_2 "arduino/thermostats"
#define AWS_MAX_RECONNECT_TRIES 10

// WiFi credentials
const char ssid[] = "censored";
const char pass[] = "censored";

WiFiClient wifi;
ESP_SSLClient net;
MQTTClient client1(net);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0, 1000);  // Sync every second

void setup() {
  Serial.begin(9600);

  // Connect to Wi-Fi
  Serial.print("Connecting to Wi-Fi...");
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnected to Wi-Fi");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Initialize NTPClient
  timeClient.begin();
  timeClient.update();

  connectToAWS();
}

void connectToAWS() {
  timeClient.update();

  // Get the current epoch time in UTC
  unsigned long utcTime = timeClient.getEpochTime();

  // Print the UTC time in Unix format
  Serial.print("Current UTC time in Unix format: ");
  Serial.println(utcTime);

  net.setX509Time(utcTime);

  // Configure WiFiClientSecure to use the AWS certificates we generated
  net.setCACert(AWS_CERT_CA);
  net.setCertificate(AWS_CERT_CRT);
  net.setPrivateKey(AWS_CERT_PRIVATE);

  net.setBufferSizes(1024 /* rx */, 512 /* tx */);

  net.setDebugLevel(4);
  net.setClient(&wifi);

  // Connect to the MQTT broker on the AWS endpoint we defined earlier
  client1.begin(AWS_IOT_ENDPOINT, 8883, net);

  // Try to connect to AWS
  Serial.println("Connecting to AWS IOT...");

  client1.connect(DEVICE_NAME);
}

This is the serial output for the connection attempt:

16:54:06.681 -> Current UTC time in Unix format: 1722873246 16:54:06.915 -> Connecting to AWS IOT... 16:54:07.384 -> > INFO.mConnectBasicClient: Basic client connected! 16:54:07.384 -> > INFO.mConnectSSL: Start connection. 16:54:07.384 -> > WARN.mConnectSSL: Connection will fail, no authentication method is setup. 16:54:07.571 -> > INFO.mConnectSSL: Wait for SSL handshake. 16:54:07.571 -> > INFO.mUpdateEngine: State RECVREC 16:54:07.618 -> > INFO.mUpdateEngine: State RECVREC 16:54:07.757 -> > INFO.mRunUntil: SSL state changed. 16:54:07.757 -> > INFO.mRunUntil: State RECVREC 16:54:07.757 -> > INFO.mRunUntil: Expected bytes count: 5 16:54:09.395 -> > INFO.mUpdateEngine: State RECVREC 16:54:15.010 -> > INFO.mUpdateEngine: State RECVREC 16:54:15.195 -> > INFO.mUpdateEngine: State SENDAPP 16:54:15.288 -> > INFO.mRunUntil: SSL state changed. 16:54:15.288 -> > INFO.mRunUntil: State SENDAPP 16:54:15.288 -> > INFO.mConnectSSL: Connection successful!

Is it really connecting? It says that the connection will fail but then it says it connected successfully. I tried using an insecure connection, in that case it just says that the connection was successful.

Later in my code I have a function to attempt sending data to the database, structured like this:

void sendDeviceData() {

  timeClient.update();

  // Get the current epoch time in UTC
  unsigned long utcTime = timeClient.getEpochTime();

  // Print the UTC time in Unix format
  Serial.print("Current UTC time in Unix format: ");
  Serial.println(utcTime);

  Serial.println("Sending device data to AWS...");

  // Create a JSON object to hold the temperature data
  DynamicJsonDocument tempDoc(512); // Adjust size as needed
  JsonObject historyEntry = tempDoc.createNestedObject(utcTime);
  historyEntry["tempA"] = tempA;
  historyEntry["tempF"] = tempF;
  historyEntry["tempR"] = tempR;
  historyEntry["tempD"] = tempD;

  // Serialize JSON object to string
  String tempData;
  serializeJson(tempDoc, tempData);

  // Publish temperature data to AWS IoT
  if (client1.publish(AWS_IOT_TOPIC_1, tempData)) {
    Serial.println("Temperature data published to AWS IoT");
  } else {
    Serial.println("Failed to publish temperature data");
  }

  // Create a JSON object to hold the message and alarm data
  DynamicJsonDocument messageDoc(256);  // Adjust size as needed
  messageDoc["message"] = message;
  messageDoc["alarm"] = alarm;

  // Serialize JSON object to string
  String messageData;
  serializeJson(messageDoc, messageData);

  // Publish message data to AWS IoT
  if (client1.publish(AWS_IOT_TOPIC_2, messageData)) {
    Serial.println("Message data published to AWS IoT");
  } else {
    Serial.println("Failed to publish message data");
  }
}

However, the message is never received by AWS IOT.

If someone could help me with this I'd really appreciate it. Other alternatives like using SSLClientSecure are not an option because of the board I'm using (most tutorials I found use that library).

Thanks in advance.

mobizt commented 1 month ago

Server was connected and negotiated.

You have to check the authorization or authentication in your application instead.

mobizt commented 1 month ago

I have checked and sorry for that false warning message. You can ignore it.

mobizt commented 1 month ago

The false warning was fixed in v2.1.10.