-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uable to connect mqtt broker #63
Comments
Hi, I don't have the sim module you are using but if you post your full code I can try it later against my aws account. |
Hi @RobertByrnes , I'm having the exact same issue. I can get the entire pipeline to work when I'm leveraging alkonosst/SSLClientESP32, although it's incredibly slow (4s for publish, 6s for loop). But I'd like to use govorox's as it's more widely used and hopefully is faster. I too am getting :
My main file is: #include <configs/certificate.h>
// bricks
#include <bricks/SIMCOM.hpp>
// libs
#include <Arduino.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <SSLClient.h>
SSLClient secure(&SIMCOM::client);
PubSubClient pubsub(secure);
void publishMessage()
{
StaticJsonDocument<200> doc;
doc["humidity"] = "hello there!";
doc["temperature"] = 123;
char jsonBuffer[256];
serializeJson(doc, jsonBuffer); // print to pubsub
pubsub.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer);
}
void messageHandler(char *topic, byte *payload, unsigned int length)
{
Serial.print("incoming: ");
Serial.println(topic);
StaticJsonDocument<200> doc;
deserializeJson(doc, payload);
const char *message = doc["message"];
Serial.println(message);
}
void setup()
{
Serial.begin(115200);
secure.setCACert(AWS_CERT_CA);
secure.setCertificate(AWS_CERT_CRT);
secure.setPrivateKey(AWS_CERT_PRIVATE);
Serial.println("Started...");
SIMCOM::init();
// Connect to the MQTT broker on the AWS endpoint we defined earlier
pubsub.setServer(AWS_IOT_ENDPOINT, 8883);
// Create a message handler
pubsub.setCallback(messageHandler);
Serial.print("Connecting to AWS IOT: ");
if (pubsub.connect(THINGNAME)) {
// Subscribe to a topic
Serial.println("AWS IoT Connected!");
} else {
while (!pubsub.connected()) {
pubsub.connect(THINGNAME);
Serial.println("... still not connected");
}
}
pubsub.subscribe(AWS_IOT_SUBSCRIBE_TOPIC, MQTTQOS1);
}
void loop()
{
publishMessage();
pubsub.loop();
delay(1000);
} and, yep this works with alkonosst/SSLClientESP32, so I know the URL, port, and certs are okay... static const char AWS_CERT_CA[] PROGMEM =
"-----BEGIN CERTIFICATE-----\r\n"
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\r\n"
...
"-----END CERTIFICATE-----\r\n";
static const char AWS_CERT_CRT[] PROGMEM =
"-----BEGIN CERTIFICATE-----""\n"
"MIIDWjCCAkKgAwIBAgIVAKPQbOtfpI4/8pcCYPJVZ8/pN2zSMA0GCSqGSIb3DQEB""\n"
...
"-----END CERTIFICATE-----";
static const char AWS_CERT_PRIVATE[] PROGMEM =
"-----BEGIN RSA PRIVATE KEY-----""\n"
"MIIEpgIBAAKCAQEA10ESwd+HUTP8y1aQVcApc4Bjk9DQ+UejnNMrqtfZD5zoDKKI""\n"
...
"-----END RSA PRIVATE KEY-----"; My SIMCOM init is just a wrapper around the normal SIMCOM initializers (I'm using TinyGSM on a SIM7600G) ...
TinyGsm modem(SerialAT);
TinyGsmClient client(modem, 0);
...
/**
* @brief Initialize the SIMCOM module against the configs, and connect to network.
*
* @returns true if successful, otherwise false
*/
bool init()
{
SerialAT.begin(AT_BAUD, SERIAL_8N1, UART_RX, UART_TX);
delay(6000);
// This can take quite some time
Serial.println("Initializing modem... ");
while (!modem.init())
{
}
String modemInfo = modem.getModemInfo();
Serial.print("Modem Info: ");
Serial.println(modemInfo);
Serial.print("Waiting for network... ");
if (!modem.waitForNetwork())
{
Serial.println(" fail");
return false;
}
if (modem.isNetworkConnected())
{
Serial.println("Network connected");
}
// Enable full functionality
modem.setPhoneFunctionality(1);
// Turn on the GPRS
Serial.print(F("Connecting to "));
Serial.print(APN_4G);
if (!modem.gprsConnect(APN_4G))
{
Serial.println(" fail");
return false;
}
Serial.println(" success");
if (modem.isGprsConnected())
{
Serial.println("GPRS connected");
}
// Update the internal clock (good for SSL)
modem.NTPServerSync();
// Turn on the GPS
modem.disableGPS();
delay(500);
if (modem.enableGPS())
{
Serial.println("GPS enabled");
}
return true;
} Have you got any ideas? Edit: |
So I'm not completely alone in experiencing literally the exact same error as posted in the very beginning of this issue, namely:
It appears to be directly caused by use of a client certificate/key, as the server logs indicate the SSL CA is complete by this point. Heck, the function failing is literally the one that uses the client cert/key! Lines 691 to 735 in eee8718
It fails on both WiFiClient and TinyGsmClient (as I've made my code able to switch between the two at will) exactly the same. So far, ArduinoBearSSL also fails. And yes, after running dangerously low on hair, I did finally try SSLClientESP32 whose successful connection was the most beautiful sight I've seen in over two weeks at this point. I literally just imported the library, changed the #include and the define, and compiled the project--to success. I don't understand the difference, as the SSLClientESP32 repo was forked from SSLClient here. Both use mbedTLS under the hood. The only potential clue I see is the commonality with the only other SSL library that has worked: the default WiFiClientSecure on the Arduino-ESP32 core. Apart from both using mbedTLS, both also come with certificate packs. I sincerely hope there isn't anything to that--because if so, then the certs we provide are being ignored or are insufficient in some way. I shall have to disable the cert packs in that library and see if success turns into failure. For science. |
Whoa, wait a minute....! A significant amount of code is missing in the above "perform_ssl_handshake" routine. Line 721 in eee8718
In the (working) SSLClientESP32, there are numerous search results for "cli_cert", including mbedTLS conversion and processing routines, as seen here: I have to conclude that the client cert/key functionality was never tested here with SSLClient; the code here required to support said functionality is completely missing! |
OK, so looking closer...maybe everything's not missing. Lines 539 to 567 in eee8718
But something else is missing/wrong, as the SSLClientESP32 uses the same "mbedtls_ssl_get_record_expansion" call that fails here in SSLClient--but it doesn't fail there. I'm not much help with this SSL stuff--it's gargantuan complicated. But something's definitely wrong here. |
@Matt-Stedman-HardStuff
I am suspecting part of the problem here to be how the libraries interact with each other. I'm similarly stacking an SSLClient on top of TinyGSM, but utilizing the StreamDebugger to see what's going on. I'm running the modem serial at 115200, but the above problem results in molasses speeds. (Just to read the SSL handshake in takes ~30 seconds, and then the server times out and closes the connection.) Gonna have to figure out where this nonsensical bottleneck is, and fix it...! Oh, and a size comparison...SSLClientESP32 is definitely the biggest of all of the ones so far. Size of compressed firmware with the entire rest of my application stack in it, so the size is not as important as the difference:
|
@WebDust21 @TONYCHOU81905 @Matt-Stedman-HardStuff - @RobertByrnes - I get the same issue as above for
|
@WebDust21 - I use this library with AWS IoT and TinyGSM as it was the least painful one. I haven't tested the speed though as I'm only using this for low speed IoT communications |
My findings with alkonosst/SSLClientESP32@^2.0.3: it actually leverages the mbedTLS implementation provided in the Arduino-ESP32 core, instead of bringing an entirely separate one in. That ends up not helping the total binary size, as it's still the largest of all of the available options...but it's the simplest wrapper. The main huge speed bottleneck I encountered (initial testing was >30 seconds for SSL handshake--which would fail because the server would abort the connection) was due to the default TinyGSM buffer size of 64 bytes. When you're transferring 4KB+ for the SSL handshake, it takes an extremely long time to do it 63 bytes at a time. After setting the TinyGSM default buffer to 1436 bytes (i.e. a typical MTU) with
...I promptly ran into another issue: the default Arduino-ESP32 serial FIFO buffer size of 256 bytes, resulting in most of the data being lost. (Plus a TinyGSM bug that would cause it to wait for nonexistent data for close to 2 minutes at a time.) Setting the serial FIFO buffer size to 1436 bytes * 1.2 (for some extra headroom)...
...solved the issue; now the SSL handshake takes ~5 seconds tops. @deeja Very good info to know...now I want to diff the two versions and see what changed to break it! |
This is great info in this thread! Haven't had a lot of time recently but feeling a pulling it all together update very soon. Please consider adding PR for any changes - even if it is just in the README.md to document best practice based on your findings. Cheers.... @deeja @WebDust21 @TONYCHOU81905 @Matt-Stedman-HardStuff |
@WebDust21 Fair enough. This is roughly how I wrapped my call. #define TINY_GSM_RX_BUFFER 1024
TinyGsmClient networkClient(modem);
SSLClient sslClient(&networkClient);
PubSubClient mqttClient(AWS_IOT_ENDPOINT, AWS_IOT_PORT, provisionCallback, &sslClient, Serial);
// Wrapper
SSLClient sslClient(&networkClient);
sslClient->setCACert(AWS_CA_CERTIFICATE);
sslClient->setCertificate(AWS_CERTIFICATE);
sslClient->setPrivateKey(AWS_PRIVATEKEY); |
Interestingly I am getting this in 1.1.16 but the connection still works :
|
Just a note to everyone that might be trying to get SSL working via a SIM7600 and leveraging TinyGSM, @floBik and I (though mostly @floBik) managed to leverage the SIM7600's in-built SSL functionality, which seems to work for HTTPS and MQTTS. Currently the PR is still awaiting approval, but you can reference or fork via https://github.com/Matt-Stedman-HardStuff/TinyGSM This means you can use the SIMCOM module and SSL without needing this govorox/SSLClient (sorry @govorox 😂) |
@Matt-Stedman-HardStuff - I'll keep an eye on that PR |
Problem for me is that the SIM7080 modules I have, cannot successfully complete an SSL connection over either SSL TCP or MQTT. (The latter is unsurprising, as it runs over a TCP connection.) |
#78 @deeja @WebDust21 @TONYCHOU81905 Please see this PR and the comments in issue #71 This may now be fixed |
closed as solved by v1.2.0 |
Hi,
I am using A7600 with esp32 to connect AWS mqtt!
But I got the error message below:
[ 26256][E][ssl_client.cpp:728] perform_ssl_handshake(): mbedtls_ssl_get_record_expansion returned -0xffffffe3
[ 26263][E][ssl_client.cpp:45] _handle_error(): [start_ssl_client():353]: (29) UNKNOWN ERROR CODE (001D)
[ 26264][E][SSLClient.cpp:235] connect(): start_ssl_client failed: 0
This is my code
`TinyGsmClient base_client(modem, 0);
SSLClient secure_layer(&base_client);
PubSubClient mqtt(secure_layer);
while (!mqtt.connect(mqttid.c_str()))
{
mqtt.setServer(broker, 8883);
mqtt.setCallback(mqttCallback);
mqtt.setKeepAlive(60);
mqtt.setBufferSize(2048);
Serial.println("Connecting to AWS IoT...");
Serial.println("AWS2_FreeHeap : " + String(ESP.getFreeHeap()));
if (mqtt.connect(String(THINGNAME).c_str())) {
Serial.println("Connected to AWS IoT!");
Serial.println("Topic:");
Serial.println(THINGNAME);
} else {
Serial.print("Failed to connect to AWS IoT, rc=");
Serial.println(mqtt.state());
delay(2000);
}
}`
This is my certificate's format
![圖片1](https://private-user-images.githubusercontent.com/48522029/288985461-d5abcab9-32f3-4426-b009-3a550733f187.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkwNjIwNTQsIm5iZiI6MTczOTA2MTc1NCwicGF0aCI6Ii80ODUyMjAyOS8yODg5ODU0NjEtZDVhYmNhYjktMzJmMy00NDI2LWIwMDktM2E1NTA3MzNmMTg3LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA5VDAwNDIzNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTZiN2Q2ODRlMjQ3ZmU1N2IyN2FlY2QxZDVhY2ZiNzBmODJlMjVkODNiYzc1YzVhY2E4ODE4MzYwZmU0YTNlZmEmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.XmyMgclZVBnhsyIxhkjOqsjYjuUubMprrWdKdH4IhLM)
The text was updated successfully, but these errors were encountered: