I have a MKR1000 board and been getting some kind of timeout error SSL_CLIENT_WRITE_FAIL with SSL each time the MQTT client publishes to the broker. The sketch seems to work otherwise. That is to say it connects to the MQTT broker and publishes and other clients can subscribe and receive the sent messages, all over TLS. However, after publishing a message to the broker the sketch seems to hang for about 22 seconds before producing some warning messages and then moving on while producing some additional warning messages. I can't figure out how to prevent the delay. I'd like to get rid of both the delay and the errors or, failing that, just get rid of the delay.
Below is the output sent by the script to the Serial Monitor, and in that the epoch is shown before each debugging message. Below that is the sketch itself. What should I be looking at to correct the mistake and at least avoid the timeout if not also the error messages? As mentioned, the broker is receiving the encrypted messages from the MKR1000.
Setup: Attempting to connect to WPA SSID: xxxxx
SSID: xxxxx
BSSID: xx:xx:xx:xx:xx:xx
192.168.xxx.xxx
signal strength (RSSI): -67
Encryption Type: 2
--------------------------------------------------
Setup is done
Reconnect() attempting MQTT connection...
(SSLClient)(SSL_WARN)(connect): Using a raw IP Address for an SSL connection bypasses some important verification steps. You should use a domain name (www.google.com) whenever possible.
1611241426+connected...
1611241426+published...
(SSLClient)(SSL_ERROR)(m_update_engine): Error writing to m_client
(SSLClient)(SSL_ERROR)(m_update_engine): 1
(SSLClient)(SSL_ERROR)(connected): Socket was unexpectedly interrupted. m_client error:
(SSLClient)(SSL_ERROR)(connected): 1
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
(SSLClient)(SSL_WARN)(m_run_until): Terminating with write error:
(SSLClient)(SSL_WARN)(m_run_until): 4
(SSLClient)(SSL_ERROR)(flush): Could not flush write buffer!
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
1611241448+flushed...
(SSLClient)(SSL_ERROR)(write): Cannot operate if the write error is not reset:
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
1611241449+disconnected...
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
Reconnect() attempting MQTT connection...
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
(SSLClient)(SSL_WARN)(connect): Using a raw IP Address for an SSL connection bypasses some important verification steps. You should use a domain name (www.google.com) whenever possible.
1611241449+connected...
1611241449+published...
Here is the sketch:
/*
This connects but gives an SSL Error
*/
#include <SPI.h> // built-in WiFi shield uses SPI
#include <WiFi101.h> // WiFi support https://www.arduino.cc/en/Reference/WiFi101
#include <WiFiUdp.h>
#include <SSLClient.h> // https://github.com/OPEnSLab-OSU/SSLClient
#include <PubSubClient.h> // https://pubsubclient.knolleary.net/
#include <RTCZero.h> // https://www.arduino.cc/en/Reference/RTC
RTCZero rtc;
#include "certificates.h" //
#include "wifi-secrets.h" //
char ssid[] = SECRET_SSID; // network SSID
char pass[] = SECRET_PASS; // network password
int status = WL_IDLE_STATUS; // the WiFi radio's status
SSLClientParameters mTLS = SSLClientParameters::fromPEM(my_cert, sizeof my_cert, my_key, sizeof my_key);
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void printMacAddress(byte mac[]) {
for (int i = 5; i >= 0; i--) {
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
if (i > 0) {
Serial.print(":");
}
}
Serial.println();
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// IP Address
ip = WiFi.localIP();
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI): ");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type: ");
Serial.println(encryption, HEX);
Serial.println();
}
WiFiClient wifi;
SSLClient tls(wifi, TAs, (size_t)TAs_NUM, A5); // the last value is an Analog pin to draw random input from
PubSubClient mqttClient(mqttServer, mqttPort, callback, tls);
// mqttClient.setServer(mqttServer, mqttPort);
boolean reconnect() {
int epoch = WiFi.getTime();
// mqttClient.setKeepAlive(90);
/// mqttClient.setCallback(callback);
// Loop until we're reconnected
while (!mqttClient.connected()) {
Serial.println("Reconnect() attempting MQTT connection...");
// Attempt to connect
if (mqttClient.connect("mkr1000", MQTT_ACCT, MQTT_PASS)) {
epoch = WiFi.getTime();
Serial.print(epoch);
Serial.println("+connected...");
// tls.flush();
// Once connected, publish an announcement...
mqttClient.publish("outTopic", "Hello World from MKR1000");
epoch = WiFi.getTime();
Serial.print(epoch);
Serial.println("+published...");
// This is a necessary workaround to partially address https://github.com/OPEnSLab-OSU/SSLClient/issues/9
tls.flush();
epoch = WiFi.getTime();
Serial.print(epoch);
Serial.println("+flushed...");
// ... and resubscribe
// mqttClient.subscribe("inTopic");
// This is a workaround to address https://github.com/OPEnSLab-OSU/SSLClient/issues/9
// tls.flush();
mqttClient.disconnect ();
epoch = WiFi.getTime();
Serial.print(epoch);
Serial.println("+disconnected...");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
return mqttClient.connected();
}
void setup() {
// Start Serial
Serial.begin(115200);
Serial.println("Starting");
while (!Serial);
WiFi.hostname("mkr1000");
// Enable mutual TLS with SSLClient
tls.setMutualAuthParams(mTLS);
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("Setup: WiFi shield not present");
// don't continue:
while (true);
}
// attempt to connect to WiFi network:
while ( WiFi.status() != WL_CONNECTED) {
Serial.print("Setup: Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 5 seconds for connection:
delay(5000);
}
printCurrentNet();
// Initialize RTC
rtc.begin();
Serial.println("--------------------------------------------------");
Serial.println("Setup is done");
}
void loop() {
if (!mqttClient.connected()) {
reconnect();
}
Serial.println();
mqttClient.loop();
}