Hi All,
I am unable to establish a successful connection to nRF Cloud using the nRF52840 and OpenThread network via MQTT over TLS.
Sensitive information in the project, such as certificates, will be invalidated by deleting devices after the issue is resolved.
My NCS version is v2.5.2, and I aim to connect to nRF Cloud using the nRF52840 with the OpenThread network.
I am aware of the ncs\v2.5.2\nrf\samples\cellular\nrf_cloud_multi_service example, but it is complex and not specifically tailored for the Thread network. Therefore, I initially attempted to use the relatively simpler ncs\v2.5.2\nrf\samples\net\aws_iot example.
According to the nRF Cloud documentation, I first created a device using the CreateDeviceCertificate API and obtained the device certificate. The returned content is as follows:
{ "clientId": "device001", "caCert": "-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\nADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\nb24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\nb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\nca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\nIFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\nVOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\njgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\nA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\nU5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\nN+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\no/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\nrqXRfboQnoZsG4q5WTP468SQvvG5\n-----END CERTIFICATE-----\n", "privateKey": "-----BEGIN EC PARAMETERS-----\nBggqhkjOPQMBBw==\n-----END EC PARAMETERS-----\n-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFYf7XHeemu6d+i3sInjMB+sfaRc4388kB77CCUqxJlwoAoGCCqGSM49\nAwEHoUQDQgAEREwfetVI+bXNsdcEhrijYMnsgsqR2aNDNWnKDmlsVAh7BohJ8sLB\nLROSzhg2TgdSMmP85utf+odzTsHv1uxJ8w==\n-----END EC PRIVATE KEY-----\n", "clientCert": "-----BEGIN CERTIFICATE-----\nMIICoDCCAYgCCQCaZE9v50In9jANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJO\nTzEPMA0GA1UECAwGTm9yd2F5MRIwEAYDVQQHDAlUcm9uZGhlaW0xHTAbBgNVBAoM\nFE5vcmRpYyBTZW1pY29uZHVjdG9yMRkwFwYDVQQLDBBHZW5lcmljLTE0YTE4Yjkw\nMCAXDTI0MDIyOTA3NDMwMloYDzIwNTQwMjIxMDc0MzAyWjCBgDELMAkGA1UEBhMC\nTk8xEjAQBgNVBAgMCVRyb25kZWxhZzESMBAGA1UEBwwJVHJvbmRoZWltMSEwHwYD\nVQQKDBhOb3JkaWMgU2VtaWNvbmR1Y3RvciBBU0ExEjAQBgNVBAMMCWRldmljZTAw\nMTESMBAGA1UELhMJZGV2aWNlMDAxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nREwfetVI+bXNsdcEhrijYMnsgsqR2aNDNWnKDmlsVAh7BohJ8sLBLROSzhg2TgdS\nMmP85utf+odzTsHv1uxJ8zANBgkqhkiG9w0BAQsFAAOCAQEAnrOOM440DEzLvrdH\nFPbLZfjgS/qxZG41kGm6zR6TRGRaORAIOocwkrnGpaGcqFHWIvcP4l1nKe3DAnDj\n4QLnmEiogvS2aB7TBTokd67KCjt/mP+6w9SIaSph7I6+yjjcxasABDbYb0kd9X99\npvZ5OAMLLbSmIQan9lXakONFeE6iZVDMp9gL0DdB1CP3ydEQm9oG+Y6CnQhU3egS\nOLqVSNZNPlGx2Y35kwu6HmAcRoYCuLQXXbPw8lPLvuJXdA6+mQP6Uufc77AzPuvv\nKQv+EtmTAmv3r4GBCIij1I38MWQeMNTi79uOK4TOZvAl75TEv0boaa9gwIFNCXgA\nrpm+Uw==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIDqzCCApOgAwIBAgIJAOXo6/ALtz+gMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV\nBAYTAk5PMQ8wDQYDVQQIDAZOb3J3YXkxEjAQBgNVBAcMCVRyb25kaGVpbTEdMBsG\nA1UECgwUTm9yZGljIFNlbWljb25kdWN0b3IxGTAXBgNVBAsMEEdlbmVyaWMtMTRh\nMThiOTAwHhcNMjMwMzE2MDMzODAwWhcNMjYwMTAzMDMzODAwWjBsMQswCQYDVQQG\nEwJOTzEPMA0GA1UECAwGTm9yd2F5MRIwEAYDVQQHDAlUcm9uZGhlaW0xHTAbBgNV\nBAoMFE5vcmRpYyBTZW1pY29uZHVjdG9yMRkwFwYDVQQLDBBHZW5lcmljLTE0YTE4\nYjkwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2CE46Te7DvZxfauo\nCZhNGpvJ/RNP5cfunU3qnzhpnpDwbgMT8lU2zMe14kolzNr2LQN09EYSDmBYh5je\nszKUT1FKKvMAs59UnPrdLiwWG6tWhfa5CzsNgMi+TjGcqK8K7D+Gv+b7EzDqtYFM\ng5FovJE6wYO/DIHRq7dVa21B3GB2vqiQZCXuef8kc1NCAXFm2MX5lkV6MQxyXYBo\nV8+/jNTiXSriGFJVG6MvF4lRTKC0TTV2NBFaJmRDwEuBoUSpbNoNDhhNOm+kbVBH\nlfXP81YwNOl+RVNbjGmA2lG3SEf/42jsCiaKjXp1cozF+EKGI8/H7ryMyoq0a3dG\nEFy7zwIDAQABo1AwTjAdBgNVHQ4EFgQU8QcvSXGLHmKmu6LrgIobANmjQ6IwHwYD\nVR0jBBgwFoAU8QcvSXGLHmKmu6LrgIobANmjQ6IwDAYDVR0TBAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAQEAAuXJuAx2BBDh44ljxqQsfLfhDNN3J8LZeoG5wbcSKQw6\nXCBp4BO/oeL8SWZ8G7WmTIxxpWyf5wBEvVGqmUnKj+skRXKVsHon63+ihomGDZTM\nb+lsPJFH0XYvmFhYhRMnDJC5FVyhsyRloyWgmRcsFoXqlkySPD8qN7/EXvHdcQwI\nB4d6mfcN9943Oywh72GdlMPxvmdBsOoRDP46Hb8NoVlEcgvNT4SWfjh6AHZiqO5r\n2NOCvvbO8S2r1NzCXBuBPtm5dY/hmbZOCiTBnK7SX6Aol24rVH7vuYOW0iLv30O2\nqke6pyCrthgdokfe2kd94L/Saos6cR8phmH5SqkZFg==\n-----END CERTIFICATE-----\n" }
I converted it to a standard PEM format certificate and validated the certificate's functionality by testing the connection using client software like mqttx. The test results showed a successful connection with a proper TLS handshake, and the simulated device appeared online on the nRF Cloud platform.
Next, I started modifying the configuration settings and code in the aws_iot example, including:
- adjustments related to net txrx/log buffer sizes
- net tls/offload configurations
- enabling IPv6/TCP/OpenThread
- configuring aws_iot to use IPv6 addresses/a specific client_id/a specific server address/device certificate
- setting mbedtls-related parameters such as heap size/CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN
- updating certificate information with the actual data obtained earlier (ca-cert.pem, client-cert.pem, private-key.pem)
These changes are mostly from existing issues with devzone:
- https://devzone.nordicsemi.com/f/nordic-q-a/86632/openthread-and-mqtt-over-tls-is-single-program
- https://devzone.nordicsemi.com/f/nordic-q-a/95781/adaption-to-tcp-tls-on-top-of-openthread
- https://devzone.nordicsemi.com/f/nordic-q-a/90352/error--22-in-mqtt_connect---nrf52840dk-with-azure-iot-hub-using-openthread-and-tcp
- https://devzone.nordicsemi.com/f/nordic-q-a/106545/rf5340-openthread-tls-handshake-problem
- https://devzone.nordicsemi.com/f/nordic-q-a/96365/tls-socket-connection-request-return-with-error-number--22-einval
- https://devzone.nordicsemi.com/f/nordic-q-a/89810/nrf-connect-mqtt-returns--22-invalid-argument
My target IPv6 address involved ping mqtt.nrfcloud.com on my PC to obtain its IPv4 address and then using CONFIG_OPENTHREAD_SHELL=y on th device to ping this address and acquire the NAT64 address.
ubuntu@guoyuchao-vm:~$ ping mqtt.nrfcloud.com PING a2n7tk1kp18wix-ats.iot.us-east-1.amazonaws.com (54.160.125.106) 56(84) bytes of data. 64 bytes from ec2-54-160-125-106.compute-1.amazonaws.com (54.160.125.106): icmp_seq=1 ttl=62 time=1.59 ms 64 bytes from ec2-54-160-125-106.compute-1.amazonaws.com (54.160.125.106): icmp_seq=2 ttl=62 time=1.03 ms 64 bytes from ec2-54-160-125-106.compute-1.amazonaws.com (54.160.125.106): icmp_seq=3 ttl=62 time=0.481 ms ^C --- a2n7tk1kp18wix-ats.iot.us-east-1.amazonaws.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 0.481/1.033/1.589/0.452 ms uart:~$ ot ping 54.160.125.106 Pinging synthesized IPv6 address: fd12:6809:36e5:2:0:0:36a0:7d6a 16 bytes from fd12:6809:36e5:2:0:0:36a0:7d6a: icmp_seq=2 hlim=60 time=16ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 16/16.0/16 ms. Done uart:~$ ot ping fd12:6809:36e5:2::36a0:7d6a 16 bytes from fd12:6809:36e5:2:0:0:36a0:7d6a: icmp_seq=1 hlim=60 time=14ms 1 packets transmitted, 1 packets received. Packet loss = 0.0%. Round-trip min/avg/max = 14/14.0/14 ms. Done uart:~$ net ping fd12:6809:36e5:2::36a0:7d6a PING fd12:6809:36e5:2::36a0:7d6a 8 bytes from fd12:6809:36e5:2::36a0:7d6a to fd11:3a::da96:b69:20e0:1d5d: icmp_seq=1 ttl=60 rssi=-174 time=29 ms 8 bytes from fd12:6809:36e5:2::36a0:7d6a to fd11:3a::da96:b69:20e0:1d5d: icmp_seq=2 ttl=60 rssi=-174 time=14 ms 8 bytes from fd12:6809:36e5:2::36a0:7d6a to fd11:3a::da96:b69:20e0:1d5d: icmp_seq=3 ttl=60 rssi=-174 time=13 ms
The only code modification made was in the client_broker_init function within the "ncs\v2.5.2\nrf\subsys\net\lib\aws_iot\src\aws_iot.c" file.
I manually changed tls_cfg->hostname to "iot.us-east-1.amazonaws.com," which is the CNAME record obtained from ping mqtt.nrfcloud.com.
This modification was necessary because it seemed that nRF Cloud did not accept mqtt.nrfcloud.com during the TLS handshake but accepted iot.us-east-1.amazonaws.com (although I also attempted to modify it to mqtt.nrfcloud.com).
Despite various adjustments, I have been unsuccessful in establishing a successful handshake and connection with nRF Cloud.
To rule out any issues related to OpenThread+TCP+MQTT, I tried disabling the mbedtls configurations, changing the MQTT server address to a public one (e.g., broker.emqx.io), and successfully connected without TLS. This indicated that my network environment, IP address connection method, and openthread functionalities like otbr/nat64 were functioning correctly.
My OpenThread network dataset information is as follows:
uart:~$ ot dataset active -x 35060004001fffe00c0402a0f7f8000300001a010212340208ce3544d81bfd9d8c030f484f4f5249495f4155544f54455354051080123a4556560aae5077abd2dd61b6610410655cbb7bb85d51b84d1b0c39c481e0c80708fdc56bfdb7900c9a0e080000000000010000 Done uart:~$ ot dataset active Active Timestamp: 1 Channel: 26 Channel Mask: 0x07fff800 Ext PAN ID: ce3544d81bfd9d8c Mesh Local Prefix: fdc5:6bfd:b790:c9a::/64 Network Key: 80123a4556560aae5077abd2dd61b661 Network Name: HOORII_AUTOTEST PAN ID: 0x1234 PSKc: 655cbb7bb85d51b84d1b0c39c481e0c8 Security Policy: 672 onrc 0 Done
My prj.conf is as follows:
# # Copyright (c) 2020 Nordic Semiconductor ASA # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # # General CONFIG_LOG=y CONFIG_LOG_BUFFER_SIZE=2048 CONFIG_HW_ID_LIBRARY=y CONFIG_ASSERT=y CONFIG_JSON_LIBRARY=y # CONFIG_LOG_MODE_IMMEDIATE=y # Heap and stacks CONFIG_HEAP_MEM_POOL_SIZE=8192 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096 CONFIG_AWS_IOT_POLL_THREAD_STACK_SIZE=4096 # Network CONFIG_NETWORKING=y CONFIG_NET_NATIVE=y CONFIG_NET_IPV4=n CONFIG_NET_CONNECTION_MANAGER=y # AWS IoT library CONFIG_AWS_IOT=y CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT=2 CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE=y CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE=y CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE=y CONFIG_AWS_IOT_CLIENT_ID_STATIC="device001" CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN=128 CONFIG_AWS_IOT_SEC_TAG=16842753 # ---------------------------------------------------- CONFIG_NET_TCP=y CONFIG_AWS_IOT_IPV6=y CONFIG_AWS_IOT_BROKER_HOST_NAME="fd12:6809:36e5:2:0:0:36a0:7d6a" CONFIG_AWS_IOT_PROVISION_CERTIFICATES=y CONFIG_NET_L2_OPENTHREAD=y CONFIG_OPENTHREAD_SLAAC=y CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_TCP_ENABLE=n CONFIG_OPENTHREAD_MANUAL_START=n CONFIG_OPENTHREAD_PANID=4660 CONFIG_OPENTHREAD_XPANID="ce:35:44:d8:1b:fd:9d:8c" CONFIG_OPENTHREAD_NETWORK_NAME="HOORII_AUTOTEST" CONFIG_OPENTHREAD_NETWORKKEY="80:12:3a:45:56:56:0a:ae:50:77:ab:d2:dd:61:b6:61" CONFIG_OPENTHREAD_CHANNEL=26 CONFIG_NET_SHELL=y CONFIG_OPENTHREAD_SHELL=y CONFIG_NET_LOG=y CONFIG_NET_CONTEXT_LOG_LEVEL_DBG=y CONFIG_MQTT_LOG_LEVEL_DBG=y CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=y CONFIG_NET_TCP_LOG_LEVEL_DBG=y CONFIG_AWS_IOT_LOG_LEVEL_DBG=y # Enable Mbed TLS logs CONFIG_MBEDTLS_DEBUG=y CONFIG_MBEDTLS_LOG_LEVEL_DBG=y # START NET #Socket settings CONFIG_NET_SOCKETS_SOCKOPT_TLS=y CONFIG_POSIX_MAX_FDS=8 CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=10 CONFIG_NET_PKT_RX_COUNT=16 CONFIG_NET_PKT_TX_COUNT=16 CONFIG_NET_BUF_RX_COUNT=100 CONFIG_NET_BUF_TX_COUNT=100 CONFIG_NET_SOCKETS_POSIX_NAMES=y CONFIG_NET_SOCKETS_POLL_MAX=10 CONFIG_NET_CONTEXT_RCVTIMEO=y CONFIG_NET_CONTEXT_SNDTIMEO=y CONFIG_NET_MAX_CONTEXTS=10 CONFIG_NET_CONTEXT_NET_PKT_POOL=y CONFIG_NET_SOCKETS_OFFLOAD=n CONFIG_NET_RX_STACK_SIZE=4096 # MBEDTLS # FROM DEVZONE # https://devzone.nordicsemi.com/f/nordic-q-a/86632/openthread-and-mqtt-over-tls-is-single-program # https://devzone.nordicsemi.com/f/nordic-q-a/95781/adaption-to-tcp-tls-on-top-of-openthread # https://devzone.nordicsemi.com/f/nordic-q-a/90352/error--22-in-mqtt_connect---nrf52840dk-with-azure-iot-hub-using-openthread-and-tcp #MBEDTLS and security configuration CONFIG_NORDIC_SECURITY_BACKEND=n CONFIG_NRF_SECURITY=n CONFIG_NET_TCP_ISN_RFC6528=n CONFIG_NRF_SECURITY=n CONFIG_OPENTHREAD_MBEDTLS_CHOICE=y CONFIG_MBEDTLS_TLS_VERSION_1_2=y CONFIG_MBEDTLS_CIPHER_MODE_CBC_ENABLED=y CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED=y CONFIG_OPENTHREAD_NRF_SECURITY_CHOICE=n CONFIG_MBEDTLS_ECDSA_C=y CONFIG_MBEDTLS_SHA256_C=y CONFIG_MBEDTLS_RSA_C=y CONFIG_MBEDTLS_AES_C=y CONFIG_MBEDTLS_PKCS1_V21=y CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=y CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED=y CONFIG_MBEDTLS_CIPHER_AES_ENABLED=y CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y CONFIG_MBEDTLS_CIPHER_GCM_ENABLED=y CONFIG_MBEDTLS_GCM_C=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_BUILTIN=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=64000 CONFIG_MBEDTLS_ENTROPY_ENABLED=y # certificate must fit into one message, fragmenting is not supported CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 #Credentials CONFIG_TLS_CREDENTIALS=y
I will share my complete project, hoping to help you analyze the problem.
My goal was to get some code or configuration changes I needed to make in order to connect to nRF Cloud, such as:
- openthread configuration
- network configuration
- mbedtls configuration,
- etc.