507#include "mmhal_app.h"
512#include "mqtt_agent_task.h"
513#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
514#include "shadow_device_task.h"
516#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
517#include "ota_update_task.h"
519#if defined(ENABLE_PROVISIONING_APP) && ENABLE_PROVISIONING_APP
520#include "fleet_provisioning_task.h"
522#include "sntp_client.h"
523#include "core_json.h"
528#define NTP_MIN_TIMEOUT 3000
530#define NTP_MIN_BACKOFF 60000
532#define NTP_MIN_BACKOFF_JITTER 3000
534#define NTP_MAX_BACKOFF_JITTER 60000
555#define SHADOW_PUBLISH_JSON \
562 "\"clientToken\":\"%06lu\"" \
565#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
574void ota_preupdate_callback(
void)
577 printf(
"An OTA update has been triggered, downloading the file in the background...\n");
597void ota_postupdate_callback(
const char *update_file,
int status)
603 printf(
"OTA Update completed successfully\n");
607 printf(
"OTA Update failed with error code %d\n", status);
612#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
615static uint32_t ulCurrentPowerOnState = 0;
618static uint32_t ulDesiredPowerOnState = 0;
621struct mmosal_sem *state_change_sem = NULL;
630void shadow_update_callback(
char *json,
size_t json_len,
enum shadow_update_status status)
633 int result = JSON_Validate(json, json_len);
635 if (result != JSONSuccess)
637 printf(
"ERR:Invalid JSON document received\n");
641 static uint32_t ulCurrentVersion = 0;
642 char *pcOutValue = NULL;
643 uint32_t ulOutValueLength = 0UL;
644 uint32_t ulVersion = 0;
669 result = JSON_Search(json,
674 (
size_t *)&ulOutValueLength);
676 if (result != JSONSuccess)
678 printf(
"ERR:Version field not found in JSON document\n");
682 ulVersion = (uint32_t)strtoul(pcOutValue, NULL, 10);
684 if (ulVersion <= ulCurrentVersion)
690 printf(
"ERR:Received unexpected delta update with version %u, "
691 "current version is %u\n",
692 (
unsigned int)ulVersion,
693 (
unsigned int)ulCurrentVersion);
697 ulCurrentVersion = ulVersion;
700 result = JSON_Search(json,
703 sizeof(
"state.powerOn") - 1,
705 (
size_t *)&ulOutValueLength);
707 if (result != JSONSuccess)
709 printf(
"ERR:powerOn field not found in JSON document\n");
714 ulDesiredPowerOnState = (uint32_t)strtoul(pcOutValue, NULL, 10);
721 case UPDATE_ACCEPTED:
752 case UPDATE_REJECTED:
763 result = JSON_Search(json,
768 (
size_t *)&ulOutValueLength);
771 ulCode = (uint32_t)strtoul(pcOutValue, NULL, 10);
773 printf(
"ERR:Received rejected response code %lu\n", ulCode);
776 result = JSON_Search(json,
779 sizeof(
"message") - 1,
781 (
size_t *)&ulOutValueLength);
782 printf(
" Message: %.*s\n", (
int)ulOutValueLength, pcOutValue);
793void aws_shadow_loop(
char *shadow_name)
799 if (ulDesiredPowerOnState == 1)
802 printf(
"INF:Setting powerOn state to 1.\n");
804 ulCurrentPowerOnState = ulDesiredPowerOnState;
806 else if (ulDesiredPowerOnState == 0)
809 printf(
"INF:Setting powerOn state to 0.\n");
811 ulCurrentPowerOnState = ulDesiredPowerOnState;
816 printf(
"ERR:Invalid power state %lu requested.\n", ulDesiredPowerOnState);
820 printf(
"INF:Reporting change in PowerOn state to %lu.\n", ulCurrentPowerOnState);
826 (void)memset(UpdateDocument, 0x00,
sizeof(UpdateDocument));
827 snprintf(UpdateDocument,
830 ulCurrentPowerOnState,
834 aws_publish_shadow(shadow_name, UpdateDocument);
836 printf(
"INF:Publishing to /update with following client token %lu.\n", ulClientToken);
847 printf(
"\n\nMorse AWS IoT Demo (Built " __DATE__
" " __TIME__
")\n\n");
854 char sntp_server[64];
855 strncpy(sntp_server,
"0.pool.ntp.org",
sizeof(sntp_server));
857 sntp_sync_with_backoff(sntp_server,
867 printf(
"Current Time (UTC) is : %s\r\n", ctime(&now));
870 start_mqtt_agent_task();
873 char *shadow_name = NULL;
879#if defined(ENABLE_PROVISIONING_APP) && ENABLE_PROVISIONING_APP
884 printf(
"Initiating fleet provisioning...\n");
885 do_fleet_provisioning();
886 printf(
"Failed to provision device, unable to continue.\n"
887 "Please see getting started guide on how to provision.\n");
891 printf(
"Device is not provisioned, "
892 "please see getting started guide on how to provision.\n");
896#if defined(ENABLE_OTA_APP) && ENABLE_OTA_APP
898 start_ota_update_task(ota_preupdate_callback, ota_postupdate_callback);
901#if defined(ENABLE_SHADOW_APP) && ENABLE_SHADOW_APP
905 aws_create_shadow(shadow_name, shadow_update_callback);
906 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.