Demo application for using the AT&T IoT Starter Kit Powered by AWS.

Dependencies:   SDFileSystem

Fork of ATT_AWS_IoT_demo by Anthony Phillips

IoT Starter Kit Powered by AWS Demo

This program demonstrates the AT&T IoT Starter Kit sending data directly into AWS IoT. It's explained and used in the Getting Started with the IoT Starter Kit Powered by AWS on starterkit.att.com.

What's required

  • AT&T IoT LTE Add-on (also known as the Cellular Shield)
  • NXP K64F - for programming
  • microSD card - used to store your AWS security credentials
  • AWS account
  • Python, locally installed

If you don't already have an IoT Starter Kit, you can purchase a kit here. The IoT Starter Kit Powered by AWS includes the LTE cellular shield, K64F, and a microSD card.

Committer:
ampembeng
Date:
Thu Dec 01 18:05:38 2016 +0000
Revision:
15:6f2798e45099
Child:
18:6370da1de572
Initial commit.  Demo works with both the FRDM wired Ethernet and the Avnet Shield wireless modem.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ampembeng 15:6f2798e45099 1 /*
ampembeng 15:6f2798e45099 2 * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
ampembeng 15:6f2798e45099 3 *
ampembeng 15:6f2798e45099 4 * Licensed under the Apache License, Version 2.0 (the "License").
ampembeng 15:6f2798e45099 5 * You may not use this file except in compliance with the License.
ampembeng 15:6f2798e45099 6 * A copy of the License is located at
ampembeng 15:6f2798e45099 7 *
ampembeng 15:6f2798e45099 8 * http://aws.amazon.com/apache2.0
ampembeng 15:6f2798e45099 9 *
ampembeng 15:6f2798e45099 10 * or in the "license" file accompanying this file. This file is distributed
ampembeng 15:6f2798e45099 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
ampembeng 15:6f2798e45099 12 * express or implied. See the License for the specific language governing
ampembeng 15:6f2798e45099 13 * permissions and limitations under the License.
ampembeng 15:6f2798e45099 14 */
ampembeng 15:6f2798e45099 15 #ifndef AWS_IOT_SDK_SRC_IOT_SHADOW_H_
ampembeng 15:6f2798e45099 16 #define AWS_IOT_SDK_SRC_IOT_SHADOW_H_
ampembeng 15:6f2798e45099 17
ampembeng 15:6f2798e45099 18
ampembeng 15:6f2798e45099 19 /**
ampembeng 15:6f2798e45099 20 * @file aws_iot_shadow_interface.h
ampembeng 15:6f2798e45099 21 * @brief Interface for thing shadow
ampembeng 15:6f2798e45099 22 *
ampembeng 15:6f2798e45099 23 * These are the functions and structs to manage/interact the Thing Shadow(in the cloud).
ampembeng 15:6f2798e45099 24 * This SDK will let you interact with your own thing shadow or any other shadow using its Thing Name.
ampembeng 15:6f2798e45099 25 * There are totally 3 actions a device can perform on the shadow - Get, Update and Delete.
ampembeng 15:6f2798e45099 26 *
ampembeng 15:6f2798e45099 27 * Currently the device should use MQTT/S underneath. In the future this will also support other protocols. As it supports MQTT, the shadow needs to connect and disconnect.
ampembeng 15:6f2798e45099 28 * It will also work on the pub/sub model. On performing any action, the acknowledgment will be received in either accepted or rejected. For Example:
ampembeng 15:6f2798e45099 29 * If we want to perform a GET on the thing shadow the following messages will be sent and received:
ampembeng 15:6f2798e45099 30 * 1. A MQTT Publish on the topic - $aws/things/{thingName}/shadow/get
ampembeng 15:6f2798e45099 31 * 2. Subscribe to MQTT topics - $aws/things/{thingName}/shadow/get/accepted and $aws/things/{thingName}/shadow/get/rejected.
ampembeng 15:6f2798e45099 32 * If the request was successful we will receive the things json document in the accepted topic.
ampembeng 15:6f2798e45099 33 *
ampembeng 15:6f2798e45099 34 *
ampembeng 15:6f2798e45099 35 */
ampembeng 15:6f2798e45099 36 #include "aws_iot_mqtt_interface.h"
ampembeng 15:6f2798e45099 37 #include "aws_iot_shadow_json_data.h"
ampembeng 15:6f2798e45099 38
ampembeng 15:6f2798e45099 39 /*!
ampembeng 15:6f2798e45099 40 * @brief Shadow Connect parameters
ampembeng 15:6f2798e45099 41 *
ampembeng 15:6f2798e45099 42 * As the Shadow SDK uses MQTT underneath, it could be connected and disconnected on events to save some battery.
ampembeng 15:6f2798e45099 43 * @note Always use the \c ShadowParametersDefault to initialize this struct
ampembeng 15:6f2798e45099 44 *
ampembeng 15:6f2798e45099 45 *
ampembeng 15:6f2798e45099 46 *
ampembeng 15:6f2798e45099 47 */
ampembeng 15:6f2798e45099 48 typedef struct {
ampembeng 15:6f2798e45099 49 char *pMyThingName; ///< Every device has a Thing Shadow and this is the placeholder for name
ampembeng 15:6f2798e45099 50 char *pMqttClientId; ///< Currently the Shadow uses MQTT to connect and it is important to ensure we have unique client id
ampembeng 15:6f2798e45099 51 char *pHost; ///< This will be unique to a customer and can be retrieved from the console
ampembeng 15:6f2798e45099 52 int port; ///< By default the port is 8883
ampembeng 15:6f2798e45099 53 char *pRootCA; ///< Location with the Filename of the Root CA
ampembeng 15:6f2798e45099 54 char *pClientCRT; ///< Location of Device certs signed by AWS IoT service
ampembeng 15:6f2798e45099 55 char *pClientKey; ///< Location of Device private key
ampembeng 15:6f2798e45099 56 } ShadowParameters_t;
ampembeng 15:6f2798e45099 57
ampembeng 15:6f2798e45099 58 /*!
ampembeng 15:6f2798e45099 59 * @brief This is set to defaults from the configuration file
ampembeng 15:6f2798e45099 60 * The certs are set to NULL because they need the path to the file. shadow_sample.c file demonstrates on how to get the relative path
ampembeng 15:6f2798e45099 61 *
ampembeng 15:6f2798e45099 62 * \relates ShadowParameters_t
ampembeng 15:6f2798e45099 63 */
ampembeng 15:6f2798e45099 64 extern const ShadowParameters_t ShadowParametersDefault;
ampembeng 15:6f2798e45099 65
ampembeng 15:6f2798e45099 66
ampembeng 15:6f2798e45099 67 /**
ampembeng 15:6f2798e45099 68 * @brief Initialize the Thing Shadow before use
ampembeng 15:6f2798e45099 69 *
ampembeng 15:6f2798e45099 70 * This function takes care of initializing the internal book-keeping data structures
ampembeng 15:6f2798e45099 71 *
ampembeng 15:6f2798e45099 72 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 73 * @return An IoT Error Type defining successful/failed Initialization
ampembeng 15:6f2798e45099 74 */
ampembeng 15:6f2798e45099 75 IoT_Error_t aws_iot_shadow_init(MQTTClient_t *pClient);
ampembeng 15:6f2798e45099 76 /**
ampembeng 15:6f2798e45099 77 * @brief Connect to the AWS IoT Thing Shadow service over MQTT
ampembeng 15:6f2798e45099 78 *
ampembeng 15:6f2798e45099 79 * This function does the TLSv1.2 handshake and establishes the MQTT connection
ampembeng 15:6f2798e45099 80 *
ampembeng 15:6f2798e45099 81 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 82 * @param pParams Shadow Conenction parameters like TLS cert location
ampembeng 15:6f2798e45099 83 * @return An IoT Error Type defining successful/failed Connection
ampembeng 15:6f2798e45099 84 */
ampembeng 15:6f2798e45099 85 IoT_Error_t aws_iot_shadow_connect(MQTTClient_t *pClient, ShadowParameters_t *pParams);
ampembeng 15:6f2798e45099 86 /**
ampembeng 15:6f2798e45099 87 * @brief Yield function to let the background tasks of MQTT and Shadow
ampembeng 15:6f2798e45099 88 *
ampembeng 15:6f2798e45099 89 * This function could be use in a separate thread waiting for the incoming messages, ensuring the connection is kept alive with the AWS Service.
ampembeng 15:6f2798e45099 90 * It also ensures the expired requests of Shadow actions are cleared and Timeout callback is executed.
ampembeng 15:6f2798e45099 91 * @note All callbacks ever used in the SDK will be executed in the context of this function.
ampembeng 15:6f2798e45099 92 *
ampembeng 15:6f2798e45099 93 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 94 * @param timeout in milliseconds, This is the maximum time the yield function will wait for a message and/or read the messages from the TLS buffer
ampembeng 15:6f2798e45099 95 * @return An IoT Error Type defining successful/failed Yield
ampembeng 15:6f2798e45099 96 */
ampembeng 15:6f2798e45099 97 IoT_Error_t aws_iot_shadow_yield(MQTTClient_t *pClient, int timeout);
ampembeng 15:6f2798e45099 98 /**
ampembeng 15:6f2798e45099 99 * @brief Disconnect from the AWS IoT Thing Shadow service over MQTT
ampembeng 15:6f2798e45099 100 *
ampembeng 15:6f2798e45099 101 * This will close the underlying TCP connection, MQTT connection will also be closed
ampembeng 15:6f2798e45099 102 *
ampembeng 15:6f2798e45099 103 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 104 * @return An IoT Error Type defining successful/failed disconnect status
ampembeng 15:6f2798e45099 105 */
ampembeng 15:6f2798e45099 106 IoT_Error_t aws_iot_shadow_disconnect(MQTTClient_t *pClient);
ampembeng 15:6f2798e45099 107
ampembeng 15:6f2798e45099 108 /**
ampembeng 15:6f2798e45099 109 * @brief Thing Shadow Acknowledgment enum
ampembeng 15:6f2798e45099 110 *
ampembeng 15:6f2798e45099 111 * This enum type is use in the callback for the action response
ampembeng 15:6f2798e45099 112 *
ampembeng 15:6f2798e45099 113 */
ampembeng 15:6f2798e45099 114 typedef enum {
ampembeng 15:6f2798e45099 115 SHADOW_ACK_TIMEOUT, SHADOW_ACK_REJECTED, SHADOW_ACK_ACCEPTED
ampembeng 15:6f2798e45099 116 } Shadow_Ack_Status_t;
ampembeng 15:6f2798e45099 117
ampembeng 15:6f2798e45099 118 /**
ampembeng 15:6f2798e45099 119 * @brief Thing Shadow Action type enum
ampembeng 15:6f2798e45099 120 *
ampembeng 15:6f2798e45099 121 * This enum type is use in the callback for the action response
ampembeng 15:6f2798e45099 122 *
ampembeng 15:6f2798e45099 123 */
ampembeng 15:6f2798e45099 124 typedef enum {
ampembeng 15:6f2798e45099 125 SHADOW_GET, SHADOW_UPDATE, SHADOW_DELETE
ampembeng 15:6f2798e45099 126 } ShadowActions_t;
ampembeng 15:6f2798e45099 127
ampembeng 15:6f2798e45099 128
ampembeng 15:6f2798e45099 129 /**
ampembeng 15:6f2798e45099 130 * @brief Function Pointer typedef used as the callback for every action
ampembeng 15:6f2798e45099 131 *
ampembeng 15:6f2798e45099 132 * This function will be called from the context of \c aws_iot_shadow_yield() context
ampembeng 15:6f2798e45099 133 *
ampembeng 15:6f2798e45099 134 * @param pThingName Thing Name of the response received
ampembeng 15:6f2798e45099 135 * @param action The response of the action
ampembeng 15:6f2798e45099 136 * @param status Informs if the action was Accepted/Rejected or Timed out
ampembeng 15:6f2798e45099 137 * @param pReceivedJsonDocument Received JSON document
ampembeng 15:6f2798e45099 138 * @param pContextData the void* data passed in during the action call(update, get or delete)
ampembeng 15:6f2798e45099 139 *
ampembeng 15:6f2798e45099 140 */
ampembeng 15:6f2798e45099 141 typedef void (*fpActionCallback_t)(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
ampembeng 15:6f2798e45099 142 const char *pReceivedJsonDocument, void *pContextData);
ampembeng 15:6f2798e45099 143
ampembeng 15:6f2798e45099 144 /**
ampembeng 15:6f2798e45099 145 * @brief This function is the one used to perform an Update action to a Thing Name's Shadow.
ampembeng 15:6f2798e45099 146 *
ampembeng 15:6f2798e45099 147 * update is one of the most frequently used functionality by a device. In most cases the device may be just reporting few params to update the thing shadow in the cloud
ampembeng 15:6f2798e45099 148 * Update Action if no callback or if the JSON document does not have a client token then will just publish the update and not track it.
ampembeng 15:6f2798e45099 149 *
ampembeng 15:6f2798e45099 150 * @note The update has to subscribe to two topics update/accepted and update/rejected. This function waits 2 seconds to ensure the subscriptions are registered before publishing the update message.
ampembeng 15:6f2798e45099 151 * The following steps are performed on using this function:
ampembeng 15:6f2798e45099 152 * 1. Subscribe to Shadow topics - $aws/things/{thingName}/shadow/update/accepted and $aws/things/{thingName}/shadow/update/rejected
ampembeng 15:6f2798e45099 153 * 2. wait for 2 seconds for the subscription to take effect
ampembeng 15:6f2798e45099 154 * 3. Publish on the update topic - $aws/things/{thingName}/shadow/update
ampembeng 15:6f2798e45099 155 * 4. In the \c aws_iot_shadow_yield() function the response will be handled. In case of timeout or if the response is received, the subscription to shadow response topics are un-subscribed from.
ampembeng 15:6f2798e45099 156 * On the contrary if the persistent subscription is set to true then the un-subscribe will not be done. The topics will always be listened to.
ampembeng 15:6f2798e45099 157 *
ampembeng 15:6f2798e45099 158 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 159 * @param pThingName Thing Name of the shadow that needs to be Updated
ampembeng 15:6f2798e45099 160 * @param pJsonString The update action expects a JSON document to send. The JSO String should be a null terminated string. This JSON document should adhere to the AWS IoT Thing Shadow specification. To help in the process of creating this document- SDK provides apis in \c aws_iot_shadow_json_data.h
ampembeng 15:6f2798e45099 161 * @param callback This is the callback that will be used to inform the caller of the response from the AWS IoT Shadow service.Callback could be set to NULL if response is not important
ampembeng 15:6f2798e45099 162 * @param pContextData This is an extra parameter that could be passed along with the callback. It should be set to NULL if not used
ampembeng 15:6f2798e45099 163 * @param timeout_seconds It is the time the SDK will wait for the response on either accepted/rejected before declaring timeout on the action
ampembeng 15:6f2798e45099 164 * @param isPersistentSubscribe As mentioned above, every time if a device updates the same shadow then this should be set to true to avoid repeated subscription and unsubscription. If the Thing Name is one off update then this should be set to false
ampembeng 15:6f2798e45099 165 * @return An IoT Error Type defining successful/failed update action
ampembeng 15:6f2798e45099 166 */
ampembeng 15:6f2798e45099 167 IoT_Error_t aws_iot_shadow_update(MQTTClient_t *pClient, const char *pThingName, char *pJsonString,
ampembeng 15:6f2798e45099 168 fpActionCallback_t callback, void *pContextData, uint8_t timeout_seconds, bool isPersistentSubscribe);
ampembeng 15:6f2798e45099 169
ampembeng 15:6f2798e45099 170 /**
ampembeng 15:6f2798e45099 171 * @brief This function is the one used to perform an Get action to a Thing Name's Shadow.
ampembeng 15:6f2798e45099 172 *
ampembeng 15:6f2798e45099 173 * One use of this function is usually to get the config of a device at boot up.
ampembeng 15:6f2798e45099 174 * It is similar to the Update function internally except it does not take a JSON document as the input. The entire JSON document will be sent over the accepted topic
ampembeng 15:6f2798e45099 175 *
ampembeng 15:6f2798e45099 176 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 177 * @param pThingName Thing Name of the JSON document that is needed
ampembeng 15:6f2798e45099 178 * @param callback This is the callback that will be used to inform the caller of the response from the AWS IoT Shadow service.Callback could be set to NULL if response is not important
ampembeng 15:6f2798e45099 179 * @param pContextData This is an extra parameter that could be passed along with the callback. It should be set to NULL if not used
ampembeng 15:6f2798e45099 180 * @param timeout_seconds It is the time the SDK will wait for the response on either accepted/rejected before declaring timeout on the action
ampembeng 15:6f2798e45099 181 * @param isPersistentSubscribe As mentioned above, every time if a device gets the same Sahdow (JSON document) then this should be set to true to avoid repeated subscription and un-subscription. If the Thing Name is one off get then this should be set to false
ampembeng 15:6f2798e45099 182 * @return An IoT Error Type defining successful/failed get action
ampembeng 15:6f2798e45099 183 */
ampembeng 15:6f2798e45099 184 IoT_Error_t aws_iot_shadow_get(MQTTClient_t *pClient, const char *pThingName, fpActionCallback_t callback,
ampembeng 15:6f2798e45099 185 void *pContextData, uint8_t timeout_seconds, bool isPersistentSubscribe);
ampembeng 15:6f2798e45099 186 /**
ampembeng 15:6f2798e45099 187 * @brief This function is the one used to perform an Delete action to a Thing Name's Shadow.
ampembeng 15:6f2798e45099 188 *
ampembeng 15:6f2798e45099 189 * This is not a very common use case for device. It is generally the responsibility of the accompanying app to do the delete.
ampembeng 15:6f2798e45099 190 * It is similar to the Update function internally except it does not take a JSON document as the input. The Thing Shadow referred by the ThingName will be deleted.
ampembeng 15:6f2798e45099 191 *
ampembeng 15:6f2798e45099 192 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 193 * @param pThingName Thing Name of the Shadow that should be deleted
ampembeng 15:6f2798e45099 194 * @param callback This is the callback that will be used to inform the caller of the response from the AWS IoT Shadow service.Callback could be set to NULL if response is not important
ampembeng 15:6f2798e45099 195 * @param pContextData This is an extra parameter that could be passed along with the callback. It should be set to NULL if not used
ampembeng 15:6f2798e45099 196 * @param timeout_seconds It is the time the SDK will wait for the response on either accepted/rejected before declaring timeout on the action
ampembeng 15:6f2798e45099 197 * @param isPersistentSubscribe As mentioned above, every time if a device deletes the same Sahdow (JSON document) then this should be set to true to avoid repeated subscription and un-subscription. If the Thing Name is one off delete then this should be set to false
ampembeng 15:6f2798e45099 198 * @return An IoT Error Type defining successful/failed delete action
ampembeng 15:6f2798e45099 199 */
ampembeng 15:6f2798e45099 200 IoT_Error_t aws_iot_shadow_delete(MQTTClient_t *pClient, const char *pThingName, fpActionCallback_t callback,
ampembeng 15:6f2798e45099 201 void *pContextData, uint8_t timeout_seconds, bool isPersistentSubscriptions);
ampembeng 15:6f2798e45099 202
ampembeng 15:6f2798e45099 203 /**
ampembeng 15:6f2798e45099 204 * @brief This function is used to listen on the delta topic of #AWS_IOT_MY_THING_NAME mentioned in the aws_iot_config.h file.
ampembeng 15:6f2798e45099 205 *
ampembeng 15:6f2798e45099 206 * Any time a delta is published the Json document will be delivered to the pStruct->cb. If you don't want the parsing done by the SDK then use the jsonStruct_t key set to "state". A good example of this is displayed in the sample_apps/shadow_console_echo.c
ampembeng 15:6f2798e45099 207 *
ampembeng 15:6f2798e45099 208 * @param pClient MQTT Client used as the protocol layer
ampembeng 15:6f2798e45099 209 * @param pStruct The struct used to parse JSON value
ampembeng 15:6f2798e45099 210 * @return An IoT Error Type defining successful/failed delta registering
ampembeng 15:6f2798e45099 211 */
ampembeng 15:6f2798e45099 212 IoT_Error_t aws_iot_shadow_register_delta(MQTTClient_t *pClient, jsonStruct_t *pStruct);
ampembeng 15:6f2798e45099 213
ampembeng 15:6f2798e45099 214 /**
ampembeng 15:6f2798e45099 215 * @brief Reset the last received version number to zero.
ampembeng 15:6f2798e45099 216 * This will be useful if the Thing Shadow is deleted and would like to to reset the local version
ampembeng 15:6f2798e45099 217 * @return no return values
ampembeng 15:6f2798e45099 218 *
ampembeng 15:6f2798e45099 219 */
ampembeng 15:6f2798e45099 220 void aws_iot_shadow_reset_last_received_version(void);
ampembeng 15:6f2798e45099 221 /**
ampembeng 15:6f2798e45099 222 * @brief Version of a document is received with every accepted/rejected and the SDK keeps track of the last received version of the JSON document of #AWS_IOT_MY_THING_NAME shadow
ampembeng 15:6f2798e45099 223 *
ampembeng 15:6f2798e45099 224 * One exception to this version tracking is that, the SDK will ignore the version from update/accepted topic. Rest of the responses will be scanned to update the version number.
ampembeng 15:6f2798e45099 225 * Accepting version change for update/accepted may cause version conflicts for delta message if the update message is received before the delta.
ampembeng 15:6f2798e45099 226 *
ampembeng 15:6f2798e45099 227 * @return version number of the last received response
ampembeng 15:6f2798e45099 228 *
ampembeng 15:6f2798e45099 229 */
ampembeng 15:6f2798e45099 230 uint32_t aws_iot_shadow_get_last_received_version(void);
ampembeng 15:6f2798e45099 231 /**
ampembeng 15:6f2798e45099 232 * @brief Enable the ignoring of delta messages with old version number
ampembeng 15:6f2798e45099 233 *
ampembeng 15:6f2798e45099 234 * As we use MQTT underneath, there could be more than 1 of the same message if we use QoS 0. To avoid getting called for the same message, this functionality should be enabled. All the old message will be ignored
ampembeng 15:6f2798e45099 235 */
ampembeng 15:6f2798e45099 236 void aws_iot_shadow_enable_discard_old_delta_msgs(void);
ampembeng 15:6f2798e45099 237 /**
ampembeng 15:6f2798e45099 238 * @brief Disable the ignoring of delta messages with old version number
ampembeng 15:6f2798e45099 239 */
ampembeng 15:6f2798e45099 240 void aws_iot_shadow_disable_discard_old_delta_msgs(void);
ampembeng 15:6f2798e45099 241
ampembeng 15:6f2798e45099 242 #endif //AWS_IOT_SDK_SRC_IOT_SHADOW_H_
ampembeng 15:6f2798e45099 243