Skip to content

Cbor messages #17

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 11 commits into from
Feb 26, 2025
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[codespell]
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
ignore-words-list = ,
skip = ./.git,./.licenses,__pycache__,node_modules,./go.mod,./go.sum,./package-lock.json,./poetry.lock,./yarn.lock,./src/tinycbor
skip = ./.git,./.licenses,__pycache__,node_modules,./go.mod,./go.sum,./package-lock.json,./poetry.lock,./yarn.lock,./src/cbor/tinycbor
builtin = clear,informal,en-GB_to_en-US
check-filenames =
check-hidden =
2 changes: 2 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
- examples/crc32
- examples/crc16
- examples/sha256
- examples/customCborDecoder
- examples/customCborEncoder
- examples/timedBlink
SKETCHES_REPORTS_PATH: sketches-reports

Expand Down
79 changes: 79 additions & 0 deletions examples/customCborDecoder/customCborDecoder.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
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 <Arduino_CBOR.h>

enum : MessageId {
CBORTestMessageId = 0x0123,
};

enum : CBORTag {
CBORTestMessageTag = 0x0321,
};


struct CBORTestMessage {
Message m;
char parameter[20];
};

class CustomMessageDecoder: public CBORMessageDecoderInterface {
public:
CustomMessageDecoder()
: CBORMessageDecoderInterface(CBORTestMessageTag, CBORTestMessageId) {}

protected:
MessageDecoder::Status decode(CborValue* iter, Message *msg) override {
CBORTestMessage* test = (CBORTestMessage*) msg;
size_t dest_size = 20;

if(!cbor_value_is_text_string(iter)) {
return MessageDecoder::Status::Error;
}

// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
if(_cbor_value_copy_string(iter, test->parameter, &dest_size, NULL) != CborNoError) {
return MessageDecoder::Status::Error;
}

return MessageDecoder::Status::Complete;
}
} customMessageDecoder;

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

CBORMessageDecoder decoder;

CBORTestMessage expected_result {
CBORTestMessageId,
"abcdef",
};

uint8_t buffer[] {
0xD9, 0x03, 0x21, 0x81, 0x66, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
};
size_t buffer_len = sizeof(buffer);

CBORTestMessage cmd_res;
MessageDecoder::Status res = decoder.decode((Message*)&cmd_res, buffer, buffer_len);

if(res == MessageDecoder::Status::Complete &&
cmd_res.m.id == expected_result.m.id &&
strcmp(cmd_res.parameter, expected_result.parameter) == 0) {

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

void loop() {}
77 changes: 77 additions & 0 deletions examples/customCborEncoder/customCborEncoder.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
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 <Arduino_CBOR.h>

enum : MessageId {
CBORTestMessageId = 0x0123,
};

enum : CBORTag {
CBORTestMessageTag = 0x0321,
};


struct CBORTestMessage {
Message m;
char parameter[20];
};

class CustomMessageEncoder: public CBORMessageEncoderInterface {
public:
CustomMessageEncoder()
: CBORMessageEncoderInterface(CBORTestMessageTag, CBORTestMessageId) {}

protected:
MessageEncoder::Status encode(CborEncoder* encoder, Message *msg) override {
CBORTestMessage * testMessage = (CBORTestMessage *) 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, testMessage->parameter) != CborNoError) {
return MessageEncoder::Status::Error;
}

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

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

CBORMessageEncoder encoder;
uint8_t buffer[100]; // shared buffer for encoding
uint8_t expected[] = {0xD9, 0x03, 0x21, 0x81, 0x66, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
const size_t buf_len = sizeof(buffer);

CBORTestMessage cmd {
CBORTestMessageId,
"abcdef",
};
size_t res_len=buf_len;
MessageEncoder::Status res = encoder.encode((Message*)&cmd, buffer, res_len);

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

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

void loop() {}
15 changes: 15 additions & 0 deletions extras/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ set(TEST_SRCS
src/crc16/test_crc16.cpp
src/sha256/test_sha256.cpp
src/hex/test_hex.cpp
src/cbor/test_cbor_encoder.cpp
src/cbor/test_cbor_decoder.cpp
src/time/test_TimedAttempt.cpp
)

Expand All @@ -36,6 +38,19 @@ set(TEST_DUT_SRCS
../../src/crc/crc16.cpp
../../src/sha256/sha2.c
../../src/hex/chex.h
../../src/cbor/MessageDecoder.cpp
../../src/cbor/MessageEncoder.cpp
../../src/cbor/tinycbor
../../src/cbor/tinycbor/src/cborencoder.c
../../src/cbor/tinycbor/src/cborencoder_close_container_checked.c
../../src/cbor/tinycbor/src/cborerrorstrings.c
../../src/cbor/tinycbor/src/cborparser.c
../../src/cbor/tinycbor/src/cborparser_dup_string.c
../../src/cbor/tinycbor/src/cborpretty.c
../../src/cbor/tinycbor/src/cborpretty_stdio.c
../../src/cbor/tinycbor/src/cbortojson.c
../../src/cbor/tinycbor/src/cborvalidation.c
../../src/cbor/tinycbor/src/open_memstream.c
../../src/time/TimedAttempt.cpp
)

Expand Down
85 changes: 85 additions & 0 deletions extras/test/src/cbor/test_cbor_decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
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_string.hpp>
#include <cbor/MessageDecoder.h>

#include <stdio.h>

enum : MessageId {
CBORTestMessageId = 0x0123,
};

enum : CBORTag {
CBORTestMessageTag = 0x0321,
};

struct CBORTestMessage {
Message m;
char parameter[20];
};

class CustomMessageDecoder: public CBORMessageDecoderInterface {
public:
CustomMessageDecoder()
: CBORMessageDecoderInterface(CBORTestMessageTag, CBORTestMessageId) {}

protected:
MessageDecoder::Status decode(CborValue* iter, Message *msg) override {
CBORTestMessage* test = (CBORTestMessage*) msg;
size_t dest_size = 20;

if(!cbor_value_is_text_string(iter)) {
return MessageDecoder::Status::Error;
}

// NOTE: keep in mind that _cbor_value_copy_string tries to put a \0 at the end of the string
if(_cbor_value_copy_string(iter, test->parameter, &dest_size, NULL) != CborNoError) {
return MessageDecoder::Status::Error;
}

return MessageDecoder::Status::Complete;
}
} customMessageDecoder;

SCENARIO( "A custom decoder is defined", "[cbor][decode]" ) {
CBORMessageDecoder decoder;
GIVEN( "A buffer containing a cbor encoded message" ) {
CBORTestMessage expected_result {
CBORTestMessageId,
"abcdef",
};

uint8_t buffer[] {
0xD9, 0x03, 0x21, 0x81, 0x66, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
};
size_t buffer_len = sizeof(buffer);

CBORTestMessage cmd_res;

MessageDecoder::Status res = decoder.decode((Message*)&cmd_res, buffer, buffer_len);

THEN( "Message decode result is Complete" ) {
REQUIRE(res == MessageDecoder::Status::Complete);
}

THEN( "the decode result matches the expectations" ) {
REQUIRE(buffer_len == sizeof(buffer));

REQUIRE(expected_result.m.id == cmd_res.m.id);

std::string parameter_expected(expected_result.parameter);
std::string parameter_result(cmd_res.parameter);

REQUIRE_THAT(parameter_result, Catch::Matchers::Equals(parameter_expected));
}
}
}
79 changes: 79 additions & 0 deletions extras/test/src/cbor/test_cbor_encoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
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/MessageEncoder.h>

enum : MessageId {
CBORTestMessageId = 0x0123,
};

enum : CBORTag {
CBORTestMessageTag = 0x0321,
};


struct CBORTestMessage {
Message m;
char parameter[20];
};

class CustomMessageEncoder: public CBORMessageEncoderInterface {
public:
CustomMessageEncoder()
: CBORMessageEncoderInterface(CBORTestMessageTag, CBORTestMessageId) {}

protected:
MessageEncoder::Status encode(CborEncoder* encoder, Message *msg) override {
CBORTestMessage * testMessage = (CBORTestMessage *) 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, testMessage->parameter) != CborNoError) {
return MessageEncoder::Status::Error;
}

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

SCENARIO( "A custom encoder is defined", "[cbor][encode]" ) {
CBORMessageEncoder encoder;
uint8_t buffer[100]; // shared buffer for encoding
const size_t buf_len = sizeof(buffer);

GIVEN( "A Message with an id that the global encoder is able to encode" ) {
CBORTestMessage cmd {
CBORTestMessageId,
"abcdef",
};
size_t res_len=buf_len;
MessageEncoder::Status res = encoder.encode((Message*)&cmd, buffer, res_len);

THEN( "Message encode result is Complete" ) {
REQUIRE(res == MessageEncoder::Status::Complete);
}

THEN( "the encode result matches the expectations" ) {
std::vector<uint8_t> res(buffer, buffer+res_len);

REQUIRE_THAT(res, Catch::Matchers::Equals(std::vector<uint8_t>{
0xD9, 0x03, 0x21, 0x81, 0x66, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
}));
}
}
}
13 changes: 13 additions & 0 deletions src/Arduino_CBOR.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
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/.
*/
#pragma once

#include "./cbor/MessageEncoder.h"
#include "./cbor/MessageDecoder.h"
2 changes: 1 addition & 1 deletion src/Arduino_TinyCBOR.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
*/
#pragma once

#include "./tinycbor/cbor-lib.h"
#include "./cbor/tinycbor/cbor-lib.h"
Loading
Loading