Skip to content

Commit e63ec02

Browse files
implementing cbor message encoder following cloud utils definition
1 parent 7a78092 commit e63ec02

File tree

2 files changed

+155
-160
lines changed

2 files changed

+155
-160
lines changed

src/cbor/MessageEncoder.cpp

+111-126
Original file line numberDiff line numberDiff line change
@@ -14,161 +14,146 @@
1414

1515
#include "CBOREncoder.h"
1616

17-
#undef max
18-
#undef min
19-
#include <algorithm>
20-
#include <iterator>
21-
2217
#include "MessageEncoder.h"
2318

2419
/******************************************************************************
2520
* PUBLIC MEMBER FUNCTIONS
2621
******************************************************************************/
2722

28-
Encoder::Status CBORMessageEncoder::encode(Message * message, uint8_t * data, size_t& len)
29-
{
30-
EncoderState current_state = EncoderState::EncodeTag,
31-
next_state = EncoderState::Error;
32-
33-
CborEncoder encoder;
34-
CborEncoder arrayEncoder;
3523

36-
cbor_encoder_init(&encoder, data, len, 0);
24+
/******************************************************************************
25+
PRIVATE MEMBER FUNCTIONS
26+
******************************************************************************/
3727

38-
while (current_state != EncoderState::Complete) {
28+
Encoder::Status OtaBeginCommandEncoder::encode(CborEncoder* encoder, Message *msg) {
29+
OtaBeginUp * otaBeginUp = (OtaBeginUp*) msg;
30+
CborEncoder array_encoder;
3931

40-
switch (current_state) {
41-
case EncoderState::EncodeTag : next_state = handle_EncodeTag(&encoder, message); break;
42-
case EncoderState::EncodeArray : next_state = handle_EncodeArray(&encoder, &arrayEncoder, message); break;
43-
case EncoderState::EncodeParam : next_state = handle_EncodeParam(&arrayEncoder, message); break;
44-
case EncoderState::CloseArray : next_state = handle_CloseArray(&encoder, &arrayEncoder); break;
45-
case EncoderState::Complete : /* Nothing to do */ break;
46-
case EncoderState::MessageNotSupported :
47-
case EncoderState::Error : return Encoder::Status::Error;
48-
}
32+
if(cbor_encoder_create_array(encoder, &array_encoder, 1) != CborNoError) {
33+
return Encoder::Status::Error;
34+
}
4935

50-
current_state = next_state;
36+
if(cbor_encode_byte_string(&array_encoder, otaBeginUp->params.sha, SHA256_SIZE) != CborNoError) {
37+
return Encoder::Status::Error;
5138
}
5239

53-
len = cbor_encoder_get_buffer_size(&encoder, data);
40+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
41+
return Encoder::Status::Error;
42+
}
5443

5544
return Encoder::Status::Complete;
5645
}
5746

58-
/******************************************************************************
59-
PRIVATE MEMBER FUNCTIONS
60-
******************************************************************************/
47+
Encoder::Status ThingBeginCommandEncoder::encode(CborEncoder* encoder, Message *msg) {
48+
ThingBeginCmd * thingBeginCmd = (ThingBeginCmd*) msg;
49+
CborEncoder array_encoder;
6150

62-
CBORMessageEncoder::EncoderState CBORMessageEncoder::handle_EncodeTag(CborEncoder * encoder, Message * message)
63-
{
64-
CborTag commandTag = toCBORCommandTag(message->id);
65-
if (commandTag == CBORCommandTag::CBORUnknownCmdTag16b ||
66-
commandTag == CBORCommandTag::CBORUnknownCmdTag32b ||
67-
commandTag == CBORCommandTag::CBORUnknownCmdTag64b ||
68-
cbor_encode_tag(encoder, commandTag) != CborNoError) {
69-
return EncoderState::Error;
51+
if(cbor_encoder_create_array(encoder, &array_encoder, 1) != CborNoError) {
52+
return Encoder::Status::Error;
7053
}
7154

72-
return EncoderState::EncodeArray;
73-
}
55+
if(cbor_encode_text_stringz(&array_encoder, thingBeginCmd->params.thing_id) != CborNoError) {
56+
return Encoder::Status::Error;
57+
}
7458

75-
CBORMessageEncoder::EncoderState CBORMessageEncoder::handle_EncodeArray(CborEncoder * encoder, CborEncoder * array_encoder, Message * message)
76-
{
77-
// Set array size based on the message id
78-
size_t array_size = 0;
79-
switch (message->id)
80-
{
81-
case CommandId::OtaBeginUpId:
82-
array_size = 1;
83-
break;
84-
case CommandId::ThingBeginCmdId:
85-
array_size = 1;
86-
break;
87-
case CommandId::DeviceBeginCmdId:
88-
array_size = 1;
89-
break;
90-
case CommandId::LastValuesBeginCmdId:
91-
break;
92-
case CommandId::OtaProgressCmdUpId:
93-
array_size = 4;
94-
break;
95-
case CommandId::TimezoneCommandUpId:
96-
break;
97-
default:
98-
return EncoderState::MessageNotSupported;
99-
}
100-
101-
// Start an array with fixed width based on message type
102-
if (cbor_encoder_create_array(encoder, array_encoder, array_size) != CborNoError){
103-
return EncoderState::Error;
104-
}
105-
106-
return EncoderState::EncodeParam;
107-
}
59+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
60+
return Encoder::Status::Error;
61+
}
10862

109-
CBORMessageEncoder::EncoderState CBORMessageEncoder::handle_EncodeParam(CborEncoder * array_encoder, Message * message)
110-
{
111-
CborError error = CborNoError;
112-
switch (message->id)
113-
{
114-
case CommandId::OtaBeginUpId:
115-
error = CBORMessageEncoder::encodeOtaBeginUp(array_encoder, message);
116-
break;
117-
case CommandId::ThingBeginCmdId:
118-
error = CBORMessageEncoder::encodeThingBeginCmd(array_encoder, message);
119-
break;
120-
case CommandId::DeviceBeginCmdId:
121-
error = CBORMessageEncoder::encodeDeviceBeginCmd(array_encoder, message);
122-
break;
123-
case CommandId::LastValuesBeginCmdId:
124-
break;
125-
case CommandId::OtaProgressCmdUpId:
126-
error = CBORMessageEncoder::encodeOtaProgressCmdUp(array_encoder, message);
127-
break;
128-
case CommandId::TimezoneCommandUpId:
129-
break;
130-
default:
131-
return EncoderState::MessageNotSupported;
132-
}
133-
134-
return (error != CborNoError) ? EncoderState::Error : EncoderState::CloseArray;
63+
return Encoder::Status::Complete;
13564
}
13665

137-
CBORMessageEncoder::EncoderState CBORMessageEncoder::handle_CloseArray(CborEncoder * encoder, CborEncoder * array_encoder)
138-
{
139-
CborError error = cbor_encoder_close_container(encoder, array_encoder);
66+
Encoder::Status LastValuesBeginCommandEncoder::encode(CborEncoder* encoder, Message *msg) {
67+
// This command contains no parameters, it contains just the id of the message
68+
// nothing to perform here
69+
// (void)(encoder);
70+
(void)(msg);
71+
CborEncoder array_encoder;
14072

141-
return (error != CborNoError) ? EncoderState::Error : EncoderState::Complete;
142-
}
73+
// FIXME we are encoiding an empty array, this could be avoided
74+
if (cbor_encoder_create_array(encoder, &array_encoder, 0) != CborNoError){
75+
return Encoder::Status::Error;
76+
}
77+
78+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
79+
return Encoder::Status::Error;
80+
}
14381

144-
// Message specific encoders
145-
CborError CBORMessageEncoder::encodeOtaBeginUp(CborEncoder * array_encoder, Message * message)
146-
{
147-
OtaBeginUp * otaBeginUp = (OtaBeginUp *) message;
148-
CHECK_CBOR(cbor_encode_byte_string(array_encoder, otaBeginUp->params.sha, SHA256_SIZE));
149-
return CborNoError;
82+
return Encoder::Status::Complete;
15083
}
15184

152-
CborError CBORMessageEncoder::encodeThingBeginCmd(CborEncoder * array_encoder, Message * message)
153-
{
154-
ThingBeginCmd * thingBeginCmd = (ThingBeginCmd *) message;
155-
CHECK_CBOR(cbor_encode_text_stringz(array_encoder, thingBeginCmd->params.thing_id));
156-
return CborNoError;
85+
Encoder::Status DeviceBeginCommandEncoder::encode(CborEncoder* encoder, Message *msg) {
86+
DeviceBeginCmd * deviceBeginCmd = (DeviceBeginCmd*) msg;
87+
CborEncoder array_encoder;
88+
89+
if(cbor_encoder_create_array(encoder, &array_encoder, 1) != CborNoError) {
90+
return Encoder::Status::Error;
91+
}
92+
93+
if(cbor_encode_text_stringz(&array_encoder, deviceBeginCmd->params.lib_version) != CborNoError) {
94+
return Encoder::Status::Error;
95+
}
96+
97+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
98+
return Encoder::Status::Error;
99+
}
100+
101+
return Encoder::Status::Complete;
157102
}
158103

159-
CborError CBORMessageEncoder::encodeDeviceBeginCmd(CborEncoder * array_encoder, Message * message)
160-
{
161-
DeviceBeginCmd * deviceBeginCmd = (DeviceBeginCmd *) message;
162-
CHECK_CBOR(cbor_encode_text_stringz(array_encoder, deviceBeginCmd->params.lib_version));
163-
return CborNoError;
104+
Encoder::Status OtaProgressCommandUpEncoder::encode(CborEncoder* encoder, Message *msg) {
105+
OtaProgressCmdUp * ota = (OtaProgressCmdUp*) msg;
106+
CborEncoder array_encoder;
107+
108+
if(cbor_encoder_create_array(encoder, &array_encoder, 4) != CborNoError) {
109+
return Encoder::Status::Error;
110+
}
111+
112+
if(cbor_encode_byte_string(&array_encoder, ota->params.id, ID_SIZE) != CborNoError) {
113+
return Encoder::Status::Error;
114+
}
115+
116+
if(cbor_encode_simple_value(&array_encoder, ota->params.state) != CborNoError) {
117+
return Encoder::Status::Error;
118+
}
119+
120+
if(cbor_encode_int(&array_encoder, ota->params.state_data) != CborNoError) {
121+
return Encoder::Status::Error;
122+
}
123+
124+
if(cbor_encode_uint(&array_encoder, ota->params.time) != CborNoError) {
125+
return Encoder::Status::Error;
126+
}
127+
128+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
129+
return Encoder::Status::Error;
130+
}
131+
132+
return Encoder::Status::Complete;
164133
}
165134

166-
CborError CBORMessageEncoder::encodeOtaProgressCmdUp(CborEncoder * array_encoder, Message * message)
167-
{
168-
OtaProgressCmdUp * ota = (OtaProgressCmdUp *)message;
169-
CHECK_CBOR(cbor_encode_byte_string(array_encoder, ota->params.id, ID_SIZE));
170-
CHECK_CBOR(cbor_encode_simple_value(array_encoder, ota->params.state));
171-
CHECK_CBOR(cbor_encode_int(array_encoder, ota->params.state_data));
172-
CHECK_CBOR(cbor_encode_uint(array_encoder, ota->params.time));
173-
return CborNoError;
135+
Encoder::Status TimezoneCommandUpEncoder::encode(CborEncoder* encoder, Message *msg) {
136+
// This command contains no parameters, it contains just the id of the message
137+
// nothing to perform here
138+
// (void)(encoder);
139+
(void)(msg);
140+
CborEncoder array_encoder;
141+
142+
// FIXME we are encoiding an empty array, this could be avoided
143+
if (cbor_encoder_create_array(encoder, &array_encoder, 0) != CborNoError){
144+
return Encoder::Status::Error;
145+
}
146+
147+
if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
148+
return Encoder::Status::Error;
149+
}
150+
151+
return Encoder::Status::Complete;
174152
}
153+
154+
static OtaBeginCommandEncoder otaBeginCommandEncoder;
155+
static ThingBeginCommandEncoder thingBeginCommandEncoder;
156+
static LastValuesBeginCommandEncoder lastValuesBeginCommandEncoder;
157+
static DeviceBeginCommandEncoder deviceBeginCommandEncoder;
158+
static OtaProgressCommandUpEncoder otaProgressCommandUpEncoder;
159+
static TimezoneCommandUpEncoder timezoneCommandUpEncoder;

src/cbor/MessageEncoder.h

+44-34
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,61 @@
1515
* INCLUDE
1616
******************************************************************************/
1717

18-
#include <Arduino.h>
19-
20-
#undef max
21-
#undef min
22-
#include <list>
23-
24-
#include "CBOR.h"
25-
#include "../interfaces/Encoder.h"
26-
#include <Arduino_TinyCBOR.h>
18+
#include "./CBOR.h"
19+
#include <cbor/CborEncoder.h>
20+
#include "message/Commands.h"
2721

2822
/******************************************************************************
2923
* CLASS DECLARATION
3024
******************************************************************************/
3125

32-
class CBORMessageEncoder: public Encoder
33-
{
26+
class OtaBeginCommandEncoder: public CBORMessageEncoderInterface {
27+
public:
28+
OtaBeginCommandEncoder()
29+
: CBORMessageEncoderInterface(CBOROtaBeginUp, OtaBeginUpId) {}
30+
protected:
31+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
32+
};
3433

34+
class ThingBeginCommandEncoder: public CBORMessageEncoderInterface {
3535
public:
36-
CBORMessageEncoder() { }
37-
CBORMessageEncoder(CborEncoder const &) { }
38-
Encoder::Status encode(Message * message, uint8_t * data, size_t& len);
36+
ThingBeginCommandEncoder()
37+
: CBORMessageEncoderInterface(CBORThingBeginCmd, ThingBeginCmdId) {}
38+
protected:
39+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
40+
};
3941

40-
private:
42+
class LastValuesBeginCommandEncoder: public CBORMessageEncoderInterface {
43+
public:
44+
LastValuesBeginCommandEncoder()
45+
: CBORMessageEncoderInterface(CBORLastValuesBeginCmd, LastValuesBeginCmdId) {}
46+
protected:
47+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
48+
};
4149

42-
enum class EncoderState
43-
{
44-
EncodeTag,
45-
EncodeArray,
46-
EncodeParam,
47-
CloseArray,
48-
MessageNotSupported,
49-
Complete,
50-
Error
51-
};
50+
class DeviceBeginCommandEncoder: public CBORMessageEncoderInterface {
51+
public:
52+
DeviceBeginCommandEncoder()
53+
: CBORMessageEncoderInterface(CBORDeviceBeginCmd, DeviceBeginCmdId) {}
54+
protected:
55+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
56+
};
5257

53-
EncoderState handle_EncodeTag(CborEncoder * encoder, Message * message);
54-
EncoderState handle_EncodeArray(CborEncoder * encoder, CborEncoder * array_encoder, Message * message);
55-
EncoderState handle_EncodeParam(CborEncoder * array_encoder, Message * message);
56-
EncoderState handle_CloseArray(CborEncoder * encoder, CborEncoder * array_encoder);
58+
class OtaProgressCommandUpEncoder: public CBORMessageEncoderInterface {
59+
public:
60+
OtaProgressCommandUpEncoder()
61+
: CBORMessageEncoderInterface(CBOROtaProgressCmdUp, OtaProgressCmdUpId) {}
62+
protected:
63+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
64+
};
5765

58-
// Message specific encoders
59-
CborError encodeThingBeginCmd(CborEncoder * array_encoder, Message * message);
60-
CborError encodeOtaBeginUp(CborEncoder * array_encoder, Message * message);
61-
CborError encodeDeviceBeginCmd(CborEncoder * array_encoder, Message * message);
62-
CborError encodeOtaProgressCmdUp(CborEncoder * array_encoder, Message * message);
66+
class TimezoneCommandUpEncoder: public CBORMessageEncoderInterface {
67+
public:
68+
TimezoneCommandUpEncoder()
69+
: CBORMessageEncoderInterface(CBORTimezoneCommandUp, TimezoneCommandUpId) {}
70+
protected:
71+
Encoder::Status encode(CborEncoder* encoder, Message *msg) override;
6372
};
6473

74+
6575
#endif /* ARDUINO_CBOR_MESSAGE_ENCODER_H_ */

0 commit comments

Comments
 (0)