Skip to content

Commit be25876

Browse files
authored
Merge pull request #447 from arduino-libraries/command-cbor-integration
Add new Command topics
2 parents c381c97 + ba2d584 commit be25876

15 files changed

+2022
-132
lines changed

Diff for: extras/test/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ set(TEST_SRCS
3636
src/test_CloudSchedule.cpp
3737
src/test_decode.cpp
3838
src/test_encode.cpp
39+
src/test_command_decode.cpp
40+
src/test_command_encode.cpp
3941
src/test_publishEvery.cpp
4042
src/test_publishOnChange.cpp
4143
src/test_publishOnChangeRateLimit.cpp
@@ -55,6 +57,9 @@ set(TEST_DUT_SRCS
5557
../../src/property/PropertyContainer.cpp
5658
../../src/cbor/CBORDecoder.cpp
5759
../../src/cbor/CBOREncoder.cpp
60+
../../src/cbor/MessageDecoder.cpp
61+
../../src/cbor/MessageEncoder.cpp
62+
../../src/cbor/CBOR.cpp
5863
../../src/cbor/lib/tinycbor/src/cborencoder.c
5964
../../src/cbor/lib/tinycbor/src/cborencoder_close_container_checked.c
6065
../../src/cbor/lib/tinycbor/src/cborerrorstrings.c

Diff for: extras/test/src/test_command_decode.cpp

+736
Large diffs are not rendered by default.

Diff for: extras/test/src/test_command_encode.cpp

+322
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
/*
2+
Copyright (c) 2024 Arduino. All rights reserved.
3+
*/
4+
5+
/******************************************************************************
6+
INCLUDE
7+
******************************************************************************/
8+
9+
#include <catch.hpp>
10+
11+
#include <memory>
12+
13+
#include <util/CBORTestUtil.h>
14+
#include <MessageEncoder.h>
15+
16+
/******************************************************************************
17+
TEST CODE
18+
******************************************************************************/
19+
20+
SCENARIO("Test the encoding of command messages") {
21+
/****************************************************************************/
22+
23+
WHEN("Encode the OtaBeginUp message")
24+
{
25+
OtaBeginUp command;
26+
uint8_t sha[SHA256_SIZE] = {0x01, 0x02, 0x03, 0x04};
27+
memcpy(command.params.sha, sha, SHA256_SIZE);
28+
29+
command.c.id = CommandId::OtaBeginUpId;
30+
31+
uint8_t buffer[512];
32+
size_t bytes_encoded = sizeof(buffer);
33+
34+
CBORMessageEncoder encoder;
35+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
36+
37+
uint8_t expected_result[] = {
38+
0xda, 0x00, 0x01, 0x00, 0x00, 0x81, 0x58, 0x20,
39+
0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00,
40+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
42+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
43+
};
44+
45+
// Test the encoding is
46+
// DA 00010000 # tag(65536)
47+
// 81 # array(1)
48+
// 58 20 # bytes(32)
49+
// 01020304
50+
THEN("The encoding is successful") {
51+
REQUIRE(err == Encoder::Status::Complete);
52+
REQUIRE(bytes_encoded == sizeof(expected_result));
53+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
54+
}
55+
}
56+
57+
58+
/****************************************************************************/
59+
60+
WHEN("Encode the ThingBeginCmd message")
61+
{
62+
ThingBeginCmd command;
63+
String thing_id = "thing_id";
64+
strcpy(command.params.thing_id, thing_id.c_str());
65+
66+
command.c.id = CommandId::ThingBeginCmdId;
67+
68+
uint8_t buffer[512];
69+
size_t bytes_encoded = sizeof(buffer);
70+
71+
CBORMessageEncoder encoder;
72+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
73+
74+
uint8_t expected_result[] = {
75+
0xda, 0x00, 0x01, 0x03, 0x00, 0x81, 0x68, 0x74,
76+
0x68, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x64
77+
};
78+
79+
// Test the encoding is
80+
// DA 00010300 # tag(66304)
81+
// 81 # array(1)
82+
// 68 # text(8)
83+
// 7468696E675F6964 # "thing_id"
84+
85+
THEN("The encoding is successful") {
86+
REQUIRE(err == Encoder::Status::Complete);
87+
REQUIRE(bytes_encoded == sizeof(expected_result));
88+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
89+
}
90+
}
91+
92+
/****************************************************************************/
93+
94+
WHEN("Encode the LastValuesBeginCmd message")
95+
{
96+
LastValuesBeginCmd command;
97+
command.c.id = CommandId::LastValuesBeginCmdId;
98+
99+
uint8_t buffer[512];
100+
size_t bytes_encoded = sizeof(buffer);
101+
102+
CBORMessageEncoder encoder;
103+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
104+
105+
uint8_t expected_result[] = {
106+
0xda, 0x00, 0x01, 0x05, 0x00, 0x80
107+
};
108+
109+
// Test the encoding is
110+
// DA 00010500 # tag(66816)
111+
// 80 # array(0)
112+
THEN("The encoding is successful") {
113+
REQUIRE(err == Encoder::Status::Complete);
114+
REQUIRE(bytes_encoded == sizeof(expected_result));
115+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
116+
}
117+
}
118+
119+
/**************************************************************************/
120+
121+
WHEN("Encode the DeviceBeginCmd message")
122+
{
123+
DeviceBeginCmd command;
124+
String lib_version = "2.0.0";
125+
strcpy(command.params.lib_version, lib_version.c_str());
126+
127+
command.c.id = CommandId::DeviceBeginCmdId;
128+
129+
uint8_t buffer[512];
130+
size_t bytes_encoded = sizeof(buffer);
131+
132+
CBORMessageEncoder encoder;
133+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
134+
135+
uint8_t expected_result[] = {
136+
0xda, 0x00, 0x01, 0x07, 0x00, 0x81, 0x65, 0x32,
137+
0x2e, 0x30, 0x2e, 0x30
138+
};
139+
140+
// Test the encoding is
141+
// DA 00010700 # tag(67328)
142+
// 81 # array(1)
143+
// 65 # text(5)
144+
// 322E302E30 # "2.0.0"
145+
THEN("The encoding is successful") {
146+
REQUIRE(err == Encoder::Status::Complete);
147+
REQUIRE(bytes_encoded == sizeof(expected_result));
148+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
149+
}
150+
}
151+
152+
/****************************************************************************/
153+
154+
WHEN("Encode the OtaProgressCmdUp message")
155+
{
156+
OtaProgressCmdUp command;
157+
command.params.time = 2;
158+
159+
uint8_t id[ID_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
160+
memcpy(command.params.id, id, ID_SIZE);
161+
command.params.state = 1;
162+
command.params.state_data = -1;
163+
command.params.time = 100;
164+
165+
command.c.id = CommandId::OtaProgressCmdUpId;
166+
167+
uint8_t buffer[512];
168+
size_t bytes_encoded = sizeof(buffer);
169+
170+
CBORMessageEncoder encoder;
171+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
172+
173+
uint8_t expected_result[] = {
174+
0xda, 0x00, 0x01, 0x02, 0x00, 0x84, 0x50, 0x00,
175+
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
176+
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xe1,
177+
0x20, 0x18, 0x64
178+
};
179+
180+
// Test the encoding is
181+
// DA 00010200 # tag(66048)
182+
// 84 # array(4)
183+
// 50 # bytes(16)
184+
// 000102030405060708090A0B0C0D0E0F # "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f"
185+
// E1 # primitive(1)
186+
// 20 # negative(0)
187+
// 18 64 # unsigned(100)
188+
THEN("The encoding is successful") {
189+
REQUIRE(err == Encoder::Status::Complete);
190+
REQUIRE(bytes_encoded == sizeof(expected_result));
191+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
192+
}
193+
}
194+
195+
/****************************************************************************/
196+
197+
WHEN("Encode the TimezoneCommandUp message")
198+
{
199+
TimezoneCommandUp command;
200+
command.c.id = CommandId::TimezoneCommandUpId;
201+
202+
uint8_t buffer[512];
203+
size_t bytes_encoded = sizeof(buffer);
204+
205+
CBORMessageEncoder encoder;
206+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
207+
208+
uint8_t expected_result[] = {
209+
0xda, 0x00, 0x01, 0x08, 0x00, 0x80
210+
};
211+
212+
// Test the encoding is
213+
// DA 00010800 # tag(67584)
214+
// 80 # array(0)
215+
THEN("The encoding is successful") {
216+
REQUIRE(err == Encoder::Status::Complete);
217+
REQUIRE(bytes_encoded == sizeof(expected_result));
218+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
219+
}
220+
}
221+
222+
/****************************************************************************/
223+
224+
WHEN("Encode the ThingUpdateCmdId message")
225+
{
226+
ThingUpdateCmd command;
227+
command.c.id = CommandId::ThingUpdateCmdId;
228+
229+
String thing_id = "e4494d55-872a-4fd2-9646-92f87949394c";
230+
strcpy(command.params.thing_id, thing_id.c_str());
231+
232+
uint8_t buffer[512];
233+
size_t bytes_encoded = sizeof(buffer);
234+
235+
CBORMessageEncoder encoder;
236+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
237+
238+
THEN("The encoding is unsuccessful - ThingUpdateCmdId is not supported") {
239+
REQUIRE(err == Encoder::Status::Error);
240+
}
241+
}
242+
243+
/****************************************************************************/
244+
245+
WHEN("Encode the SetTimezoneCommand message")
246+
{
247+
TimezoneCommandDown command;
248+
command.c.id = CommandId::TimezoneCommandDownId;
249+
250+
command.params.offset = 1708963873;
251+
command.params.until = 2024579473;
252+
253+
uint8_t buffer[512];
254+
size_t bytes_encoded = sizeof(buffer);
255+
256+
CBORMessageEncoder encoder;
257+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
258+
259+
THEN("The encoding is unsuccessful - SetTimezoneCommand is not supported") {
260+
REQUIRE(err == Encoder::Status::Error);
261+
}
262+
}
263+
264+
/****************************************************************************/
265+
266+
WHEN("Encode the LastValuesUpdateCmd message")
267+
{
268+
LastValuesUpdateCmd command;
269+
command.c.id = CommandId::LastValuesUpdateCmdId;
270+
271+
command.params.length = 13;
272+
uint8_t last_values[13] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
273+
0x08, 0x09, 0x10, 0x11, 0x12};
274+
command.params.last_values = last_values;
275+
276+
uint8_t buffer[512];
277+
size_t bytes_encoded = sizeof(buffer);
278+
279+
CBORMessageEncoder encoder;
280+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
281+
282+
THEN("The encoding is unsuccessful - LastValuesUpdateCmd is not supported") {
283+
REQUIRE(err == Encoder::Status::Error);
284+
}
285+
}
286+
287+
/****************************************************************************/
288+
289+
WHEN("Encode the OtaUpdateCmdDown message")
290+
{
291+
OtaUpdateCmdDown command;
292+
command.c.id = CommandId::OtaUpdateCmdDownId;
293+
294+
uint8_t buffer[512];
295+
size_t bytes_encoded = sizeof(buffer);
296+
297+
CBORMessageEncoder encoder;
298+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
299+
300+
THEN("The encoding is unsuccessful - OtaUpdateCmdDown is not supported") {
301+
REQUIRE(err == Encoder::Status::Error);
302+
}
303+
}
304+
305+
/****************************************************************************/
306+
307+
WHEN("Encode a message with unknown command Id")
308+
{
309+
OtaUpdateCmdDown command;
310+
command.c.id = CommandId::UnknownCmdId;
311+
312+
uint8_t buffer[512];
313+
size_t bytes_encoded = sizeof(buffer);
314+
315+
CBORMessageEncoder encoder;
316+
Encoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
317+
318+
THEN("The encoding is unsuccessful - UnknownCmdId is not supported") {
319+
REQUIRE(err == Encoder::Status::Error);
320+
}
321+
}
322+
}

Diff for: src/ArduinoIoTCloudDevice.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,12 @@ ArduinoCloudDevice::State ArduinoCloudDevice::handleInit() {
104104

105105
ArduinoCloudDevice::State ArduinoCloudDevice::handleSendCapabilities() {
106106
/* Sends device capabilities message */
107-
Message message = { DeviceBeginCmdId };
108-
deliver(&message);
107+
DeviceBeginCmd deviceBegin = { DeviceBeginCmdId, AIOT_CONFIG_LIB_VERSION };
108+
deliver(reinterpret_cast<Message*>(&deviceBegin));
109109

110110
/* Subscribe to device topic to request */
111-
message = { ThingBeginCmdId };
112-
deliver(&message);
111+
ThingBeginCmd thingBegin = { ThingBeginCmdId };
112+
deliver(reinterpret_cast<Message*>(&thingBegin));
113113

114114
/* No device configuration received. Wait: 4s -> 8s -> 16s -> 32s -> 32s ...*/
115115
_attachAttempt.retry();

0 commit comments

Comments
 (0)