510#include "mqtt_agent_task.h"
511#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
512#include "shadow_device_task.h"
514#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
515#include "ota_update_task.h"
517#if defined(ENABLE_PROVISIONING_APP) && ENABLE_PROVISIONING_APP
518#include "fleet_provisioning_task.h"
520#include "sntp_client.h"
521#include "core_json.h"
526#define NTP_MIN_TIMEOUT 3000
528#define NTP_MIN_BACKOFF 60000
530#define NTP_MIN_BACKOFF_JITTER 3000
532#define NTP_MAX_BACKOFF_JITTER 60000
553#define SHADOW_PUBLISH_JSON \
560 "\"clientToken\":\"%06lu\"" \
563#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
572void ota_preupdate_callback(
void)
575 printf(
"An OTA update has been triggered, downloading the file in the background...\n");
595void ota_postupdate_callback(
const char *update_file,
int status)
601 printf(
"OTA Update completed successfully\n");
605 printf(
"OTA Update failed with error code %d\n", status);
610#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
613static uint32_t ulCurrentPowerOnState = 0;
616static uint32_t ulDesiredPowerOnState = 0;
619struct mmosal_sem *state_change_sem = NULL;
628void shadow_update_callback(
char *json,
size_t json_len,
629 enum shadow_update_status status)
632 int result = JSON_Validate(json, json_len);
634 if (result != JSONSuccess)
636 printf(
"ERR:Invalid JSON document received\n");
640 static uint32_t ulCurrentVersion = 0;
641 char *pcOutValue = NULL;
642 uint32_t ulOutValueLength = 0UL;
643 uint32_t ulVersion = 0;
668 result = JSON_Search(json, json_len,
669 "version", strlen(
"version"),
671 (
size_t *)&ulOutValueLength);
673 if (result != JSONSuccess)
675 printf(
"ERR:Version field not found in JSON document\n");
679 ulVersion = (uint32_t)strtoul(pcOutValue, NULL, 10);
681 if (ulVersion <= ulCurrentVersion)
687 printf(
"ERR:Received unexpected delta update with version %u, "
688 "current version is %u\n",
689 (
unsigned int)ulVersion,
690 (
unsigned int)ulCurrentVersion);
694 ulCurrentVersion = ulVersion;
697 result = JSON_Search(json, json_len,
699 sizeof(
"state.powerOn") - 1,
701 (
size_t *)&ulOutValueLength);
703 if (result != JSONSuccess)
705 printf(
"ERR:powerOn field not found in JSON document\n");
710 ulDesiredPowerOnState = (uint32_t)strtoul(pcOutValue, NULL, 10);
717 case UPDATE_ACCEPTED:
748 case UPDATE_REJECTED:
759 result = JSON_Search(json, json_len,
763 (
size_t *)&ulOutValueLength);
766 ulCode = (uint32_t)strtoul(pcOutValue, NULL, 10);
768 printf(
"ERR:Received rejected response code %lu\n",
772 result = JSON_Search(json, json_len,
774 sizeof(
"message") - 1,
776 (
size_t *)&ulOutValueLength);
777 printf(
" Message: %.*s\n", (
int)ulOutValueLength, pcOutValue);
788void aws_shadow_loop(
char *shadow_name)
794 if (ulDesiredPowerOnState == 1)
797 printf(
"INF:Setting powerOn state to 1.\n");
799 ulCurrentPowerOnState = ulDesiredPowerOnState;
801 else if (ulDesiredPowerOnState == 0)
804 printf(
"INF:Setting powerOn state to 0.\n");
806 ulCurrentPowerOnState = ulDesiredPowerOnState;
811 printf(
"ERR:Invalid power state %lu requested.\n", ulDesiredPowerOnState);
815 printf(
"INF:Reporting change in PowerOn state to %lu.\n", ulCurrentPowerOnState);
821 (void)memset(UpdateDocument, 0x00,
sizeof(UpdateDocument));
823 ulCurrentPowerOnState, ulClientToken);
826 aws_publish_shadow(shadow_name, UpdateDocument);
828 printf(
"INF:Publishing to /update with following client token %lu.\n", ulClientToken);
839 printf(
"\n\nMorse AWS IoT Demo (Built " __DATE__
" " __TIME__
")\n\n");
846 char sntp_server[64];
847 strncpy(sntp_server,
"0.pool.ntp.org",
sizeof(sntp_server));
855 printf(
"Current Time (UTC) is : %s\r\n", ctime(&now));
858 start_mqtt_agent_task();
861 char *shadow_name = NULL;
867#if defined(ENABLE_PROVISIONING_APP) && ENABLE_PROVISIONING_APP
872 printf(
"Initiating fleet provisioning...\n");
873 do_fleet_provisioning();
874 printf(
"Failed to provision device, unable to continue.\n"
875 "Please see getting started guide on how to provision.\n");
879 printf(
"Device is not provisioned, "
880 "please see getting started guide on how to provision.\n");
884#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
886 start_ota_update_task(ota_preupdate_callback, ota_postupdate_callback);
889#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
893 aws_create_shadow(shadow_name, shadow_update_callback);
894 aws_shadow_loop(shadow_name);
#define NTP_MIN_BACKOFF_JITTER
Minimum back-off jitter per attempt.
#define NTP_MIN_TIMEOUT
Minimum NTP timeout per attempt.
#define SHADOW_PUBLISH_JSON
Format string representing a Shadow document with a "reported" state.
#define NTP_MIN_BACKOFF
We need to back-off at least 60 seconds or most NTP Servers will tell us to go away.
void app_init(void)
Main entry point to the application.
#define NTP_MAX_BACKOFF_JITTER
Maximum back-off jitter per attempt.
Contains the configuration parameters for the AWS IoT application.
#define AWS_KEY_PROVISIONING_TEMPLATE
The config store key storing the fleet provisioning template name.
#define MAX_JSON_LEN
Maximum length of JSON strings.
#define AWS_KEY_SHADOW_NAME
The config store key storing the AWS shadow name.
#define AWS_KEY_THING_NAME
The config store key storing the thing name, if not found it is assumed the device needs provisioning...
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
int mmconfig_alloc_and_load(const char *key, void **data)
Allocates memory and loads the data from persistent memory into it returning a pointer.
#define LED_OFF
A value of 0 turns OFF an LED.
void mmhal_set_led(uint8_t led, uint8_t level)
Set the specified LED to the requested level.
time_t mmhal_get_time(void)
Returns the time of day as set in the RTC.
#define LED_ON
A value of 255 turns an LED ON fully.
bool mmosal_sem_give(struct mmosal_sem *sem)
Give a counting semaphore.
struct mmosal_sem * mmosal_sem_create(unsigned max_count, unsigned initial_count, const char *name)
Create a new counting semaphore.
bool mmosal_sem_wait(struct mmosal_sem *sem, uint32_t timeout_ms)
Wait for a counting semaphore.
uint32_t mmosal_get_time_ticks(void)
Get the system time in ticks.
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_wlan_init(void)
Initializes the WLAN interface (and dependencies) using settings specified in the config store.
void app_wlan_start(void)
Starts the WLAN interface and connects to Wi-Fi using settings specified in the config store.