From eb1c163b7a599658beacd60047c0eda14619f8c2 Mon Sep 17 00:00:00 2001
From: Andrea Gilardoni <a.gilardoni@arduino.cc>
Date: Fri, 9 May 2025 11:21:28 +0200
Subject: [PATCH 1/3] Removing copyCBORStringToArray and copyCBORStringToArray
 utility functions in favor of cloud utils defined

---
 src/cbor/IoTCloudMessageDecoder.cpp | 85 +++++++++++++++++------------
 1 file changed, 49 insertions(+), 36 deletions(-)

diff --git a/src/cbor/IoTCloudMessageDecoder.cpp b/src/cbor/IoTCloudMessageDecoder.cpp
index e25962219..8a17ba1f3 100644
--- a/src/cbor/IoTCloudMessageDecoder.cpp
+++ b/src/cbor/IoTCloudMessageDecoder.cpp
@@ -15,30 +15,9 @@
 #include <Arduino.h>
 
 #include "IoTCloudMessageDecoder.h"
+#include <cbor/utils/decoder.h>
 #include <AIoTC_Config.h>
 
-static inline bool copyCBORStringToArray(CborValue * param, char * dest, size_t dest_size) {
-  if (cbor_value_is_text_string(param)) {
-    // 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(param, dest, &dest_size, NULL) == CborNoError) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-static inline size_t copyCBORByteToArray(CborValue * param, uint8_t * dest, size_t dest_size) {
-  if (cbor_value_is_byte_string(param)) {
-    // 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(param, dest, &dest_size, NULL) == CborNoError) {
-      return dest_size;
-    }
-  }
-
-  return 0;
-}
-
 /******************************************************************************
     MESSAGE DECODE FUNCTIONS
  ******************************************************************************/
@@ -46,8 +25,12 @@ static inline size_t copyCBORByteToArray(CborValue * param, uint8_t * dest, size
 MessageDecoder::Status ThingUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
   ThingUpdateCmd * thingCommand = (ThingUpdateCmd *) msg;
 
+  size_t dest_size = sizeof(thingCommand->params.thing_id);
+
   // Message is composed of a single parameter, a string (thing_id)
-  if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
+  if (cbor::utils::copyCBORStringToArray(
+      iter, thingCommand->params.thing_id,
+      dest_size) == MessageDecoder::Status::Error) {
     return MessageDecoder::Status::Error;
   }
 
@@ -57,8 +40,14 @@ MessageDecoder::Status ThingUpdateCommandDecoder::decode(CborValue* iter, Messag
 MessageDecoder::Status ThingDetachCommandDecoder::decode(CborValue* iter, Message *msg) {
   ThingDetachCmd * thingCommand = (ThingDetachCmd *) msg;
 
+  size_t dest_size = sizeof(thingCommand->params.thing_id);
+
+
   // Message is composed of a single parameter, a string (thing_id)
-  if (!copyCBORStringToArray(iter, thingCommand->params.thing_id, sizeof(thingCommand->params.thing_id))) {
+  if (cbor::utils::copyCBORStringToArray(
+      iter,
+      thingCommand->params.thing_id,
+      dest_size) == MessageDecoder::Status::Error) {
     return MessageDecoder::Status::Error;
   }
 
@@ -125,33 +114,57 @@ MessageDecoder::Status LastValuesUpdateCommandDecoder::decode(CborValue* iter, M
 }
 
 MessageDecoder::Status OtaUpdateCommandDecoder::decode(CborValue* iter, Message *msg) {
-  CborError error = CborNoError;
   OtaUpdateCmdDown * ota = (OtaUpdateCmdDown *) msg;
+  size_t dest_size = sizeof(ota->params.id);
 
   // Message is composed 4 parameters: id, url, initialSha, finalSha
-  if (!copyCBORByteToArray(iter, ota->params.id, sizeof(ota->params.id))) {
+
+  // decoding parameter id
+  if (cbor::utils::copyCBORByteToArray(
+      iter,
+      ota->params.id,
+      dest_size) == MessageDecoder::Status::Error) {
     return MessageDecoder::Status::Error;
   }
 
-  error = cbor_value_advance(iter);
+  // decoding parameter url
+  if(cbor_value_advance(iter) != CborNoError) {
+    return MessageDecoder::Status::Error;
+  }
+
+  dest_size = sizeof(ota->params.url);
+
+  if (cbor::utils::copyCBORStringToArray(iter,
+      ota->params.url,
+      dest_size) == MessageDecoder::Status::Error) {
+    return MessageDecoder::Status::Error;
+  }
 
-  if ((error != CborNoError) || !copyCBORStringToArray(iter, ota->params.url, sizeof(ota->params.url))) {
+  // decoding parameter initialSha256
+  if(cbor_value_advance(iter) != CborNoError) {
     return MessageDecoder::Status::Error;
   }
 
-  error = cbor_value_advance(iter);
+  dest_size = sizeof(ota->params.initialSha256);
+
+  if (cbor::utils::copyCBORByteToArray(iter,
+        ota->params.initialSha256,
+        dest_size) == MessageDecoder::Status::Error ||
+      dest_size != sizeof(ota->params.initialSha256)) {
+    return MessageDecoder::Status::Error;
+  }
 
-  if ((error != CborNoError) ||
-      copyCBORByteToArray(iter, ota->params.initialSha256,
-        sizeof(ota->params.initialSha256)) != sizeof(ota->params.initialSha256)) {
+  // decoding parameter finalSha256
+  if(cbor_value_advance(iter) != CborNoError) {
     return MessageDecoder::Status::Error;
   }
 
-  error = cbor_value_advance(iter);
+  dest_size = sizeof(ota->params.finalSha256);
 
-  if ((error != CborNoError) ||
-      copyCBORByteToArray(iter, ota->params.finalSha256,
-        sizeof(ota->params.finalSha256)) != sizeof(ota->params.finalSha256)) {
+  if (cbor::utils::copyCBORByteToArray(iter,
+        ota->params.finalSha256,
+        dest_size) == MessageDecoder::Status::Error ||
+      dest_size != sizeof(ota->params.finalSha256)) {
     return MessageDecoder::Status::Error;
   }
 

From 8404c21b5ac8fc647d5bfa8408c2dbd304e60367 Mon Sep 17 00:00:00 2001
From: Andrea Gilardoni <a.gilardoni@arduino.cc>
Date: Tue, 20 May 2025 13:29:21 +0200
Subject: [PATCH 2/3] Added cloud utils cbor/utils directory in cmake include
 path

---
 extras/test/CMakeLists.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt
index 5435dfcf1..dfe322324 100644
--- a/extras/test/CMakeLists.txt
+++ b/extras/test/CMakeLists.txt
@@ -45,6 +45,11 @@ target_include_directories(
   ${cloudutils_SOURCE_DIR}/src/cbor
 )
 
+target_include_directories(
+  cloudutils INTERFACE
+  ${cloudutils_SOURCE_DIR}/src/cbor/utils
+)
+
 target_include_directories(
   cloudutils INTERFACE
   ${cloudutils_SOURCE_DIR}/src/interfaces

From a47facc3cb9619cfc2a876e5acc09c69cca9e28e Mon Sep 17 00:00:00 2001
From: Andrea Gilardoni <a.gilardoni@arduino.cc>
Date: Wed, 21 May 2025 08:46:33 +0200
Subject: [PATCH 3/3] added unit test for OtaUpdateCmdDown message decode
 without field url

---
 extras/test/src/test_command_decode.cpp | 26 +++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/extras/test/src/test_command_decode.cpp b/extras/test/src/test_command_decode.cpp
index 8d75e6c90..1d47c99ee 100644
--- a/extras/test/src/test_command_decode.cpp
+++ b/extras/test/src/test_command_decode.cpp
@@ -667,6 +667,32 @@ SCENARIO("Test the decoding of command messages") {
     }
   }
 
+/****************************************************************************/
+
+  WHEN("Decode the OtaUpdateCmdDown message without url field")
+  {
+    CommandDown command;
+
+    /*
+      DA 00010100                             # tag(65792)
+        80                                    # array(1)
+            50                                # bytes(16)
+              C73CB045F9C2434585AFFA36A307BFE7"\xC7<\xB0E\xF9\xC2CE\x85\xAF\xFA6\xA3\a\xBF\xE7"
+
+    */
+    uint8_t const payload[] = {0xda, 0x00, 0x01, 0x01, 0x00, 0x81, 0x50, 0xc7,
+                               0x3c, 0xb0, 0x45, 0xf9, 0xc2, 0x43, 0x45, 0x85,
+                               0xaf, 0xfa, 0x36, 0xa3, 0x07, 0xbf, 0xe7};
+
+    size_t payload_length = sizeof(payload) / sizeof(uint8_t);
+    CBORMessageDecoder decoder;
+    MessageDecoder::Status err =  decoder.decode((Message*)&command, payload, payload_length);
+
+    THEN("The decode is unsuccessful") {
+      REQUIRE(err == MessageDecoder::Status::Error);
+    }
+  }
+
   /****************************************************************************/
 
   WHEN("Decode the OtaBeginUp message")