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

nRF9160: AWS IoT Sample Application

Hi,

I am trying to run the nRF9160 AWS IoT sample - https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/nrf9160/aws_iot/README.html on an nRF9160 DK, but have had no luck. I have done all setup, but the code fails during AWS IoT initialisation:

*** Booting Zephyr OS build v2.4.0-ncs1  ***
The AWS IoT sample started, version: v1.0.0
E: aws_topics_populate, error: -12
AWS IoT library could not be initialized, error: -12

I have inspected the call stack, and noticed that aws_topics_populate is called by aws_iot_init, which in turn is called from main.c as follows:

err = aws_iot_init(NULL, aws_iot_event_handler);
if (err) {
	printk("AWS IoT library could not be initialized, error: %d\n", err);
}

From the above, the first argument to the function is NULL, is this expected? I noticed that this maps to the aws_iot_config * parameter inside the function declaration in aws_iot.c, and the argument actually gets used, with failure eventually happening inside aws_topics_populate

I read the AWS IoT library documentation - https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/include/net/aws_iot.html#lib-aws-iot, and encountered the note:

The API requires that a configuration structure aws_iot_config is declared in the application and passed into the aws_iot_init() and aws_iot_connect() functions. This exposes the application to the MQTT socket used for the connection, which is polled on, in the application. It also enables the application to pass in a client id (thingname) at runtime.

I then set out to create an instance of the struct, but couldn't figure out what the socket field should be set to. 

Question: Am I on the right path the and aws_iot_config instance needs to be created for the nRF9160 AWS IoT sample even though the sample documentation doesn't say so explicitly. And if so, how do determine what the socket value should be set to?

The API requires that a configuration structure aws_iot_config is declared 
in the application and passed into the aws_iot_init() and aws_iot_connect() 
functions. This exposes the application to the MQTT socket used for the 
connection, which is polled on, in the application. It also enables the 
application to pass in a client id (thingname) at runtime.

Parents
  • Hi,

    The sample seems to be working for me. I still get an error (when I call getaddrinfo, it does not find the hostname), but that is probably just an error on my end. Anyway, the error I get comes after the point where I should have seen your error, so the call to aws_iot_init returns successfully.

    Looking at the code, the argument is not used in aws_topics_populate, unless you have set CONFIG_AWS_IOT_CLIENT_ID_APP. Do you know which call to snprintf fails in aws_topics_populate.

    As for the note, I think that it is only for when CONFIG_IOT_CLIENT_ID_APP is set. But I agree that the note is confusing, and I will talk to our developers to see if it can be improved.

    The socket will be created and set when you call aws_iot_connect, so you do not need to set that field yourself.

    Best regards,

    Didrik

  • Hi Didrik,

    Thanks for picking this up, and kindly getting back to me.

    I can confirm that CONFIG_AWS_IOT_CLIENT_ID_APP is not set.

    The aws_iot_init implementation is as follows:

    int aws_iot_init(const struct aws_iot_config *const config,
    		 aws_iot_evt_handler_t event_handler)
    {
    	int err;
    
    	if (IS_ENABLED(CONFIG_AWS_IOT_CLIENT_ID_APP) &&
    	    config->client_id_len >= CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN) {
    		LOG_ERR("Client ID string too long");
    		return -EMSGSIZE;
    	}
    
    	if (IS_ENABLED(CONFIG_AWS_IOT_CLIENT_ID_APP) &&
    	    config->client_id == NULL) {
    		LOG_ERR("Client ID not set in the application");
    		return -ENODATA;
    	}
    
    	err = aws_iot_topics_populate(config->client_id, config->client_id_len);
    	if (err) {
    		LOG_ERR("aws_topics_populate, error: %d", err);
    		return err;
    	}
    
    #if defined(CONFIG_AWS_FOTA)
    	err = aws_fota_init(&client, aws_fota_cb_handler);
    	if (err) {
    		LOG_ERR("aws_fota_init, error: %d", err);
    		return err;
    	}
    #endif
    
    	module_evt_handler = event_handler;
    
    	return err;
    }

    so if a NULL argument is passed for aws_iot_config*, config->client_id evaluates to garbage I would assume but as you correctly stated is not used inside aws_iot_topics_populate. 

    I tried debugging into aws_iot_topics_populate to see where the failure is happening but for some reason the debugger won't step into the C function. Here's a screenshot of what I get:

    I thought the reason may be due to optimisations done by the compiler, so I tried the below setting in prj.conf:

    CONFIG_DEBUG_OPTIMIZATIONS=y

    but still couldn't step into the function. In fact, the code seems to crash... please see below:

    Any suggestions / pointers?

Reply
  • Hi Didrik,

    Thanks for picking this up, and kindly getting back to me.

    I can confirm that CONFIG_AWS_IOT_CLIENT_ID_APP is not set.

    The aws_iot_init implementation is as follows:

    int aws_iot_init(const struct aws_iot_config *const config,
    		 aws_iot_evt_handler_t event_handler)
    {
    	int err;
    
    	if (IS_ENABLED(CONFIG_AWS_IOT_CLIENT_ID_APP) &&
    	    config->client_id_len >= CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN) {
    		LOG_ERR("Client ID string too long");
    		return -EMSGSIZE;
    	}
    
    	if (IS_ENABLED(CONFIG_AWS_IOT_CLIENT_ID_APP) &&
    	    config->client_id == NULL) {
    		LOG_ERR("Client ID not set in the application");
    		return -ENODATA;
    	}
    
    	err = aws_iot_topics_populate(config->client_id, config->client_id_len);
    	if (err) {
    		LOG_ERR("aws_topics_populate, error: %d", err);
    		return err;
    	}
    
    #if defined(CONFIG_AWS_FOTA)
    	err = aws_fota_init(&client, aws_fota_cb_handler);
    	if (err) {
    		LOG_ERR("aws_fota_init, error: %d", err);
    		return err;
    	}
    #endif
    
    	module_evt_handler = event_handler;
    
    	return err;
    }

    so if a NULL argument is passed for aws_iot_config*, config->client_id evaluates to garbage I would assume but as you correctly stated is not used inside aws_iot_topics_populate. 

    I tried debugging into aws_iot_topics_populate to see where the failure is happening but for some reason the debugger won't step into the C function. Here's a screenshot of what I get:

    I thought the reason may be due to optimisations done by the compiler, so I tried the below setting in prj.conf:

    CONFIG_DEBUG_OPTIMIZATIONS=y

    but still couldn't step into the function. In fact, the code seems to crash... please see below:

    Any suggestions / pointers?

Children
No Data
Related