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

Merged
Merged
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
82 changes: 82 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,82 @@
/*
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);
}
}

WHEN("Error encoding a message with provisioning wifi fw version not enough space for array")
{
VersionMessage command;
command.c.id = StandardMessageId::WiFiFWVersionMessageId;
command.params.version = "1.6.0";
uint8_t buffer[5]; // Not enough space
size_t bytes_encoded = sizeof(buffer);

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

// Test the encoding fails due to insufficient space
THEN("The encoding fails with an error") {
REQUIRE(err == MessageEncoder::Status::Error);
}
}

WHEN("Error encoding a message with provisioning wifi fw version not enough space for version string")
{
VersionMessage command;
command.c.id = StandardMessageId::WiFiFWVersionMessageId;
command.params.version = "1.6.0";
uint8_t buffer[7]; // Not enough space
size_t bytes_encoded = sizeof(buffer);

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

// Test the encoding fails due to insufficient space
THEN("The encoding fails with an error") {
REQUIRE(err == MessageEncoder::Status::Error);
}
}

}
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;
}

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

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 = ArduinoVersionsStartId,
};

struct VersionMessage {
Message c;
struct {
const char *version; //The payload is a string.
} params;
};
2 changes: 2 additions & 0 deletions src/interfaces/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct Message {
* and boundaries and avoid value clashing
*/
enum : MessageId {
ArduinoMessageStartId = 0x000,
ArduinoIOTCloudStartMessageId = 0x100,
ArduinoProvisioningStartMessageId = 0x200,
ArduinoVersionsStartId = 0x300,
};
Loading