aws / aws-iot-device-sdk-embedded-C

SDK for connecting to AWS IoT from a device using embedded C.
MIT License
975 stars 623 forks source link

Fleet provisioning compatibility with ESP32 on Arduino #1828

Closed gavin-k-mccormick closed 1 year ago

gavin-k-mccormick commented 1 year ago

I am using Arduino for ESP32 programming and have successfully connected the ESP32 to AWS by manually creating a new thing, generating a cert and using that cert on the ESP32 (not using the AWS SDK). However, I am hoping there is a way to use fleet provisioning on the ESP32 via Arduino and not esp-idf running FreeRTOS. Has this been done? I don't see an easy way to port this SDK over to Arduino to get the provisioning demo to work.

aggarg commented 1 year ago

If you have a successful connection to AWS IoT, that means you have an MQTT clinet running on the device doing MQTT Subscribe and Publish. Fleet-Provisioning-for-AWS-IoT-embedded-sdk helps you to generate topic strings that you can use with your MQTT client to interact with the Fleet Provisioning service. You can use this example for reference.

gavin-k-mccormick commented 1 year ago

Thanks for the response. My issue seems to be with porting the dependencies over to Arduino. the generateKeyAndCsr() function within pkcs11_operations.c calling the mbedtls libraries is an example where the porting complexity is above my head. I'm hoping fleet provisioning has been done on the arduino ESP32 and some simpler examples can be found.

aggarg commented 1 year ago

When you connect to AWS, which TLS stack are you using? If Arduino for ESP32 uses ESP-IDF, then you are likely using mbedTLS and you should be able to use the example as-is.

gavin-k-mccormick commented 1 year ago

I am using MQTTClient library to connect to AWS. below is my code to manually connect without using provisioning. i have a separate file, config.h, that contains wifi creds and the certs to connect to AWS.

/*
  AWS Communication test code

  - TODO : Test fleet provisioning to connect and get cert for later use

*/

#include "config.h"

#include <WiFiClientSecure.h>
#include <MQTTClient.h> //MQTT Library Source: https://github.com/256dpi/arduino-mqtt

#include <ArduinoJson.h> //ArduinoJson Library Source: https://github.com/bblanchon/ArduinoJson
#include "WiFi.h"

// MQTT topics for the device
#define AWS_IOT_PUBLISH_TOPIC   "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"

WiFiClientSecure wifi_client = WiFiClientSecure();
MQTTClient mqtt_client = MQTTClient(256); //256 indicates the maximum size for packets being published and received.

uint32_t t1;

/****************************************************
  connectAWS
****************************************************/
void connectAWS()
{
  //Begin WiFi in station mode
  WiFi.mode(WIFI_STA); 
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("Connecting to Wi-Fi");

  //Wait for WiFi connection
  while (WiFi.status() != WL_CONNECTED){

    delay(500);
    Serial.print(".");

  }
  Serial.println();

  // Configure wifi_client with the correct certificates and keys
  wifi_client.setCACert(AWS_CERT_CA);
  wifi_client.setCertificate(AWS_CERT_CRT);
  wifi_client.setPrivateKey(AWS_CERT_PRIVATE);

  //Connect to AWS IOT Broker. 8883 is the port used for MQTT
  mqtt_client.begin(AWS_IOT_ENDPOINT, 8883, wifi_client);

  //Register callback function for incoming messages
  mqtt_client.onMessage(CallBackHandler);

  Serial.print("Connecting to AWS IOT");

  //Wait for connection to AWS IoT
  while (!mqtt_client.connect(THINGNAME)) {    

    Serial.print(".");
    delay(100);

  }
  Serial.println();

  if(!mqtt_client.connected()){

    Serial.println("AWS IoT Timeout!");
    return;

  }

  //Subscribe to a topic
  mqtt_client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);

  Serial.println("AWS IoT Connected!");
}

/****************************************************
  publishMessage
****************************************************/
void publishMessage()
{
  //Create a JSON document of size 200 bytes, and populate it
  //See https://arduinojson.org/
  StaticJsonDocument<200> doc;
  doc["elapsed_time"] = millis() - t1;
  doc["value"] = random(1000);
  char jsonBuffer[512];
  serializeJson(doc, jsonBuffer); // print to mqtt_client

  //Publish to the topic
  mqtt_client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
  Serial.println("Sent a message");
}

/****************************************************
  CallBackHandler
****************************************************/
void CallBackHandler(String &topic, String &payload) {

  Serial.println("Message received!");
  Serial.println("Topic: " + topic);
  Serial.println("Payload: " + payload);

}

/*********************** SETUP *******************************/
void setup() {

  Serial.begin(115200);
  t1 = millis();
  connectAWS();

}

/*********************** MAIN LOOP ***************************/
void loop() {

  publishMessage();
  mqtt_client.loop();
  delay(4000); // minimum of 10ms after .loop for stability

}
aggarg commented 1 year ago

It seems to use mbedTLS - https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFiClientSecure/src/esp_crt_bundle.c#L49

Do you face any issue when you try to build the code for generateKeyAndCsr?

aggarg commented 1 year ago

I am closing this issue. Feel free to reopen or create a new issue if you need more help.