Skip to content

Commit d98ef3e

Browse files
committed
Rework the example to use the new AWS Client
The previous version (v4) of aws-iot-device-sdk-embedded-C is now deprecated in favour of coreMQTT from Amazon FreeRTOS. An new AWS client based on coreMQTT and written for Mbed OS has been contributed by Nantis GmbH, and this commit reworks the example to support the new AWS client. Two demos are provided. The demo is selected based on the config in mbed_app.json: * MQTT (default): if aws-client.shadow is unset or false * Device Shadow service: if aws-client.shadow is true
1 parent 2072de4 commit d98ef3e

File tree

6 files changed

+309
-148
lines changed

6 files changed

+309
-148
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ target_include_directories(${APP_TARGET}
3030
target_sources(${APP_TARGET}
3131
PRIVATE
3232
main.cpp
33+
demo_mqtt.cpp
34+
demo_shadow.cpp
3335
)
3436

3537
if("-DMBED_CONF_ISM43362_PROVIDE_DEFAULT=1" IN_LIST MBED_CONFIG_DEFINITIONS)

demo_mqtt.cpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (c) 2020-2021 Arm Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#if !MBED_CONF_AWS_CLIENT_SHADOW
7+
8+
#include "mbed.h"
9+
#include "mbed-trace/mbed_trace.h"
10+
#include "rtos/ThisThread.h"
11+
#include "AWSClient/AWSClient.h"
12+
13+
extern "C" {
14+
#include "core_json.h"
15+
}
16+
17+
#define TRACE_GROUP "Main"
18+
19+
static bool reply_received = false;
20+
21+
// Callback when a MQTT message has been added to the topic
22+
void on_message_callback(
23+
const char *topic,
24+
uint16_t topic_length,
25+
const void *payload,
26+
size_t payload_length)
27+
{
28+
char *json_value;
29+
size_t value_length;
30+
auto ret = JSON_Search((char *)payload, payload_length, "sender", strlen("sender"), &json_value, &value_length);
31+
if (ret == JSONSuccess && (strncmp(json_value, "device", strlen("device")) == 0)) {
32+
tr_info("Message sent successfully");
33+
} else {
34+
ret = JSON_Search((char *)payload, payload_length, "message", strlen("message"), &json_value, &value_length);
35+
if (ret == JSONSuccess) {
36+
reply_received = true;
37+
tr_info("Message received from the cloud: \"%.*s\"", value_length, json_value);
38+
} else {
39+
tr_error("Failed to extract message from the payload: \"%.*s\"", payload_length, (const char *) payload);
40+
}
41+
}
42+
}
43+
44+
void demo()
45+
{
46+
AWSClient &client = AWSClient::getInstance();
47+
48+
// Subscribe to the topic
49+
const char topic[] = MBED_CONF_APP_AWS_MQTT_TOPIC;
50+
int ret = client.subscribe(topic, strlen(topic));
51+
if (ret != MBED_SUCCESS) {
52+
tr_error("AWSClient::subscribe() failed");
53+
return;
54+
}
55+
56+
// Send ten message to the cloud (one per second)
57+
// Stop when we receive a cloud-to-device message
58+
char payload[128];
59+
for (int i = 0; i < 10; i++) {
60+
if (reply_received) {
61+
// If we have received a message from the cloud, don't send more messeges
62+
break;
63+
}
64+
65+
// The MQTT protocol does not distinguish between senders,
66+
// so we add a "sender" attribute to the payload
67+
const char base_message[] = "messages left to send, or until we receive a reply";
68+
sprintf(payload, "{\n"
69+
" \"sender\": \"device\",\n"
70+
" \"message\": \"%d %s\"\n"
71+
"}",
72+
10 - i, base_message);
73+
tr_info("Publishing \"%d %s\" to topic \"%s\"", 10 - i, base_message, topic);
74+
ret = client.publish(
75+
topic,
76+
strlen(topic),
77+
payload,
78+
strlen(payload)
79+
);
80+
if (ret != MBED_SUCCESS) {
81+
tr_error("AWSClient::publish() failed");
82+
goto unsubscribe;
83+
}
84+
85+
rtos::ThisThread::sleep_for(1s);
86+
}
87+
88+
// If the user didn't manage to send a cloud-to-device message earlier,
89+
// let's wait until we receive one
90+
while (!reply_received) {
91+
// Continue to receive messages in the communication thread
92+
// which is internally created and maintained by the Azure SDK.
93+
sleep();
94+
}
95+
96+
unsubscribe:
97+
// Unsubscribe from the topic
98+
ret = client.unsubscribe(topic, strlen(topic));
99+
if (ret != MBED_SUCCESS) {
100+
tr_error("AWSClient::unsubscribe() failed");
101+
}
102+
}
103+
104+
#endif // !MBED_CONF_AWS_CLIENT_SHADOW

demo_shadow.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) 2020-2021 Arm Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#if MBED_CONF_AWS_CLIENT_SHADOW
7+
8+
#include "mbed.h"
9+
#include "mbed-trace/mbed_trace.h"
10+
#include "AWSClient/AWSClient.h"
11+
12+
extern "C" {
13+
#include "core_json.h"
14+
}
15+
16+
#define TRACE_GROUP "Main"
17+
18+
// This should not be called for the Device Shadow demo -
19+
// Device Shadow messages are internally consumed by the client
20+
void on_message_callback(
21+
const char *topic,
22+
uint16_t topic_length,
23+
const void *payload,
24+
size_t payload_length)
25+
{
26+
tr_warning(
27+
"Message received on non-shadow topic: %.*s payload: %.*s",
28+
topic_length,
29+
topic,
30+
(const char *) payload_length,
31+
payload
32+
);
33+
}
34+
35+
void demo()
36+
{
37+
AWSClient &client = AWSClient::getInstance();
38+
39+
// Download shadow document
40+
auto ret = client.downloadShadowDocument();
41+
if (ret == MBED_SUCCESS) {
42+
tr_info("Device Shadow document downloaded");
43+
} else {
44+
tr_error("AWSClient::downloadShadowDocument() failed: %d", ret);
45+
return; // cannot continue without downloadShadowDocument()
46+
}
47+
48+
// Get a desired shadow value
49+
const char shadow_demo_int_key[] = "DemoNumber";
50+
const int shadow_demo_int_value = 100;
51+
char *shadow_value;
52+
size_t shadow_value_length;
53+
ret = client.getShadowDesiredValue(
54+
shadow_demo_int_key,
55+
strlen(shadow_demo_int_key),
56+
&shadow_value,
57+
&shadow_value_length
58+
);
59+
if (ret == MBED_SUCCESS) {
60+
tr_info("Desired value of %s: %.*s", shadow_demo_int_key, shadow_value_length, shadow_value);
61+
} else {
62+
tr_error(
63+
"AWSClient::getShadowDesiredValue() failed: %d, "
64+
"please ensure you have set a desired value for %s (e.g. using the AWS Console)",
65+
ret,
66+
shadow_demo_int_key
67+
);
68+
}
69+
70+
// Report a string shadow value
71+
const char shadow_demo_string_key[] = "DemoName";
72+
const char shadow_demo_string_value[] = "mbed-os-example-for-aws";
73+
ret = client.publishShadowReportedValue(
74+
shadow_demo_string_key,
75+
strlen(shadow_demo_string_key),
76+
shadow_demo_string_value,
77+
strlen(shadow_demo_string_value)
78+
);
79+
if (ret == MBED_SUCCESS) {
80+
tr_info("Device Shadow reported string value published");
81+
} else {
82+
tr_error("AWSClient::publishShadowReportedValue() failed: %d", ret);
83+
}
84+
85+
// Report an integer shadow value
86+
ret = client.publishShadowReportedValue(
87+
shadow_demo_int_key,
88+
strlen(shadow_demo_int_key),
89+
shadow_demo_int_value
90+
);
91+
if (ret == MBED_SUCCESS) {
92+
tr_info("Device Shadow reported integer value published");
93+
} else {
94+
tr_error("AWSClient::publishShadowReportedValue() failed: %d", ret);
95+
}
96+
}
97+
98+
#endif // MBED_CONF_AWS_CLIENT_SHADOW

0 commit comments

Comments
 (0)