Skip to content

Add classes for standard cbor encoders/decoders #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
- examples/customCborEncoder
- examples/timedBlink
- examples/flashFormatter
- examples/versionCborEncoder
SKETCHES_REPORTS_PATH: sketches-reports

strategy:
Expand Down
42 changes: 42 additions & 0 deletions examples/versionCborEncoder/versionCborEncoder.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2025 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <Arduino_CBOR.h>
#include <cbor/standards/StandardMessages.h>

void setup() {
Serial.begin(9600);
while(!Serial);

VersionMessage command;
command.c.id = StandardMessageId::WiFiFWVersionMessageId;
command.params.version = "1.6.0";
uint8_t buffer[512];
size_t buf_len = sizeof(buffer);

CBORMessageEncoder encoder;
MessageEncoder::Status err = encoder.encode((Message*)&command, buffer, buf_len);

uint8_t expected_result[] = {
0xda, 0x00, 0x01, 0x20, 0x14, 0x81, 0x65, 0x31, 0x2E, 0x36, 0x2E, 0x30
};
size_t res_len=buf_len;
MessageEncoder::Status res = encoder.encode((Message*)&command, buffer, res_len);

if(res == MessageEncoder::Status::Complete &&
memcmp(buffer, expected_result, res_len) == 0) {

Serial.println("Encode operation completed with success");
} else {
Serial.println("Encode operation failed");
}
}

void loop() {}
2 changes: 2 additions & 0 deletions extras/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(TEST_SRCS
src/hex/test_hex.cpp
src/cbor/test_cbor_encoder.cpp
src/cbor/test_cbor_decoder.cpp
src/cbor/test_cbor_standard_enc.cpp
src/time/test_TimedAttempt.cpp
)

Expand All @@ -40,6 +41,7 @@ set(TEST_DUT_SRCS
../../src/hex/chex.h
../../src/cbor/MessageDecoder.cpp
../../src/cbor/MessageEncoder.cpp
../../src/cbor/standards/StandardEncoders.cpp
../../src/cbor/tinycbor
../../src/cbor/tinycbor/src/cborencoder.c
../../src/cbor/tinycbor/src/cborencoder_close_container_checked.c
Expand Down
48 changes: 48 additions & 0 deletions extras/test/src/cbor/test_cbor_standard_enc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2024 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers.hpp>
#include <catch2/matchers/catch_matchers_vector.hpp>
#include <cbor/standards/StandardEncoders.h>

/******************************************************************************
TEST CODE
******************************************************************************/

SCENARIO("Test the encoding of command messages") {

WHEN("Encode a message with provisioning wifi fw version ")
{
VersionMessage command;
command.c.id = StandardMessageId::WiFiFWVersionMessageId;
command.params.version = "1.6.0";
uint8_t buffer[512];
size_t bytes_encoded = sizeof(buffer);

CBORMessageEncoder encoder;
MessageEncoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);

uint8_t expected_result[] = {
0xda, 0x00, 0x01, 0x20, 0x14, 0x81, 0x65, 0x31, 0x2E, 0x36, 0x2E, 0x30
};

// Test the encoding is
//DA 00012014 # tag(73748)
// 81 # array(1)
// 65 # text(5)
// 312E362E30 # "1.6.0"
THEN("The encoding is successful") {
REQUIRE(err == MessageEncoder::Status::Complete);
REQUIRE(bytes_encoded == sizeof(expected_result));
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
}
}

}
32 changes: 32 additions & 0 deletions src/cbor/standards/StandardEncoders.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2025 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "StandardEncoders.h"

MessageEncoder::Status VersionMessageEncoder::encode(CborEncoder* encoder, Message *msg) {
VersionMessage * versionMsg = (VersionMessage*) msg;
CborEncoder array_encoder;

if(cbor_encoder_create_array(encoder, &array_encoder, 1) != CborNoError) {
return MessageEncoder::Status::Error;

Check warning on line 18 in src/cbor/standards/StandardEncoders.cpp

View check run for this annotation

Codecov / codecov/patch

src/cbor/standards/StandardEncoders.cpp#L18

Added line #L18 was not covered by tests
}

if(cbor_encode_text_stringz(&array_encoder, versionMsg->params.version) != CborNoError) {
return MessageEncoder::Status::Error;

Check warning on line 22 in src/cbor/standards/StandardEncoders.cpp

View check run for this annotation

Codecov / codecov/patch

src/cbor/standards/StandardEncoders.cpp#L22

Added line #L22 was not covered by tests
}

if(cbor_encoder_close_container(encoder, &array_encoder) != CborNoError) {
return MessageEncoder::Status::Error;

Check warning on line 26 in src/cbor/standards/StandardEncoders.cpp

View check run for this annotation

Codecov / codecov/patch

src/cbor/standards/StandardEncoders.cpp#L26

Added line #L26 was not covered by tests
}

return MessageEncoder::Status::Complete;
}

static VersionMessageEncoder wifiFWVersionMessageEncoderCbor(CBORWiFiFWVersionMessage, WiFiFWVersionMessageId);
21 changes: 21 additions & 0 deletions src/cbor/standards/StandardEncoders.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2025 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

#include "StandardMessages.h"

class VersionMessageEncoder: public CBORMessageEncoderInterface {
public:
VersionMessageEncoder(CBORStandardMessageTag tag, StandardMessageId id)
: CBORMessageEncoderInterface(tag, id) {}
protected:
MessageEncoder::Status encode(CborEncoder* encoder, Message *msg) override;
};
29 changes: 29 additions & 0 deletions src/cbor/standards/StandardMessages.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
This file is part of the Arduino_CloudUtils library.

Copyright (c) 2025 Arduino SA

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once
#include "../MessageEncoder.h"

enum CBORStandardMessageTag: CBORTag {

CBORWiFiFWVersionMessage = 0x012014 //Next tag starts at 0x013000
};

enum StandardMessageId: MessageId {
/* Standard commands*/
WiFiFWVersionMessageId = ArduinoStandardMessageStartId,
};

struct VersionMessage {
Message c;
struct {
const char *version; //The payload is a string.
} params;
};
1 change: 1 addition & 0 deletions src/interfaces/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct Message {
* and boundaries and avoid value clashing
*/
enum : MessageId {
ArduinoStandardMessageStartId = 0x000,
ArduinoIOTCloudStartMessageId = 0x100,
ArduinoProvisioningStartMessageId = 0x200,
Comment on lines +32 to 34
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ArduinoStandardMessageStartId = 0x000,
ArduinoIOTCloudStartMessageId = 0x100,
ArduinoProvisioningStartMessageId = 0x200,
ArduinoMessageStartId = 0x000,
ArduinoIOTCloudStartMessageId = 0x100,
ArduinoProvisioningStartMessageId = 0x200,
ArduinoVersionsStartId = 0x300,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer keeping the versions messages IDs starting from ArduinoStandardMessageStartId. My idea is that the StandardMessageEncoder is a collection of common encoders

};
Loading