gilmaimon / ArduinoWebsockets

A library for writing modern websockets applications with Arduino (ESP8266 and ESP32)
GNU General Public License v3.0
482 stars 97 forks source link

Hieromon/AutoConnect & WebSockets Client on ESP8266 - Can't Establish wss #141

Open Dishwishy opened 1 year ago

Dishwishy commented 1 year ago

Describe the bug I'm trying to integrate the AutoConnect library with ArduinoWebsockets. When I attempt to use the AutoConnect library in conjunction with ArduinoWebsockets, the ESP8266 can never set up an initial connection to wss://. I have tried this both with client.setInsecure() as well as with client.setFingerprint(). If I remove the AutoConnect library from the build and do a manual hard-coding of WifiCredentials and use that to establish a connection, I am able to establish a wss:// connection successfully.

To Reproduce Steps to reproduce the behavior. This should include:

Expected behavior I would expect the wss:// connection work work irrespective of if AutoConnect is used or not to setup the initial Wifi connection.

I have tested this on an ESP32 board (lolin_d32), and it works fine (although client.setInsecure() does not work with this library and esp32, but that is a bug report for another time).

Code

/*
  Secured Esp8266 Websockets Client
  This sketch:
        1. Connects to a WiFi network
        2. Connects to a Websockets server (using WSS)
        3. Sends the websockets server a message ("Hello Server")
        4. Sends the websocket server a "ping"
        5. Prints all incoming messages while the connection is open
    NOTE:
    The sketch dosen't check or indicate about errors while connecting to 
    WiFi or to the websockets server. For full example you might want 
    to try the example named "Esp8266-Client" (And use the ssl methods).
  Hardware:
        For this sketch you only need an ESP8266 board.
  Created 15/02/2019
  By Gil Maimon
  https://github.com/gilmaimon/ArduinoWebsockets
*/

#include <ArduinoWebsockets.h>
#ifdef ESP32
  #include <WiFi.h>
#endif
#ifdef ESP8266
  #include <ESP8266WiFi.h>
  #include <ESP8266WebServer.h>
#endif
#include <ArduinoJson.h>
#include <AutoConnect.h>

const char* websockets_connection_string = "wss://<placeholder AWS API Gateway websocket>"; //Enter server adress
// other examples to test with
//const char* websockets_server_host = "wss://echo.websocket.org/";
//const char* url_path = "/api/"; // this is the URI separate form host

AutoConnect portal;
AutoConnectConfig  config;
bool acEnable;

// CA Cert Test
#ifdef ESP32
const char aws_ssl_ca_cert[] PROGMEM = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n" \
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" \
"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n" \
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n" \
"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n" \
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n" \
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n" \
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n" \
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n" \
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n" \
"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n" \
"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n" \
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n" \
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n" \
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n" \
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n" \
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n" \
"rqXRfboQnoZsG4q5WTP468SQvvG5\n" \
"-----END CERTIFICATE-----\n";
#endif 

#ifdef ESP8266
const char ssl_fingerprint[] PROGMEM = "DA 04 49 CB 7A 77 FC 8D 6E 3B F7 65 1F 12 B9 E8 EC BF 28 2A";
#endif

using namespace websockets;
WebsocketsClient client;

// global for our JSON doc
StaticJsonDocument<200> doc;

void onMessageCallback(WebsocketsMessage message) {
    Serial.print("Got Message: ");
    Serial.println(message.data());
}

void onEventsCallback(WebsocketsEvent event, String data) {
    if(event == WebsocketsEvent::ConnectionOpened) {
        Serial.println("Connnection Opened");
        char client_msg[200];
        serializeJson(doc,client_msg);
        Serial.println(client_msg);
        client.send(client_msg);
    } else if(event == WebsocketsEvent::ConnectionClosed) {
        Serial.println("Connnection Closed");
    } else if(event == WebsocketsEvent::GotPing) {
        Serial.println("Got a Ping!");
    } else if(event == WebsocketsEvent::GotPong) {
        Serial.println("Got a Pong!");
    }
}

void setup() {
    Serial.begin(115200);
    //Autoconnect stuff
    config.portalTimeout = 30000;  // It will time out in 30 seconds
    portal.config(config);
    acEnable = portal.begin();

  if (acEnable) {

    Serial.println("Setting Up JSON");
    // Get some Chip ID per hw action
    #ifdef ESP8266
      char hwbuf[8];
      ltoa(ESP.getChipId(),hwbuf,8);
      client.setFingerprint(ssl_fingerprint);

    #endif

    #ifdef ESP32
    char hwbuf[8];
    uint32_t efuse;
    efuse = (uint32_t)ESP.getEfuseMac();
    ltoa(efuse,hwbuf,8);

    //hwbufs = String((uint32_t)ESP.getEfuseMac(), HEX);
    client.setCACert(aws_ssl_ca_cert);
    //client.setInsecure();

    #endif

    Serial.println("Hardware number");
    Serial.println(hwbuf);
    doc["hwid"] = hwbuf; //String(ESP.getChipId()).c_str();
    doc["user_email"] = "k.champlin@gmail.com";
    JsonArray recp = doc.createNestedArray("recp");
    // in prod, this will need to be captured at the wifi portal level
    recp.add("friend1");
    // in produ this will need to be captured at the wifi portal level
    doc["sender"] = "pzzachip";

    // run callback when messages are received
    client.onMessage(onMessageCallback);

    // run callback when events are occuring
    client.onEvent(onEventsCallback);

    // Before connecting, set the ssl fingerprint of the server
    //client.setFingerprint(echo_org_ssl_fingerprint);

    // Connect to server
    Serial.println("attempting websocket connection");
    client.connect(websockets_connection_string);
  }

}

void loop() {
    if (WiFi.status() == WL_CONNECTED) {

      client.poll();
    }

    if(acEnable){
      portal.handleClient();
    }

}

Additional context Add any other context about the problem here.