This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Connecting device to AWS IoT Core (aws_fota)

I've been trying to connect my device to AWS IoT for a week, but I'm getting the same error "no matter what" I do (ERROR: mqtt_connect -45), which seemingly is an authorization issue of some kind?

Here are the exact steps I'm doing to connect my device:

  1. Register my thing in AWS IoT Core.
    1. I register a single thing
    2. I create a certificate using one-click certificate creation, I download the public key, private key, the Amazon Root CA 1, and I click activate.
    3. I attach a policy matching the one given in https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/nrf9160/aws_fota/README.html
  2. I load the project and configure my device
    1. I load the project from Open nRF Connect SDK Project (using the fw-nrfconnect-nrf v1.0.0)
      1. CMakeLists.txt -> ncs/nrf/samples/nrf9160/aws_fota/CMakeLists.txt
      2. Board directory -> ncs/zephyr/boards/arm/nrf9160_pca10090
      3. Board name -> nrf9160_pca10090ns
      4. Build directory -> ncs/nrf/samples/nrf9160/aws_fota/build_nrf9160_pca10090ns
    2. I put the contents of the certificates in the certificates.h file. CLOUD_CLIENT_PRIVATE_KEY is the private key, CLOUD_CLIENT_PUBLIC_CERTIFICATE is the public key and CLOUD_CA_CERTIFICATE is Amazon Root CA 1.I go to Project -> Configure nRF Connect SDK Project -> menuconfig
      1. I set the AWS IoT MQTT broker hostname to the URL found in things -> <my-thing-name> -> Interact -> HTTPS
      2. I set the AWS IoT MQTT broker port to 8883
      3. I set the Custom MQTT Client Id to <my-thing-name>
      4. I uncheck Use provisioned certificates
  3. I flash the sample onto the board
    1. I go to Build -> Build and Debug
    2. When the debug screen appears I click the green arrow in the top right corner which runs the program.

This process gives the following output:

LTE Link Connecting ...


LTE Link Connected!

IPv4 Address 0x68e7dd12

client_id: <my-thing-name>


ERROR: mqtt_connect -45

Please help me resolve this as I can't identify which step(s) I'm missing.

Thank you in advance. 

Parents
  • The mqtt_connect: -45 by checking the error codes means operation not supported on the socket. This is usually caused by a misconfiguration of the certificates which are provisioned.

    Unchecking Use provisioned certificates will provide certificates to the security tag selected in the Kconfig. I don't think you need to add the CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES=y option as this would be for the nRF Cloud library.


    From what I can see from your post your problem is probably what you state here CLOUD_CLIENT_PUBLIC_CERTIFICATE is the public key

    This is not your public key, but your public certificate from AWS, the file generated from AWS, is usually formatted in the following form <certificate-set-id>-certificate.pem.crt this file as mentioned before has the  -----BEGIN CERTIFICATE----- at the beginning of the file. The private key file should have a -----BEGIN RSA PRIVATE KEY----- at the beginning, and the file format is usually <certificate-set-id>-private.pem.key.


    It's also important, as mentioned before that you follow the formatting of the certificates.h file by having \n endings at the end of each new line in the certificates.h header file. 

    I do recommend after provisioning your certificates, and you get a successful MQTT connection, that you check the Use provisioned certificates option again. This reduces the tear on the modem flash by not writing the certificates again to the modem. Also, by having the option unchecked, your certificates will be stored in the firmware image and when flashed in the flash of the device. By re-enabling the option, you avoid both these problems Slight smile

  • Thank you for the in-depth answer, the problem was indeed that I was using the public key instead of the certificate. Now I am, however, receiving two more error codes "MQTT connect failed -61" and "ERROR: mqtt_connect -12" when I try to connect. Do you have any idea what the cause of this might be? I remember seeing a more descriptive list of the error codes somewhere, but I'm not able to find it again.

    Also, I'm not sure if this is a version-thing, but the "CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES" option is nowhere to be found in my sample (aws_fota v1.0.0), I only find "CONFIG_USE_PROVISIONED_CERTIFICATES".

  • What I tried to say is that you don't need the CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES

    The error you get is described as ECONNREFUSED 61 /* Connection refused */ meaning the MQTT endpoint you tried to connect to refused your connection request. I would guess that what you set as the AWS IoT MQTT broker hostname is wrong.

    Not sure why you get -12 ENOMEM but I assume it's because a resource is already in use and you can't have 2 MQTT instances with TLS at the same as there is not enough memory on the device to handle it(This is just an assumption)


    I've found it easiest to find the host name by going to the test panel of the AWS IoT console. Then click on the name of the console usually something like (Connected as iotconsole-1570880786449-0) and choose view endpoint

Reply
  • What I tried to say is that you don't need the CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES

    The error you get is described as ECONNREFUSED 61 /* Connection refused */ meaning the MQTT endpoint you tried to connect to refused your connection request. I would guess that what you set as the AWS IoT MQTT broker hostname is wrong.

    Not sure why you get -12 ENOMEM but I assume it's because a resource is already in use and you can't have 2 MQTT instances with TLS at the same as there is not enough memory on the device to handle it(This is just an assumption)


    I've found it easiest to find the host name by going to the test panel of the AWS IoT console. Then click on the name of the console usually something like (Connected as iotconsole-1570880786449-0) and choose view endpoint

Children
  • The MQTT broker hostname was already found where you described. I tried adding it once more just to eliminate the possibility of typos, but I'm still getting the same errors. The correct port is 8883, right?

    Also when the thing was added to AWS IoT, a username and password was created, should these pieces of information be added somewhere, maybe?

  • Maybe attach a policy to your certificates which looks like this  https://raw.githubusercontent.com/nRFCloud/device-simulator-v2/saga/data/policy.json could help.

    Also, double-check that Client Id = Thing name and that your certificates are connected to that specific name. It could also be that you have malformed the certificates in the certificates.h file. It's important to not add any additional information to the strings except \n. So you get something which looks like

    #define MY_CERT \
    "-----BEGIN RSA PRIVATE KEY-----\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "CERT_DATA_BASE64_INFO_IS_HERE/DEADC0DEDEADC0DEDEADC0DE\n"\
    "-----END RSA PRIVATE KEY-----\n"

    If that does not work I would try to debug by testing that the certificates work with the AWS Python SDK https://docs.aws.amazon.com/greengrass/latest/developerguide/IoT-SDK.html if you know python. They also have bindings for JS, Java, and C++ but the python and JS are the simplest ones to get up and running with certificates.

  • Just tried connecting with the DeviceClass example for JS https://github.com/aws/aws-iot-device-sdk-js and it worked like a charm. Both publishing and receiving messages.

    Can't see that I've made any mistakes entering the information from the certificates either, as this would be the only logical point of failure as far as I know. Not sure where to go from here...

    But maybe it's not a certificate error, since the error code changed when I added the correct public certificate, instead of the public key earlier?

  • I'm a bit out of ideas then, if the port, host, clientId, and certificates worked with the IoT SDK, it means that your AWS IoT setup is correct, so that leaves only the setup on the device. So I would make sure the client ID, host, and certificates are correctly setup on the device.

    It could still be a certificate error. Not getting -45 only means that the input is valid, meaning you stored something that looks like a CA in the CA slot in the modem (same goes for the rest). Unfortunately, it can't tell you if what you are given is more than a valid cert. So the ECONNREFUSED 61 could mean that the certificates contain some information that the server did not expect, meaning the one/some of the certificates could have been mangled in the certificates.h file when you wrote them to the modem. I recommend maybe trying to ensure the formating and that no extra characters have been added to it.

Related