I have an MKR1010 and MKR Eth Shield that connects to AWS IOT Core and sends data. This all works fine with both WiFI OR wired ethernet, just by changing one line of code.
What I would like it to do is at runtime, try ethernet and if that fails then try WiFi. It correctly initialises the network but I can't work out how to get ArduinoBearSSL to link to the correct hardware depending upon the network connection.
The BearSSLClient has a ".setClient" in the class, but there is no empty constructor to allow the class to be created empty. The "setClient" is a change which was added last year "Adding an additional BearSSL constructor as well as a method setClient to allow late initialisation. #29". https://github.com/arduino-libraries/ArduinoBearSSL/pull/29.
I can't find any examples on how to use "setClient" with BearSSLClient.
I've tried many things including the following:-
BearSSLClient sslClient;
Error returned is "error: no matching function for call to 'BearSSLClient::BearSSLClient()'";
Trying to initialise two instances of BearSSLClient unsurprisingly gives an out of memory error.
BearSSLClient sslClient1(wifiClient);
BearSSLClient sslClient2(etherClient);
Error returned is "will not fit in region `RAM'"
The code below is a working example of the connectivity stage.
Any guidance or examples explaining how to assign BearSSl at runtime would be much appreciated.
I have a knowledge of many programming languages, gathered over many years, but can't claim to be a master of any. I am reasonably capable in C++ but light years from being an expert.
Thanks.
#include <ArduinoBearSSL.h>
#include <Ethernet.h>
#include <WiFiNINA.h>
// WiFi
const char param_SSID[] = "SSID"; // network SSID
const char param_Pass[] = "WiFi Password"; // your network password (use for WPA, or use as key for WEP)
// Ethernet
byte param_etherMAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // mac address
WiFiClient wifiClient; // create wifi
EthernetClient etherClient; // create ethernet
//BearSSLClient sslClient; // doesn't work - no constructor
// create SSL client (one only of the following two lines at a time)
BearSSLClient sslClient(wifiClient); // works for wifi
//BearSSLClient sslClient(etherClient); // works for wired
// following lines result in an out of memory error
//BearSSLClient sslClient1(wifiClient);
//BearSSLClient sslClient2(etherClient);
void setup() {
// setup diagnostics port
Serial.begin(9600);
while (!Serial) {}
// start the network
if ( etherConnect() ) {
// wired worked
sslClient.setClient(etherClient); // set BearSSlClient
} else {
// connect to wifi if ethernet failed
wifiConnect();
sslClient.setClient(wifiClient); // set BearSSlClient
}
}
void loop() {
}
bool wifiConnect() {
int wifiState;
// check to see if already connected
wifiState = WiFi.status();
if ( wifiState != WL_CONNECTED ) {
// check for the WiFi module:
if ( wifiState == WL_NO_MODULE) {
Serial.print("Communication with WiFi module failed!");
// don't continue
while (true);
}
// attempt to connect to WiFi network:
while ( wifiState != WL_CONNECTED ) {
Serial.print("Connecting to WiFi: ");
// Connect to WPA/WPA2 network:
wifiState = WiFi.begin(param_SSID, param_Pass);
Serial.println(wifiState);
// wait for 5 secs
delay(5000);
}
// connected
Serial.print("WiFi IP Address: ");
Serial.println(WiFi.localIP());
}
}
/* returns true if an ethernet connection is established otherwise false */
bool etherConnect() {
bool rtn = false;
// try to connect ethernet using dhcp. 2nd parameter is timeout in ms
if ( Ethernet.begin(param_etherMAC, 5000) == 0 ) {
// Check for shield and cable
if ( Ethernet.hardwareStatus() == EthernetNoHardware ) {
Serial.println("No ethernet shield");
} else if ( Ethernet.linkStatus() == LinkOFF ) {
Serial.println("No ethernet cable");
}
Serial.println("Ethernet failed to connect");
} else {
Serial.print("Ethernet IP address: ");
Serial.println(Ethernet.localIP());
rtn = true;
}
return rtn;
}