AWS IoT
The Amazon Web Services Internet-of-Things (AWS IoT) library enables applications to connect to, and exchange messages with the AWS IoT Core service. The library supports the following technologies:
TLS secured MQTT transmission protocol
Firmware-Over-The-Air (FOTA)
To connect to AWS IoT, complete the following steps:
See AWS IoT Developer Guide for general information about the Amazon Web Services IoT service.
Set up your AWS account and permissions
To connect to AWS IoT, you need to set up an AWS account with the appropriate permissions. Complete the steps documented in Set up your AWS account.
Create a Thing in AWS IoT
Before you can use this library, you must create a Thing for your client in AWS IoT. The Thing must be connected to a security policy. For testing, you can use a permissive policy, but make sure to update the policy to be more restrictive before you go into production. See AWS IoT Developer Guide: Basic Policy Variables and AWS IoT Developer Guide: Security Best Practices for more information about policies.
To create a Thing for your device:
Log in to the AWS IoT console.
Go to Security > Policies and select Create policy.
Enter a name and define your policy. For testing purposes, you can use the following policy (click on JSON, copy, and paste it):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:*", "Resource": "*" } ] }
Note
The policy example is only intended for development environments. All devices in your production fleet must have credentials with privileges that authorize only intended actions on specific resources. The specific permission policies can vary depending on the use case and should meet business and security requirements. For more information, refer to the example policies listed in AWS IoT Core policy examples and Security best practices in AWS IoT Core.
Click Create.
Go to Manage > All devices> Things and select Create things.
Click Create Thing.
Enter a name. The default name used by the library is
my-thing
.Note
If you are working with an application, that automatically sets the client ID to the IMEI of the device at run-time, you must locate the IMEI of the device and use that as the Thing name. If you choose a different name, make sure to configure a custom client ID before building.
Accept the defaults and continue to the next step.
Select Auto-generate a new certificate to generate new certificates.
Select the policy that you created in a previous step.
Click on Create Thing.
Download the following certificates and keys for later use:
Thing certificate (
*-certificate.pem.crt
)The private key (
*.private.pem.key
)The root CA (choose the Amazon Root CA 1,
AmazonRootCA1.pem
)
Click Done.
The certificates that you created or added for your Thing in AWS IoT must be stored on your device so that it can successfully connect to AWS IoT.
Provisioning of the certificates
To provision the certificates and the private key to the nRF9160 modem, complete the following steps:
Update the modem firmware on the onboard modem of the nRF9160-based device to the latest version by following the steps in Updating the modem firmware.
Build and program the nRF9160: AT Client sample to the nRF9160-based device as explained in Building and programming an application.
Launch the LTE Link Monitor application, which is part of nRF Connect for Desktop.
Click CERTIFICATE MANAGER located at the upper right corner.
Copy the server root certificate into the
CA certificate
entry.Copy and paste the device certificate and the private key into the respective entries (
Client certificate
,Private key
).Select a desired security tag (any positive integer in the range of 0 to 2147483647) and click Update certificates.
Important
The default security tag set by the CERTIFICATE MANAGER 16842753 is reserved for communications with nRF Cloud. Overwriting this security tag entry will require you to flash new certificates if you want to establish a connection to the nRF Cloud.
Configuration
Complete the following steps to set the required library options:
In the AWS IoT console, navigate to IoT core > Settings.
Find the
Device data endpoint
address and setCONFIG_AWS_IOT_BROKER_HOST_NAME
to this address string. The address can also be provided at runtime by setting theCONFIG_AWS_IOT_BROKER_HOST_NAME_APP
option. See Setting the AWS host name at runtime for more details.Set the option
CONFIG_AWS_IOT_CLIENT_ID_STATIC
to the name of the Thing created earlier in the process. This is not needed if the application sets the client ID at run time. If you still want to set a custom client ID, make sure that theCONFIG_AWS_IOT_CLIENT_ID_APP
is disabled and set theCONFIG_AWS_IOT_CLIENT_ID_STATIC
option to your desired client ID.Set the security tag configuration
CONFIG_AWS_IOT_SEC_TAG
to the security tag, chosen while you provisioned the certificates to the modem.
Optional library options
To subscribe to the various AWS IoT Device Shadow Topics, set the following options:
Other options:
Note
If you are using a longer device ID that is either set by the option CONFIG_AWS_IOT_CLIENT_ID_STATIC
or passed in during initialization, it might be required to increase the value of the option CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN
for proper initialization of the library.
Usage
The nRF9160: AWS IoT sample showcases the use of this library and can be used to verify a connection to AWS IoT. To configure and run the sample, complete the steps described in Setup and Building and running.
Initializing the library
The library is initialized by calling the aws_iot_init()
function.
If this API call fails, the application must not make any other API calls to the library.
Connecting to the AWS IoT message broker
After the initialization, the aws_iot_connect()
function must be called to connect to the AWS IoT broker.
If this API call fails, the application must retry the connection by calling aws_iot_connect()
again.
Note
The connection attempt can fail due to several reasons related to the network. Due to this its recommended to implement a routine that tries to reconnect the device upon a disconnect.
During an attempt to connect to the AWS IoT broker, the library tries to establish a connection using a TLS handshake, which usually spans a few seconds.
When the library has established a connection and subscribed to all the configured and passed-in topics, it will propagate the AWS_IOT_EVT_READY
event to signify that the library is ready to be used.
Subscribing to non-AWS specific topics
To subscribe to non-AWS specific topics, complete the following steps:
Specify the number of additional topics that needs to be subscribed to, by setting the
CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT
option.Pass a list containing application specific topics in the
aws_iot_subscription_topics_add()
function, after theaws_iot_init()
function call and before theaws_iot_connect()
function call.
The following code example shows how to subscribe to non-AWS specific topics:
#define CUSTOM_TOPIC_1 "my-custom-topic/example"
#define CUSTOM_TOPIC_2 "my-custom-topic/example2"
const struct aws_iot_topic_data topics_list[2] = {
[0].str = CUSTOM_TOPIC_1,
[0].len = strlen(CUSTOM_TOPIC_1),
[1].str = CUSTOM_TOPIC_2,
[1].len = strlen(CUSTOM_TOPIC_2)
};
err = aws_iot_subscription_topics_add(topics_list, ARRAY_SIZE(topics_list));
if (err) {
LOG_ERR("aws_iot_subscription_topics_add, error: %d", err);
return err;
}
err = aws_iot_init(NULL, aws_iot_event_handler);
if (err) {
LOG_ERR("AWS IoT library could not be initialized, error: %d", err);
return err;
}
Publishing to non-AWS specific topics
To publish to a non-AWS specific topic, complete the following steps:
Populate a
aws_iot_topic_data
with the custom topics that you want to publish to. It is not necessary to set the topic type when populating theaws_iot_topic_data
structure. This type is reserved for AWS IoT shadow topics.Pass in the entry that corresponds to the topic that the payload is to be published to in the message structure
aws_iot_data
. This structure is then passed into theaws_iot_send()
function.
The following code example shows how to publish to non-AWS specific topics:
#define MY_CUSTOM_TOPIC_1 "my-custom-topic/example"
#define MY_CUSTOM_TOPIC_1_IDX 0
static struct aws_iot_topic_data pub_topics[1] = {
[MY_CUSTOM_TOPIC_1_IDX].str = MY_CUSTOM_TOPIC_1,
[MY_CUSTOM_TOPIC_1_IDX].len = strlen(MY_CUSTOM_TOPIC_1),
};
struct aws_iot_data msg = {
/* Pointer to payload */
.ptr = buf,
/* Length of payload */
.len = len,
/* Message ID , if not set it will be provided by the AWS IoT library */
.message_id = id,
/* Quality of Service level */
.qos = MQTT_QOS_0_AT_MOST_ONCE,
/* "my-custom-topic/example" */
.topic = pub_topics[MY_CUSTOM_TOPIC_1_IDX]
};
err = aws_iot_send(&msg);
if (err) {
LOG_ERR("aws_iot_send, error: %d", err);
return err;
}
Setting client ID at run-time
The AWS IoT library also supports passing in the client ID at run time.
To enable this feature, set the client_id
entry in the aws_iot_config
structure that is passed in the aws_iot_init()
function when initializing the library, and set the CONFIG_AWS_IOT_CLIENT_ID_APP
Kconfig option.
Setting the AWS host name at runtime
The AWS IoT library also supports passing the endpoint address at runtime by setting the CONFIG_AWS_IOT_BROKER_HOST_NAME_APP
option.
If this option is set, the host_name
and host_name_len
must be set in the aws_iot_config
structure before it is passed into the aws_iot_init()
function.
The length of your AWS host name (CONFIG_AWS_IOT_BROKER_HOST_NAME
) must be shorter than the default value of CONFIG_AWS_IOT_BROKER_HOST_NAME_MAX_LEN
, for proper initialization of the library.
Testing and debugging
If you have issues with the library or sample, refer to Testing and debugging an application.
Troubleshooting
For issues related to the library and nRF Connect SDK in general, refer to Known issues.
AWS FOTA
The library automatically includes and enables support for FOTA using the AWS FOTA library. To create a FOTA job, refer to the AWS FOTA documentation.
API documentation
include/net/aws_iot.h
subsys/net/lib/aws_iot/src/
- group aws_iot
Library to connect the device to the AWS IoT message broker.
Typedefs
-
typedef void (*aws_iot_evt_handler_t)(const struct aws_iot_evt *evt)
AWS IoT library asynchronous event handler.
- Param evt
[in] The event and any associated parameters.
Enums
-
enum aws_iot_shadow_topic_type
AWS IoT shadow topics, used in messages to specify which shadow topic that will be published to.
Values:
-
enumerator AWS_IOT_SHADOW_TOPIC_NONE
Unused default value.
-
enumerator AWS_IOT_SHADOW_TOPIC_GET
This topic type corresponds to $aws/things/<thing-name>/shadow/get, publishing an empty message to this topic requests the device shadow document.
-
enumerator AWS_IOT_SHADOW_TOPIC_UPDATE
This topic type corresponds to $aws/things/<thing-name>/shadow/update, publishing data to this topic updates the device shadow document.
-
enumerator AWS_IOT_SHADOW_TOPIC_DELETE
This topic type corresponds to $aws/things/<thing-name>/shadow/delete, publishing an empty message to this topic deletes the device Shadow document.
-
enumerator AWS_IOT_SHADOW_TOPIC_NONE
-
enum aws_disconnect_result
@ AWS broker disconnect results.
Values:
-
enumerator AWS_IOT_DISCONNECT_USER_REQUEST
-
enumerator AWS_IOT_DISCONNECT_CLOSED_BY_REMOTE
-
enumerator AWS_IOT_DISCONNECT_INVALID_REQUEST
-
enumerator AWS_IOT_DISCONNECT_MISC
-
enumerator AWS_IOT_DISCONNECT_COUNT
-
enumerator AWS_IOT_DISCONNECT_USER_REQUEST
-
enum aws_connect_result
AWS broker connect results.
Values:
-
enumerator AWS_IOT_CONNECT_RES_SUCCESS
-
enumerator AWS_IOT_CONNECT_RES_ERR_NOT_INITD
-
enumerator AWS_IOT_CONNECT_RES_ERR_INVALID_PARAM
-
enumerator AWS_IOT_CONNECT_RES_ERR_NETWORK
-
enumerator AWS_IOT_CONNECT_RES_ERR_BACKEND
-
enumerator AWS_IOT_CONNECT_RES_ERR_MISC
-
enumerator AWS_IOT_CONNECT_RES_ERR_NO_MEM
-
enumerator AWS_IOT_CONNECT_RES_ERR_PRV_KEY
-
enumerator AWS_IOT_CONNECT_RES_ERR_CERT
-
enumerator AWS_IOT_CONNECT_RES_ERR_CERT_MISC
-
enumerator AWS_IOT_CONNECT_RES_ERR_TIMEOUT_NO_DATA
-
enumerator AWS_IOT_CONNECT_RES_ERR_ALREADY_CONNECTED
-
enumerator AWS_IOT_CONNECT_RES_SUCCESS
-
enum aws_iot_evt_type
AWS IoT notification event types, used to signal the application.
Values:
-
enumerator AWS_IOT_EVT_CONNECTING
Connecting to AWS IoT broker.
-
enumerator AWS_IOT_EVT_CONNECTED
Connected to AWS IoT broker.
-
enumerator AWS_IOT_EVT_READY
AWS IoT library has subscribed to all configured topics.
-
enumerator AWS_IOT_EVT_DISCONNECTED
Disconnected to AWS IoT broker.
-
enumerator AWS_IOT_EVT_DATA_RECEIVED
Data received from AWS message broker.
-
enumerator AWS_IOT_EVT_PUBACK
Acknowledgment for data sent to AWS IoT.
-
enumerator AWS_IOT_EVT_PINGRESP
Acknowledgment for pings sent to AWS IoT.
-
enumerator AWS_IOT_EVT_FOTA_START
FOTA update start.
-
enumerator AWS_IOT_EVT_FOTA_DONE
FOTA update done, request to reboot.
-
enumerator AWS_IOT_EVT_FOTA_ERASE_PENDING
FOTA erase pending.
-
enumerator AWS_IOT_EVT_FOTA_ERASE_DONE
FOTA erase done.
-
enumerator AWS_IOT_EVT_FOTA_DL_PROGRESS
FOTA progress notification.
-
enumerator AWS_IOT_EVT_FOTA_ERROR
FOTA error. Used to propagate FOTA-related errors to the application. This is to distinguish between AWS_IOT irrecoverable errors and FOTA errors, so they can be handled differently.
-
enumerator AWS_IOT_EVT_ERROR
AWS IoT library irrecoverable error.
-
enumerator AWS_IOT_EVT_CONNECTING
Functions
-
int aws_iot_init(const struct aws_iot_config *const config, aws_iot_evt_handler_t event_handler)
Initialize the module.
Note
This API must be called exactly once, and it must return successfully.
- Parameters
config – [in] Pointer to struct containing connection parameters.
event_handler – [in] Pointer to event handler to receive AWS IoT module events.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_connect(struct aws_iot_config *const config)
Connect to the AWS IoT broker.
This function exposes the MQTT socket to main so that it can be polled on.
- Parameters
config – [out] Pointer to struct containing connection parameters, the MQTT connection socket number will be copied to the socket entry of the struct.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_disconnect(void)
Disconnect from the AWS IoT broker.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_send(const struct aws_iot_data *const tx_data)
Send data to AWS IoT broker.
- Parameters
tx_data – [in] Pointer to struct containing data to be transmitted to the AWS IoT broker.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_input(void)
Get data from AWS IoT broker.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_ping(void)
Ping AWS IoT broker. Must be called periodically to keep connection to broker alive.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
int aws_iot_subscription_topics_add(const struct aws_iot_topic_data *const topic_list, size_t list_count)
Add a list of application specific topics that will be subscribed to upon connection to AWS IoT broker.
- Parameters
topic_list – [in] Pointer to list of topics.
list_count – [in] Number of entries in the list.
- Returns
0 If successful. Otherwise, a (negative) error code is returned.
-
struct aws_iot_topic_data
- #include <aws_iot.h>
AWS IoT topic data.
Public Members
-
enum aws_iot_shadow_topic_type type
Optional: type of shadow topic that will be published to. When publishing to a shadow topic this can be set instead of the application specific topic below.
-
const char *str
Pointer to string of application specific topic.
-
size_t len
Length of application specific topic.
-
enum aws_iot_shadow_topic_type type
-
struct aws_iot_app_topic_data
- #include <aws_iot.h>
Structure used to declare a list of application specific topics passed in by the application.
Public Members
-
struct mqtt_topic list[CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT]
List of application specific topics.
-
size_t list_count
Number of entries in topic list.
-
struct mqtt_topic list[CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT]
-
struct aws_iot_data
- #include <aws_iot.h>
AWS IoT transmission data.
Public Members
-
struct aws_iot_topic_data topic
Topic data is sent/received on.
-
char *ptr
Pointer to data sent/received from the AWS IoT broker.
-
size_t len
Length of data.
-
uint16_t message_id
Message id, used to match acknowledgments.
-
uint8_t dup_flag
Duplicate flag. 1 indicates the message is a retransmission, Usually triggered by missing publication acknowledgment.
-
uint8_t retain_flag
Retain flag. 1 indicates to AWS IoT that the message should be stored persistently.
-
struct aws_iot_topic_data topic
-
struct aws_iot_evt
- #include <aws_iot.h>
Struct with data received from AWS IoT broker.
Public Members
-
enum aws_iot_evt_type type
Type of event.
-
int fota_progress
FOTA progress in percentage.
-
enum aws_iot_evt_type type
-
struct aws_iot_config
- #include <aws_iot.h>
Structure for AWS IoT broker connection parameters.
Public Members
-
int socket
Socket for AWS IoT broker connection
-
char *client_id
Client id for AWS IoT broker connection, used when
CONFIG_AWS_IOT_CLIENT_ID_APP
is set. If not set an internal configurable static client id is used.
-
size_t client_id_len
Length of client_id string.
-
char *host_name
AWS IoT endpoint host name for broker connection, used when
CONFIG_AWS_IOT_BROKER_HOST_NAME_APP
is set. If not the staticAWS_IOT_BROKER_HOST_NAME
is used.
-
size_t host_name_len
Length of host_name string.
-
int socket
-
typedef void (*aws_iot_evt_handler_t)(const struct aws_iot_evt *evt)