MQTT over Thread

Today I am attempting to set up an MQTT connection from a Thread device to an MQTT server on the Internet (for better or for worse, if this is a terrible idea I'm open to suggestions).

I've done some preliminary investigation using the Thread CLI example and am now starting to develop code using the Thread API in SDK 2.6.0.  I have a border router running on an RPi with NAT64.

At this point I can do a DNS lookup using otDnsClientResolveIp4Address, sending the request to fd34:e64f:ccd9:02:0:0:808:808 (i.e. 8.8.8.8) and I get back the address of the MQTT server as a synthesized IPv6 address.  I can ping this address and get a response.

The next step is to attempt an MQTT connection. 

I start by calling getaddrinfo() to resolve the IP address of the broker, this fails with -ENOENT, it's the same whether I use hints.ai_family = AF_INET or AF_INET6.

So instead I tried using the address returned by the earlier DNS lookup.  Then I call mqtt_connect() but get -EPROTOTYPE (protocol wrong type for socket).

I see some discussion in DevZone from people trying to do similar things but none quite the same as this.  Perhaps I'm being naive thinking that it should 'just work'?

Any suggestions will be gladly received.

Thanks,

  Frog

  • Hi Frog,

    If you search MQTT_TRANSPORT_SECURE in NCS source codes, you will find some samples about to properly set up TLS connection in MQTT.

    Hope this will give you some hint.

    Best regards,

    Charlie

  • Currently I'm able to request a subset of the default ciphersuites, which is a step in the right direction.  The suite that I want to use isn't in that list though.  Looking in ssl_cipersuites.c I see that I need (at least) CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED

    although this depends on CONFIG_MBEDTLS_RSA_C and CONFIG_MBEDTLS_PKCS1_V15, and ultimately on CONFIG_MBEDTLS_LEGACY_CRYPTO_C.  The last of these breaks OpenThread.

    I see that this is a reversal of the situation described here
    PSA crypto features not enabled when CONFIG_MBEDTLS_LEGACY_CRYPTO_C is enabled
    where CONFIG_MBEDTLS_LEGACY_CRYPTO_C used to be required by OT.

    It's my intention to use PSA throughout, so I have CONFIG_OPENTHREAD_CRYPTO_PSA and CONFIG_MBEDTLS_PSA_CRYPTO_C and a few CONFIG_PSA_WANT... so I'm not clear on why I would need LEGACY_CRYPTO_C - are you able to shed any light on this?

  • CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED dependencies are listed here: Kconfig search — Kconfig reference (nordicsemi.com)

    According to the NCS v2.6.0 release notes:

    "The default cryptography backend for Thread is now Arm PSA Crypto API instead of Mbed TLS, which was used in earlier versions. You can still build all examples with deprecated Mbed TLS support by setting the CONFIG_OPENTHREAD_NRF_SECURITY_CHOICE Kconfig option to y, but you must build the Thread libraries from sources. To inherit Thread certification from Nordic Semiconductor, you must use the PSA Crypto API backend."

    The tcat command in CLI sample actually enables support for Thread commissioning over authenticated TLS.

  • I looked at the CLI sample again and found that I could request CONFIG_MBEDTLS_LEGACY_CRYPTO_C without breaking OpenThread.  I noticed that the CLI example was built with SDK version 2.5.1 rather than 2.6.0 that I'm using for the project I'm working on.  Dropping back to 2.5.1 in my own project appears to resolve the problem of breaking OpenThread, which is a step forward, but for some reason the TLS negotiation is no longer working - MQTT opens the TCP port but no 'client hello' packet is sent.  I'll continue to investigate that.

  • Thanks for your patience, I've been dealing with some other matters for a few days.

    Looking at the CLI example some more, the default configuration opens a TCP connection and then attempts TLS negotiation with the default ciphersuites (using SDK2.5.1).  However, when I set CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y it seems to break - the initial TCP connection packet should just have the SYN flag set but with LEGACY_C it has SYN, ECN and CWR according to Wireshark, and there's no response from the server.

    I know from this post  PSA crypto features not enabled when CONFIG_MBEDTLS_LEGACY_CRYPTO_C is enabled that specifying LEGACY_C causes some PSA functionality to be lost.  Given that the legacy APIs are deprecated it makes sense that I would aim not to use them but should use the PSA APIs, and logically I'd use SDK 2.6.0 where OpenThread uses PSA too.

    So I'm back to the problem of wanting to specify one additional RSA-based cipersuite in addition to those that OT needs.  As far as I can see (please tell me if I'm wrong) I should be able to use the precompiled openThread library provided that I also provide a PSA suite that at least satisfies OT.

    Since I need an RSA-based cipersuite, is it essential to enable the legacy APIs (which the dependency tree seems to suggest) or is there another way to do this?

Related