Hello,
I am facing an issue while attempting to connect my Arduino MKR 1500 NB to an MQTT broker using a combination of NBClient, BearSSLClient, and arduinoMqttClient libraries. Despite successfully connecting to the NB IoT network and establishing a UDP connection to an NTP server, the connection to the MQTT broker fails during the inital BearSSL connect process. The failure occurs specifically during the br_sslio_flush(&_ioc) call in the BearSSLClient::connectSSL function, where the program freezes without generating a response, timeout, or error. Could this issue be related to an inconsistency in the character sequence length following the AT command issued to the NBIoT module? Or is it something else?
I am using an Arduino MKR 1500 NB client -> BearSSLClient ->arduinoMqttClient
// Initialize MQTT and SSL clients from library
NBClient nbClient;
BearSSLClient sslClient(nbClient);
MqttClient arduinoMqttClient(sslClient);
I am able to connect to the NB IoT network and I am even able to start a UDP connection to an NTP server (which is used for
ArduinoBearSSL.onGetTime(get_time); // Required for server trusted root validation.
)
We then get ready to initialize the MQTT client, and the problem comes up when we run arduinoMqttClient.connect(address,port) link:
arduinoMqttClient.setId(client_id);
arduinoMqttClient.setUsernamePassword(username, password);
arduinoMqttClient.setCleanSession(true);
arduinoMqttClient.onMessage(on_message_received);
LogInfo("MQTT Client ID: %s", client_id);
LogInfo("MQTT Username: %s", username);
LogInfo("MQTT Password: ***");
LogInfo("MQTT client address: %s", address);
LogInfo("MQTT client port: %d", port);
bool mqtt_connected = false;
Serial.println("MQTT Connecting MQTT client...");
while (!mqtt_connected) {
if (arduinoMqttClient.connect(address, port)){
Serial.println("Succesful MQTT connection to Azure broker!");
mqtt_connected = true;
}
else {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(arduinoMqttClient.connectError());
//int code = arduinoMqttClient.connectError();
//LogError("Cannot connect. Error Code: %d", code);
delay(5000);
}
}
arduinoMqttClient.connect(address,port) calls, which runs until _client->connect(host, port):
int MqttClient::connect(IPAddress ip, const char* host, uint16_t port)
{
Serial.println("MQTTClient : Start connect");
if (clientConnected()) {
_client->stop();
}
_rxState = MQTT_CLIENT_RX_STATE_READ_TYPE;
_connected = false;
_txPacketId = 0x0000;
if (host) {
Serial.println("MQTTClient : Connecting by host");
if (!_client->connect(host, port)) {
_connectError = MQTT_CONNECTION_REFUSED;
Serial.println("MQTTClient : 0 - host connection refused");
return 0;
}
}
_client->connect(host, port) seems to trigger a call to two functions:
- First it calls
int NBClient::connect() link which executes successfully and creates a TCP socket with "global.azure-devices-provisioning.net",8883:
- After that in triggers
int BearSSLClient::connectSSL(const char* host) which is where the failure occurs, specifically on the call to br_sslio_flush(&_ioc); function:
-
At that time there is an AT command issued to the NBIoT module and after that the program doesn't genereate any reposnse or timeout or error return. It just freezes.
-
One thing that I did note is that the character sequence following the AT+USOWR command is not of the same length as specified in the start of the AT command (178 vs the 242 supposed to be sent). But I don't know if this is just an issue with MAX number of characters in arduino's Serial.println()
-Here are the Serial.print() statments I am using for debugging aling with the AT commands sent by MKRNB module:
14:03:39.127 -> MQTTClient : Start connect
14:03:39.127 -> MQTTClient : Connecting by host
14:03:39.127 -> NBC : Starting NB connect
14:03:39.127 -> 1
14:03:39.218 -> AT+USOCR=6
14:03:39.218 -> +USOCR: 1
14:03:39.218 ->
14:03:39.252 -> OK
14:03:39.428 -> AT+USOCO=1,"global.azure-devices-provisioning.net",8883
14:03:43.042 -> OK
14:03:43.042 -> NBC : 1 - success END
14:03:43.042 -> BSSL : Starting BSSL connect
14:03:43.168 -> AT+USOST=0,"129.6.15.28",123,48,"E30006EC0000000000000000314E31340000000000000000000000000000000000000000000000000000000000000000"
14:03:43.168 -> +USOST: 0,48
14:03:43.214 ->
14:03:43.214 -> OK
14:03:43.214 -> 1 - Waiting for time packet....
14:03:44.199 -> +UUSORF: 0,48
14:03:44.199 -> AT+USORF=0,512
14:03:44.240 ->
14:03:44.240 -> +USORF: 0,"129.6.15.28",123,48,"1C010DE300000010000000204E495354EA60F480000000000000000000000000EA60F4A027DB0056EA60F4A027DB15F6"
14:03:44.240 -> OK
14:03:44.240 -> NTP packet received
14:03:44.240 -> BSSL : Finish random - get_time()
14:03:44.240 -> BSSL : Begin socket init
14:03:44.240 -> BSSL : socketflush
14:03:44.240 -> AT+USORD=1,512
14:03:44.240 -> +USORD: 1,""
14:03:44.240 ->
14:03:44.240 -> OK
14:03:44.308 -> AT+USOWR=1,242,"16030100ED010000E9030300000000D7C94A75B33CD7C36976D1E83A101F715E653FA3017151659FDD639900005ACCA9CCA8C02BC02FC02CC030C0ACC0ADC0AEC0AFC023C027C024C028C009C013C00AC014C02DC031C02EC032C025C029C026C02AC004C00EC005C00F009C009DC09CC09DC0A0C0A1003C003D002F0035C008C012C003C00D000A01000066FF010001000000002A0028000025676C6F62616C2E617A7572652D646576696365732D70726F
Additional int BearSSLClient::connectSSL(const char* host) reference code with debug Serial.println() statements added:
int BearSSLClient::connectSSL(const char* host)
{
Serial.println("BSSL : Starting BSSL connect");
if (!_br_ssl_client_init_function) {
return 0;
}
// initialize client context with enabled algorithms and trust anchors
_br_ssl_client_init_function(&_sc, &_xc, _TAs, _numTAs);
br_ssl_engine_set_buffers_bidi(&_sc.eng, _ibuf, sizeof(_ibuf), _obuf, sizeof(_obuf));
// inject entropy in engine
unsigned char entropy[32];
#ifndef ARDUINO_DISABLE_ECCX08
if (!ECCX08.begin() || !ECCX08.locked() || !ECCX08.random(entropy, sizeof(entropy))) {
#endif
// no ECCX08 or random failed, fallback to pseudo random
for (size_t i = 0; i < sizeof(entropy); i++) {
entropy[i] = random(0, 255);
}
#ifndef ARDUINO_DISABLE_ECCX08
}
#endif
br_ssl_engine_inject_entropy(&_sc.eng, entropy, sizeof(entropy));
// add custom ECDSA vfry and EC sign
br_ssl_engine_set_ecdsa(&_sc.eng, _ecVrfy);
br_x509_minimal_set_ecdsa(&_xc, br_ssl_engine_get_ec(&_sc.eng), br_ssl_engine_get_ecdsa(&_sc.eng));
// enable client auth
if (_ecCert[0].data_len) {
#ifndef ARDUINO_BEARSSL_DISABLE_KEY_DECODER
if (_skeyDecoder) {
int skeyType = br_skey_decoder_key_type(_skeyDecoder);
if (skeyType == BR_KEYTYPE_EC) {
br_ssl_client_set_single_ec(&_sc, _ecCert, _ecChainLen, br_skey_decoder_get_ec(_skeyDecoder), BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default(), br_ecdsa_sign_asn1_get_default());
} else if (skeyType == BR_KEYTYPE_RSA) {
br_ssl_client_set_single_rsa(&_sc, _ecCert, _ecChainLen, br_skey_decoder_get_rsa(_skeyDecoder), br_rsa_pkcs1_sign_get_default());
}
} else {
#endif
br_ssl_client_set_single_ec(&_sc, _ecCert, _ecChainLen, &_ecKey, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, BR_KEYTYPE_EC, br_ec_get_default(), _ecSign);
#ifndef ARDUINO_BEARSSL_DISABLE_KEY_DECODER
}
#endif
}
// set the hostname used for SNI
br_ssl_client_reset(&_sc, host, 0);
// get the current time and set it for X.509 validation
uint32_t now = ArduinoBearSSL.getTime();
uint32_t days = now / 86400 + 719528;
uint32_t sec = now % 86400;
Serial.println("BSSL : Finish random - get_time()");
br_x509_minimal_set_time(&_xc, days, sec);
Serial.println("BSSL : Begin socket init");
// use our own socket I/O operations
br_sslio_init(&_ioc, &_sc.eng, BearSSLClient::clientRead, _client, BearSSLClient::clientWrite, _client);
Serial.println("BSSL : socketflush");
br_sslio_flush(&_ioc);
Serial.println("BSSL : PROBLEM HERE!");
while (1) {
Serial.println("BSSL : get state, on loop");
unsigned state = br_ssl_engine_current_state(&_sc.eng);
Serial.println("BSSL : run ifs");
if (state & BR_SSL_SENDAPP) {
break;
} else if (state & BR_SSL_CLOSED) {
return 0;
}
Serial.println("BSSL : help, trap");
}
Serial.println("BSSL : 1 - success END");
return 1;
}
Hello,
I am facing an issue while attempting to connect my Arduino MKR 1500 NB to an MQTT broker using a combination of NBClient, BearSSLClient, and arduinoMqttClient libraries. Despite successfully connecting to the NB IoT network and establishing a UDP connection to an NTP server, the connection to the MQTT broker fails during the inital BearSSL connect process. The failure occurs specifically during the
br_sslio_flush(&_ioc) call in theBearSSLClient::connectSSLfunction, where the program freezes without generating a response, timeout, or error. Could this issue be related to an inconsistency in the character sequence length following the AT command issued to the NBIoT module? Or is it something else?I am using an Arduino MKR 1500 NB client -> BearSSLClient ->arduinoMqttClient
I am able to connect to the NB IoT network and I am even able to start a UDP connection to an NTP server (which is used for
ArduinoBearSSL.onGetTime(get_time); // Required for server trusted root validation.)
We then get ready to initialize the MQTT client, and the problem comes up when we run
arduinoMqttClient.connect(address,port)link:arduinoMqttClient.connect(address,port)calls, which runs until_client->connect(host, port):_client->connect(host, port)seems to trigger a call to two functions:int NBClient::connect()link which executes successfully and creates a TCP socket with "global.azure-devices-provisioning.net",8883:int BearSSLClient::connectSSL(const char* host)which is where the failure occurs, specifically on the call tobr_sslio_flush(&_ioc);function:At that time there is an AT command issued to the NBIoT module and after that the program doesn't genereate any reposnse or timeout or error return. It just freezes.
One thing that I did note is that the character sequence following the AT+USOWR command is not of the same length as specified in the start of the AT command (178 vs the 242 supposed to be sent). But I don't know if this is just an issue with MAX number of characters in arduino's Serial.println()
-Here are the Serial.print() statments I am using for debugging aling with the AT commands sent by MKRNB module:
Additional
int BearSSLClient::connectSSL(const char* host)reference code with debug Serial.println() statements added: