Skip to content

Commit c7dc27b

Browse files
authored
Merge pull request #451 from robgee86/add-detach-and-timezone-commands
Add detach and update timezone commands
2 parents faae972 + b95a6fd commit c7dc27b

10 files changed

+128
-7
lines changed

extras/test/src/test_command_decode.cpp

+51-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,35 @@ SCENARIO("Test the decoding of command messages") {
5050
}
5151

5252
/****************************************************************************/
53+
WHEN("Decode the ThingDetachCmd message")
54+
{
55+
CommandDown command;
56+
/*
57+
DA 00011000 # tag(69632)
58+
81 # array(1)
59+
78 24 # text(36)
60+
65343439346435352D383732612D346664322D393634362D393266383739343933393463 # "e4494d55-872a-4fd2-9646-92f87949394c"
61+
*/
62+
uint8_t const payload[] = {0xDA, 0x00, 0x01, 0x10, 0x00, 0x81, 0x78, 0x24,
63+
0x65, 0x34, 0x34, 0x39, 0x34, 0x64, 0x35, 0x35,
64+
0x2D, 0x38, 0x37, 0x32, 0x61, 0x2D, 0x34, 0x66,
65+
0x64, 0x32, 0x2D, 0x39, 0x36, 0x34, 0x36, 0x2D,
66+
0x39, 0x32, 0x66, 0x38, 0x37, 0x39, 0x34, 0x39,
67+
0x33, 0x39, 0x34, 0x63};
68+
69+
size_t payload_length = sizeof(payload) / sizeof(uint8_t);
70+
CBORMessageDecoder decoder;
71+
Decoder::Status err = decoder.decode((Message*)&command, payload, payload_length);
72+
const char *thingIdToMatch = "e4494d55-872a-4fd2-9646-92f87949394c";
73+
74+
THEN("The decode is successful") {
75+
REQUIRE(err == Decoder::Status::Complete);
76+
REQUIRE(strcmp(command.thingDetachCmd.params.thing_id, thingIdToMatch) == 0);
77+
REQUIRE(command.c.id == ThingDetachCmdId);
78+
}
79+
}
80+
81+
/************************************************************************************/
5382

5483
WHEN("Decode the ThingUpdateCmdId message containing a number instead of a string")
5584
{
@@ -71,9 +100,30 @@ SCENARIO("Test the decoding of command messages") {
71100
}
72101
}
73102

103+
/****************************************************************************/
104+
WHEN("Decode the ThingDetachCmd message containing a number instead of a string")
105+
{
106+
CommandDown command;
107+
/*
108+
DA 00011000 # tag(69632)
109+
81 # array(1)
110+
1A 65DCB821 # unsigned(1708963873)
111+
*/
112+
uint8_t const payload[] = {0xDA, 0x00, 0x01, 0x10, 0x00, 0x81, 0x1A, 0x65,
113+
0xDC, 0xB8, 0x21};
114+
115+
size_t payload_length = sizeof(payload) / sizeof(uint8_t);
116+
CBORMessageDecoder decoder;
117+
Decoder::Status err = decoder.decode((Message*)&command, payload, payload_length);
118+
119+
THEN("The decode is successful") {
120+
REQUIRE(err == Decoder::Status::Error);
121+
}
122+
}
123+
74124
/****************************************************************************/
75125

76-
WHEN("Decode the SetTimezoneCommand message")
126+
WHEN("Decode the TimezoneCommandDown message")
77127
{
78128
CommandDown command;
79129

extras/test/src/test_command_encode.cpp

+19-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ SCENARIO("Test the encoding of command messages") {
242242

243243
/****************************************************************************/
244244

245-
WHEN("Encode the SetTimezoneCommand message")
245+
WHEN("Encode the TimezoneCommandDown message")
246246
{
247247
TimezoneCommandDown command;
248248
command.c.id = CommandId::TimezoneCommandDownId;
@@ -304,6 +304,24 @@ SCENARIO("Test the encoding of command messages") {
304304

305305
/****************************************************************************/
306306

307+
WHEN("Encode the ThingDetachCmd message")
308+
{
309+
ThingDetachCmd command;
310+
command.c.id = CommandId::ThingDetachCmdId;
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 - ThingDetachCmd is not supported") {
319+
REQUIRE(err == Encoder::Status::Error);
320+
}
321+
}
322+
323+
/****************************************************************************/
324+
307325
WHEN("Encode a message with unknown command Id")
308326
{
309327
OtaUpdateCmdDown command;

src/ArduinoIoTCloudTCP.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,24 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
410410
}
411411
break;
412412

413+
case CommandId::ThingDetachCmdId:
414+
{
415+
if (!_device.isAttached() || _thing_id != String(command.thingDetachCmd.params.thing_id)) {
416+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] thing detach rejected", __FUNCTION__, millis());
417+
}
418+
419+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] thing detach received", __FUNCTION__, millis());
420+
detachThing();
421+
}
422+
break;
423+
424+
case CommandId::TimezoneCommandDownId:
425+
{
426+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] timezone update received", __FUNCTION__, millis());
427+
_thing.handleMessage((Message*)&command);
428+
}
429+
break;
430+
413431
case CommandId::LastValuesUpdateCmdId:
414432
{
415433
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values received", __FUNCTION__, millis());

src/ArduinoIoTCloudThing.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,20 @@ void ArduinoCloudThing::update() {
6969
}
7070

7171
/* Handle external events */
72-
switch (_command) {
72+
switch (_command.c.id) {
7373
case LastValuesUpdateCmdId:
7474
if (_state == State::RequestLastValues) {
7575
DEBUG_VERBOSE("CloudThing::%s Thing is synced", __FUNCTION__);
7676
nextState = State::Connected;
7777
}
7878
break;
7979

80+
/* We have received a timezone update */
81+
case TimezoneCommandDownId:
82+
TimeService.setTimeZoneData(_command.timezoneCommandDown.params.offset,
83+
_command.timezoneCommandDown.params.until);
84+
break;
85+
8086
/* We have received a reset command */
8187
case ResetCmdId:
8288
nextState = State::Init;
@@ -86,7 +92,7 @@ void ArduinoCloudThing::update() {
8692
break;
8793
}
8894

89-
_command = UnknownCmdId;
95+
_command.c.id = UnknownCmdId;
9096
_state = nextState;
9197
}
9298

@@ -95,9 +101,9 @@ int ArduinoCloudThing::connected() {
95101
}
96102

97103
void ArduinoCloudThing::handleMessage(Message* m) {
98-
_command = UnknownCmdId;
104+
_command.c.id = UnknownCmdId;
99105
if (m != nullptr) {
100-
_command = m->id;
106+
memcpy(&_command, m, sizeof(CommandDown));
101107
}
102108
}
103109

src/ArduinoIoTCloudThing.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class ArduinoCloudThing : public CloudProcess {
5151
};
5252

5353
State _state;
54-
CommandId _command;
54+
CommandDown _command;
5555
TimedAttempt _syncAttempt;
5656
PropertyContainer _propertyContainer;
5757
unsigned int _propertyContainerIndex;

src/cbor/CBOR.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ CommandId toCommandId(CBORCommandTag tag) {
3636
return CommandId::OtaUpdateCmdDownId;
3737
case CBORCommandTag::CBORThingUpdateCmd:
3838
return CommandId::ThingUpdateCmdId;
39+
case CBORCommandTag::CBORThingDetachCmd:
40+
return CommandId::ThingDetachCmdId;
3941
case CBORCommandTag::CBORLastValuesUpdate:
4042
return CommandId::LastValuesUpdateCmdId;
4143
case CBORCommandTag::CBORTimezoneCommandDown:
@@ -63,6 +65,8 @@ CBORCommandTag toCBORCommandTag(CommandId id) {
6365
return CBORCommandTag::CBOROtaUpdateCmdDown;
6466
case CommandId::ThingUpdateCmdId:
6567
return CBORCommandTag::CBORThingUpdateCmd;
68+
case CommandId::ThingDetachCmdId:
69+
return CBORCommandTag::CBORThingDetachCmd;
6670
case CommandId::LastValuesUpdateCmdId:
6771
return CBORCommandTag::CBORLastValuesUpdate;
6872
case CommandId::TimezoneCommandDownId:

src/cbor/CBOR.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ enum CBORCommandTag: uint64_t {
3131
// Commands DOWN
3232
CBOROtaUpdateCmdDown = 0x010100,
3333
CBORThingUpdateCmd = 0x010400,
34+
CBORThingDetachCmd = 0x011000,
3435
CBORLastValuesUpdate = 0x010600,
3536
CBORTimezoneCommandDown = 0x010900,
3637

src/cbor/MessageDecoder.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeThingUpdateCmd(Cb
130130
return ArrayParserState::LeaveArray;
131131
}
132132

133+
CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeThingDetachCmd(CborValue * param, Message * message) {
134+
ThingDetachCmd * thingCommand = (ThingDetachCmd *) message;
135+
136+
// Message is composed of a single parameter, a string (thing_id)
137+
if (!copyCBORStringToArray(param, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
138+
return ArrayParserState::Error;
139+
}
140+
141+
return ArrayParserState::LeaveArray;
142+
}
143+
133144
CBORMessageDecoder::ArrayParserState CBORMessageDecoder::decodeTimezoneCommandDown(CborValue * param, Message * message) {
134145
TimezoneCommandDown * setTz = (TimezoneCommandDown *) message;
135146

@@ -213,6 +224,9 @@ CBORMessageDecoder::ArrayParserState CBORMessageDecoder::handle_Param(CborValue
213224
case CommandId::ThingUpdateCmdId:
214225
return CBORMessageDecoder::decodeThingUpdateCmd(param, message);
215226

227+
case CommandId::ThingDetachCmdId:
228+
return CBORMessageDecoder::decodeThingDetachCmd(param, message);
229+
216230
case CommandId::TimezoneCommandDownId:
217231
return CBORMessageDecoder::decodeTimezoneCommandDown(param, message);
218232

src/cbor/MessageDecoder.h

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class CBORMessageDecoder: public Decoder
6565

6666
// Message specific decoders
6767
ArrayParserState decodeThingUpdateCmd(CborValue * param, Message * message);
68+
ArrayParserState decodeThingDetachCmd(CborValue * param, Message * message);
6869
ArrayParserState decodeTimezoneCommandDown(CborValue * param, Message * message);
6970
ArrayParserState decodeLastValuesUpdateCmd(CborValue * param, Message * message);
7071
ArrayParserState decodeOtaUpdateCmdDown(CborValue * param, Message * message);

src/message/Commands.h

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum CommandId: uint32_t {
3737
DeviceBeginCmdId,
3838
ThingBeginCmdId,
3939
ThingUpdateCmdId,
40+
ThingDetachCmdId,
4041
DeviceRegisteredCmdId,
4142
DeviceAttachedCmdId,
4243
DeviceDetachedCmdId,
@@ -89,6 +90,13 @@ struct ThingUpdateCmd {
8990
} params;
9091
};
9192

93+
struct ThingDetachCmd {
94+
Command c;
95+
struct {
96+
char thing_id[THING_ID_SIZE];
97+
} params;
98+
};
99+
92100
struct LastValuesBeginCmd {
93101
Command c;
94102
};
@@ -144,6 +152,7 @@ union CommandDown {
144152
struct Command c;
145153
struct OtaUpdateCmdDown otaUpdateCmdDown;
146154
struct ThingUpdateCmd thingUpdateCmd;
155+
struct ThingDetachCmd thingDetachCmd;
147156
struct LastValuesUpdateCmd lastValuesUpdateCmd;
148157
struct TimezoneCommandDown timezoneCommandDown;
149158
};

0 commit comments

Comments
 (0)