From a1bb1b7c1414e33125cd918e0e67dc35b9538d6b Mon Sep 17 00:00:00 2001
From: kreber <hugo.kreber@b-com.com>
Date: Mon, 1 Jul 2024 17:16:53 +0200
Subject: [PATCH] Patches for keyvalueTags and payload

---
 EtsiClientGen/patches/applyPatches.sh       |   1 +
 EtsiClientGen/patches/fixCRelocInfo.patch   |  46 ++++++
 EtsiClientGen/patches/fixCTrackable.patch   | 164 +++++++++++++-------
 EtsiClientGen/patches/fixCWorldAnchor.patch | 119 ++++++++++----
 EtsiClientGen/patches/fixCWorldLink.patch   | 133 +++++++++++-----
 5 files changed, 337 insertions(+), 126 deletions(-)
 create mode 100644 EtsiClientGen/patches/fixCRelocInfo.patch

diff --git a/EtsiClientGen/patches/applyPatches.sh b/EtsiClientGen/patches/applyPatches.sh
index 4828617..dec3ac5 100755
--- a/EtsiClientGen/patches/applyPatches.sh
+++ b/EtsiClientGen/patches/applyPatches.sh
@@ -14,6 +14,7 @@ patch -u ../model/trackable_type.h -i fixHeaderTrackableType.patch
 patch -u ../model/unit_system.h -i fixHeaderUnitSystem.patch
 patch -u ../model/world_link.h -i fixHeaderWorldLink.patch
 patch -u ../api/RelocalizationInformationAPI.c -i fixRelocalizationInformationAPI.patch
+patch -u ../model/relocalization_information.c -i fixCRelocInfo.patch
 patch -u ../model/unit_system.c -i fixCUnitSystem.patch
 patch -u ../model/type_world_storage.c -i fixCTypeWorldStorage.patch
 patch -u ../model/type_world_storage.h -i fixHeaderTypeWorldStorage.patch
diff --git a/EtsiClientGen/patches/fixCRelocInfo.patch b/EtsiClientGen/patches/fixCRelocInfo.patch
new file mode 100644
index 0000000..b21037a
--- /dev/null
+++ b/EtsiClientGen/patches/fixCRelocInfo.patch
@@ -0,0 +1,46 @@
+diff --git a/EtsiClientGen/model/relocalization_information.c b/../../world-storage-c-client/EtsiClientGen/model/relocalization_information.c
+index 910561e..f527502 100644
+--- a/EtsiClientGen/model/relocalization_information.c
++++ b/../../world-storage-c-client/EtsiClientGen/model/relocalization_information.c
+@@ -75,11 +75,17 @@ cJSON *relocalization_information_convertToJSON(relocalization_information_t *re
+ 
+     // relocalization_information->request_type
+     if(relocalization_information->request_type != world_storage_api_relocalization_information__NULL) {
+-    cJSON *request_type_local_JSON = type_world_storage_convertToJSON(relocalization_information->request_type);
++    cJSON *request_type_local_JSON = type_world_storage_type_world_storage_convertToJSON(*relocalization_information->request_type);
+     if(request_type_local_JSON == NULL) {
+         goto fail; // custom
+     }
+-    cJSON_AddItemToObject(item, "requestType", request_type_local_JSON);
++    char *type_str = cJSON_GetStringValue(request_type_local_JSON);
++    if (type_str == NULL) {
++        goto fail;
++    }
++    if (cJSON_AddStringToObject(item, "requestType", type_str) == NULL) {
++        goto fail;
++    }
+     if(item->child == NULL) {
+         goto fail;
+     }
+@@ -96,7 +102,7 @@ cJSON *relocalization_information_convertToJSON(relocalization_information_t *re
+     listEntry_t *reloc_objectsListEntry;
+     if (relocalization_information->reloc_objects) {
+     list_ForEach(reloc_objectsListEntry, relocalization_information->reloc_objects) {
+-    cJSON *itemLocal = relocalization_information_reloc_objects_inner_convertToJSON(reloc_objectsListEntry->data);
++    cJSON *itemLocal = relocalization_information_reloc_objects_inner_convertToJSON((relocalization_information_reloc_objects_inner_t* )reloc_objectsListEntry->data);
+     if(itemLocal == NULL) {
+     goto fail;
+     }
+@@ -133,9 +139,11 @@ relocalization_information_t *relocalization_information_parseFromJSON(cJSON *re
+     }
+ 
+     // relocalization_information->request_type
++    request_type_local_nonprim = (type_world_storage_t *)malloc(sizeof(type_world_storage_t));
++
+     cJSON *request_type = cJSON_GetObjectItemCaseSensitive(relocalization_informationJSON, "requestType");
+     if (request_type) { 
+-    request_type_local_nonprim = type_world_storage_parseFromJSON(request_type); //custom
++    *request_type_local_nonprim = type_world_storage_type_world_storage_parseFromJSON(request_type); //custom
+     }
+ 
+     // relocalization_information->reloc_objects
diff --git a/EtsiClientGen/patches/fixCTrackable.patch b/EtsiClientGen/patches/fixCTrackable.patch
index 96bd045..f169d17 100644
--- a/EtsiClientGen/patches/fixCTrackable.patch
+++ b/EtsiClientGen/patches/fixCTrackable.patch
@@ -1,5 +1,5 @@
 diff --git a/EtsiClientGen/model/trackable.c b/../../world-storage-c-client/EtsiClientGen/model/trackable.c
-index 1a27417..f26b4d7 100644
+index 1a27417..0270bbc 100644
 --- a/EtsiClientGen/model/trackable.c
 +++ b/../../world-storage-c-client/EtsiClientGen/model/trackable.c
 @@ -3,42 +3,6 @@
@@ -83,23 +83,6 @@ index 1a27417..f26b4d7 100644
  
      // trackable->trackable_encoding_information
      if (!trackable->trackable_encoding_information) {
-@@ -188,14 +160,14 @@ cJSON *trackable_convertToJSON(trackable_t *trackable) {
-     goto fail;
-     }
- 
--
-+/*
-     // trackable->trackable_payload
-     if (!trackable->trackable_payload) {
-         goto fail;
-     }
-     if(cJSON_AddStringToObject(item, "trackablePayload", trackable->trackable_payload) == NULL) {
-     goto fail; //ByteArray
--    }
-+    }*/
- 
- 
-     // trackable->local_crs
 @@ -217,14 +189,21 @@ cJSON *trackable_convertToJSON(trackable_t *trackable) {
  
  
@@ -125,7 +108,7 @@ index 1a27417..f26b4d7 100644
      if(item->child == NULL) {
          goto fail;
      }
-@@ -243,11 +222,12 @@ cJSON *trackable_convertToJSON(trackable_t *trackable) {
+@@ -243,28 +222,31 @@ cJSON *trackable_convertToJSON(trackable_t *trackable) {
      list_ForEach(trackable_sizeListEntry, trackable->trackable_size) {
      if(cJSON_AddNumberToObject(trackable_size, "", *(double *)trackable_sizeListEntry->data) == NULL)
      {
@@ -135,20 +118,44 @@ index 1a27417..f26b4d7 100644
      }
  
 -
-+    /*
-     // trackable->keyvalue_tags
-     if (!trackable->keyvalue_tags) {
-         goto fail;
-@@ -262,7 +242,7 @@ cJSON *trackable_convertToJSON(trackable_t *trackable) {
-     list_ForEach(keyvalue_tagsListEntry, trackable->keyvalue_tags) {
-         keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
-     }
+-    // trackable->keyvalue_tags
+-    if (!trackable->keyvalue_tags) {
+-        goto fail;
 -    }
-+    }*/
- 
+-    cJSON *keyvalue_tags = cJSON_AddObjectToObject(item, "keyvalueTags");
+-    if(keyvalue_tags == NULL) {
+-        goto fail; //primitive map container
+-    }
+-    cJSON *localMapObject = keyvalue_tags;
+-    listEntry_t *keyvalue_tagsListEntry;
++ // trackable->keyvalue_tags
+     if (trackable->keyvalue_tags) {
+-    list_ForEach(keyvalue_tagsListEntry, trackable->keyvalue_tags) {
+-        keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
+-    }
++        cJSON *keyvalue_tags_JSON = cJSON_CreateObject();
++        listEntry_t *listEntry = NULL;
++        list_ForEach(listEntry, trackable->keyvalue_tags) {
++            
++            keyValuePair_t *pair = (keyValuePair_t *)listEntry->data;
++            if (pair && pair->value) {
++                cJSON *values_array = cJSON_CreateArray();
++                listEntry_t *valueEntry = NULL;
++                list_ForEach(valueEntry, (list_t*)pair->value) {
++                    char *value = (char *)valueEntry->data;
++                    cJSON_AddItemToArray(values_array, cJSON_CreateString(value));
++                }
++                cJSON_AddItemToObject(keyvalue_tags_JSON, pair->key, values_array);
++            }
++        }
++        cJSON_AddItemToObject(item, "keyvalueTags", keyvalue_tags_JSON);
+     }
  
+-
      // trackable->confidence
-@@ -305,12 +285,16 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+     if(trackable->confidence) {
+     if(cJSON_AddNumberToObject(item, "confidence", trackable->confidence) == NULL) {
+@@ -305,12 +287,16 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      // trackable->uuid
      cJSON *uuid = cJSON_GetObjectItemCaseSensitive(trackableJSON, "UUID");
      if (uuid) { 
@@ -166,7 +173,7 @@ index 1a27417..f26b4d7 100644
      // trackable->name
      cJSON *name = cJSON_GetObjectItemCaseSensitive(trackableJSON, "name");
      if (!name) {
-@@ -322,7 +306,6 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -322,7 +308,6 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      {
      goto end; //String
      }
@@ -174,7 +181,7 @@ index 1a27417..f26b4d7 100644
      // trackable->creator_uuid
      cJSON *creator_uuid = cJSON_GetObjectItemCaseSensitive(trackableJSON, "creatorUUID");
      if (!creator_uuid) {
-@@ -334,7 +317,7 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -334,7 +319,7 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      {
      goto end; //String
      }
@@ -183,7 +190,7 @@ index 1a27417..f26b4d7 100644
      // trackable->trackable_type
      cJSON *trackable_type = cJSON_GetObjectItemCaseSensitive(trackableJSON, "trackableType");
      if (!trackable_type) {
-@@ -342,35 +325,38 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -342,27 +327,30 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      }
  
      
@@ -201,9 +208,8 @@ index 1a27417..f26b4d7 100644
      trackable_encoding_information_local_nonprim = encoding_information_structure_parseFromJSON(trackable_encoding_information); //nonprimitive
 -
      // trackable->trackable_payload
--    cJSON *trackable_payload = cJSON_GetObjectItemCaseSensitive(trackableJSON, "trackablePayload");
+     cJSON *trackable_payload = cJSON_GetObjectItemCaseSensitive(trackableJSON, "trackablePayload");
 -    if (!trackable_payload) {
-+   /* cJSON *trackable_payload = cJSON_GetObjectItemCaseSensitive(trackableJSON, "trackablePayload");
 +    
 +     if (!trackable_payload) {
          goto end;
@@ -216,12 +222,11 @@ index 1a27417..f26b4d7 100644
      if(!cJSON_IsString(trackable_payload))
      {
      goto end; //ByteArray
--    }
++
+     }
  
-+    }
-+*/
      // trackable->local_crs
-     cJSON *local_crs = cJSON_GetObjectItemCaseSensitive(trackableJSON, "localCRS");
+@@ -370,7 +358,7 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      if (!local_crs) {
          goto end;
      }
@@ -230,7 +235,7 @@ index 1a27417..f26b4d7 100644
      
      cJSON *local_crs_local = NULL;
      if(!cJSON_IsArray(local_crs)) {
-@@ -392,15 +378,15 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -392,15 +380,15 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
          *local_crs_local_value = local_crs_local->valuedouble;
          list_addElement(local_crsList , local_crs_local_value);
      }
@@ -248,25 +253,76 @@ index 1a27417..f26b4d7 100644
  
      // trackable->trackable_size
      cJSON *trackable_size = cJSON_GetObjectItemCaseSensitive(trackableJSON, "trackableSize");
-@@ -429,7 +415,7 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -429,30 +417,49 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
          *trackable_size_local_value = trackable_size_local->valuedouble;
          list_addElement(trackable_sizeList , trackable_size_local_value);
      }
 -
-+     /*
++     
      // trackable->keyvalue_tags
-     cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(trackableJSON, "keyvalueTags");
-     if (!keyvalue_tags) {
-@@ -452,7 +438,7 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
-             list_addElement(keyvalue_tagsList , localMapKeyPair);
+-    cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(trackableJSON, "keyvalueTags");
+-    if (!keyvalue_tags) {
+-        goto end;
+-    }
+ 
+-    
+-    cJSON *keyvalue_tags_local_map = NULL;
+-    if(!cJSON_IsObject(keyvalue_tags) && !cJSON_IsNull(keyvalue_tags))
+-    {
+-        goto end;//primitive map container
+-    }
+-    if(cJSON_IsObject(keyvalue_tags))
+-    {
++    cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(trackableJSON, "keyvalueTags");
++    if (keyvalue_tags) {
++        if (!cJSON_IsObject(keyvalue_tags)) {
++            goto end;
++        }
+         keyvalue_tagsList = list_createList();
+-        keyValuePair_t *localMapKeyPair;
+-        cJSON_ArrayForEach(keyvalue_tags_local_map, keyvalue_tags)
+-        {
+-            cJSON *localMapObject = keyvalue_tags_local_map;
+-            list_addElement(keyvalue_tagsList , localMapKeyPair);
++        if (!keyvalue_tagsList) {
++            goto end;
++        }
++        cJSON *key = NULL;
++        cJSON_ArrayForEach(key, keyvalue_tags) {
++            if (cJSON_IsArray(key)) {
++                list_t *valuesList = list_createList();
++                if (!valuesList) {
++                    goto end;
++                }
++                cJSON *value = NULL;
++                cJSON_ArrayForEach(value, key) {
++                    if (cJSON_IsString(value)) {
++                        char *valueString = strdup(value->valuestring);
++                        if (!valueString) {
++                            goto end;
++                        }
++                        list_addElement(valuesList, valueString);
++                    }
++                }
++                keyValuePair_t *pair = malloc(sizeof(keyValuePair_t));
++                if (!pair) {
++                    goto end;
++                }
++                pair->key = strdup(key->string);
++                if (!pair->key) {
++                    free(pair);
++                    goto end;
++                }
++                pair->value = valuesList;
++                list_addElement(keyvalue_tagsList, pair);
++            }
          }
      }
 -
-+     */
      // trackable->confidence
      cJSON *confidence = cJSON_GetObjectItemCaseSensitive(trackableJSON, "confidence");
      if (confidence) { 
-@@ -462,25 +448,24 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
+@@ -462,7 +469,6 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
      }
      }
  
@@ -274,17 +330,11 @@ index 1a27417..f26b4d7 100644
      trackable_local_var = trackable_create (
          uuid && !cJSON_IsNull(uuid) ? strdup(uuid->valuestring) : NULL,
          strdup(name->valuestring),
-         strdup(creator_uuid->valuestring),
-         trackable_type_local_nonprim,
-         trackable_encoding_information_local_nonprim,
--        strdup(trackable_payload->valuestring),
-+        NULL,//strdup(trackable_payload->valuestring),
-         local_crsList,
+@@ -474,13 +480,13 @@ trackable_t *trackable_parseFromJSON(cJSON *trackableJSON){
          unit_local_nonprim,
          trackable_sizeList,
--        keyvalue_tagsList,
+         keyvalue_tagsList,
 -        confidence ? confidence->valuedouble : 0
-+        NULL,//keyvalue_tagsList,
 +        confidence ? confidence->valuedouble : 0.0
          );
  
@@ -296,7 +346,7 @@ index 1a27417..f26b4d7 100644
          trackable_type_local_nonprim = NULL;
      }
      if (trackable_encoding_information_local_nonprim) {
-@@ -497,7 +482,7 @@ end:
+@@ -497,7 +503,7 @@ end:
          local_crsList = NULL;
      }
      if (unit_local_nonprim) {
diff --git a/EtsiClientGen/patches/fixCWorldAnchor.patch b/EtsiClientGen/patches/fixCWorldAnchor.patch
index 444a62e..466b5aa 100644
--- a/EtsiClientGen/patches/fixCWorldAnchor.patch
+++ b/EtsiClientGen/patches/fixCWorldAnchor.patch
@@ -1,5 +1,5 @@
 diff --git a/EtsiClientGen/model/world_anchor.c b/../../world-storage-c-client/EtsiClientGen/model/world_anchor.c
-index 5e8a79c..7af4a19 100644
+index 5e8a79c..6834828 100644
 --- a/EtsiClientGen/model/world_anchor.c
 +++ b/../../world-storage-c-client/EtsiClientGen/model/world_anchor.c
 @@ -146,16 +146,23 @@ cJSON *world_anchor_convertToJSON(world_anchor_t *world_anchor) {
@@ -28,40 +28,45 @@ index 5e8a79c..7af4a19 100644
      // world_anchor->world_anchor_size
      if (!world_anchor->world_anchor_size) {
          goto fail;
-@@ -173,22 +180,24 @@ cJSON *world_anchor_convertToJSON(world_anchor_t *world_anchor) {
+@@ -173,21 +180,24 @@ cJSON *world_anchor_convertToJSON(world_anchor_t *world_anchor) {
      }
      }
  
 -
      // world_anchor->keyvalue_tags
 -    if (!world_anchor->keyvalue_tags) {
-+   /* if (!world_anchor->keyvalue_tags) {
-         goto fail;
-     }
-     cJSON *keyvalue_tags = cJSON_AddObjectToObject(item, "keyvalueTags");
+-        goto fail;
+-    }
+-    cJSON *keyvalue_tags = cJSON_AddObjectToObject(item, "keyvalueTags");
 -    if(keyvalue_tags == NULL) {
 -        goto fail; //primitive map container
-+    if (keyvalue_tags == NULL) {
-+        goto fail; // primitive map container
-     }
--    cJSON *localMapObject = keyvalue_tags;
-     listEntry_t *keyvalue_tagsListEntry;
--    if (world_anchor->keyvalue_tags) {
-     list_ForEach(keyvalue_tagsListEntry, world_anchor->keyvalue_tags) {
-         keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
 -    }
+-    cJSON *localMapObject = keyvalue_tags;
+-    listEntry_t *keyvalue_tagsListEntry;
+     if (world_anchor->keyvalue_tags) {
+-    list_ForEach(keyvalue_tagsListEntry, world_anchor->keyvalue_tags) {
+-        keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
 -    }
-+        if (localKeyValue == NULL || localKeyValue->key == NULL || localKeyValue->value == NULL) {
-+            goto fail;
++        cJSON *keyvalue_tags_JSON = cJSON_CreateObject();
++        listEntry_t *listEntry = NULL;
++        list_ForEach(listEntry, world_anchor->keyvalue_tags) {
++            
++            keyValuePair_t *pair = (keyValuePair_t *)listEntry->data;
++            if (pair && pair->value) {
++                cJSON *values_array = cJSON_CreateArray();
++                listEntry_t *valueEntry = NULL;
++                list_ForEach(valueEntry, (list_t*)pair->value) {
++                    char *value = (char *)valueEntry->data;
++                    cJSON_AddItemToArray(values_array, cJSON_CreateString(value));
++                }
++                cJSON_AddItemToObject(keyvalue_tags_JSON, pair->key, values_array);
++            }
 +        }
-+        //if (cJSON_AddStringToObject(keyvalue_tags, localKeyValue->key, (char *)localKeyValue->value) == NULL) {
-+        //    goto fail; // add key-value pair
-+        //}
-+    }*/
++        cJSON_AddItemToObject(item, "keyvalueTags", keyvalue_tags_JSON);
+     }
  
      return item;
- fail:
-@@ -276,13 +285,14 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
+@@ -276,13 +286,14 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
      }
  
      // world_anchor->unit
@@ -77,31 +82,77 @@ index 5e8a79c..7af4a19 100644
  
      // world_anchor->world_anchor_size
      cJSON *world_anchor_size = cJSON_GetObjectItemCaseSensitive(world_anchorJSON, "worldAnchorSize");
-@@ -313,7 +323,7 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
-     }
+@@ -314,28 +325,45 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
  
      // world_anchor->keyvalue_tags
--    cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_anchorJSON, "keyvalueTags");
-+  /*  cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_anchorJSON, "keyvalueTags");
-     if (!keyvalue_tags) {
-         goto end;
-     }
-@@ -334,8 +344,7 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
-             list_addElement(keyvalue_tagsList , localMapKeyPair);
+     cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_anchorJSON, "keyvalueTags");
+-    if (!keyvalue_tags) {
+-        goto end;
+-    }
+-
+-    
+-    cJSON *keyvalue_tags_local_map = NULL;
+-    if(!cJSON_IsObject(keyvalue_tags) && !cJSON_IsNull(keyvalue_tags))
+-    {
+-        goto end;//primitive map container
+-    }
+-    if(cJSON_IsObject(keyvalue_tags))
+-    {
++    if (keyvalue_tags) {
++        if (!cJSON_IsObject(keyvalue_tags)) {
++            goto end;
++        }
+         keyvalue_tagsList = list_createList();
+-        keyValuePair_t *localMapKeyPair;
+-        cJSON_ArrayForEach(keyvalue_tags_local_map, keyvalue_tags)
+-        {
+-            cJSON *localMapObject = keyvalue_tags_local_map;
+-            list_addElement(keyvalue_tagsList , localMapKeyPair);
++        if (!keyvalue_tagsList) {
++            goto end;
++        }
++        cJSON *key = NULL;
++        cJSON_ArrayForEach(key, keyvalue_tags) {
++            if (cJSON_IsArray(key)) {
++                list_t *valuesList = list_createList();
++                if (!valuesList) {
++                    goto end;
++                }
++                cJSON *value = NULL;
++                cJSON_ArrayForEach(value, key) {
++                    if (cJSON_IsString(value)) {
++                        char *valueString = strdup(value->valuestring);
++                        if (!valueString) {
++                            goto end;
++                        }
++                        list_addElement(valuesList, valueString);
++                    }
++                }
++                keyValuePair_t *pair = malloc(sizeof(keyValuePair_t));
++                if (!pair) {
++                    goto end;
++                }
++                pair->key = strdup(key->string);
++                if (!pair->key) {
++                    free(pair);
++                    goto end;
++                }
++                pair->value = valuesList;
++                list_addElement(keyvalue_tagsList, pair);
++            }
          }
      }
 -
 -
-+*/
      world_anchor_local_var = world_anchor_create (
          uuid && !cJSON_IsNull(uuid) ? strdup(uuid->valuestring) : NULL,
          strdup(name->valuestring),
-@@ -343,7 +352,7 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
+@@ -343,7 +371,7 @@ world_anchor_t *world_anchor_parseFromJSON(cJSON *world_anchorJSON){
          local_crsList,
          unit_local_nonprim,
          world_anchor_sizeList,
 -        keyvalue_tagsList
-+       NULL// keyvalue_tagsList
++       keyvalue_tagsList
          );
  
      return world_anchor_local_var;
diff --git a/EtsiClientGen/patches/fixCWorldLink.patch b/EtsiClientGen/patches/fixCWorldLink.patch
index 9bc7203..addc655 100644
--- a/EtsiClientGen/patches/fixCWorldLink.patch
+++ b/EtsiClientGen/patches/fixCWorldLink.patch
@@ -1,5 +1,5 @@
 diff --git a/EtsiClientGen/model/world_link.c b/../../world-storage-c-client/EtsiClientGen/model/world_link.c
-index 82f9653..102a149 100644
+index 82f9653..ab1d354 100644
 --- a/EtsiClientGen/model/world_link.c
 +++ b/../../world-storage-c-client/EtsiClientGen/model/world_link.c
 @@ -4,58 +4,6 @@
@@ -161,7 +161,7 @@ index 82f9653..102a149 100644
  
      // world_link->transform
      if (!world_link->transform) {
-@@ -221,21 +195,28 @@ cJSON *world_link_convertToJSON(world_link_t *world_link) {
+@@ -221,36 +195,47 @@ cJSON *world_link_convertToJSON(world_link_t *world_link) {
      }
      }
  
@@ -178,33 +178,55 @@ index 82f9653..102a149 100644
          goto fail; // custom
      }
 -    cJSON_AddItemToObject(item, "unit", unit_local_JSON);
+-    if(item->child == NULL) {
 +    char *unit_str = cJSON_GetStringValue(unit_local_JSON);
 +    if (unit_str == NULL) {
-+        goto fail;
-+    }
-+    if (cJSON_AddStringToObject(item, "unit", unit_str) == NULL) {
-+        goto fail;
-+    }
-     if(item->child == NULL) {
          goto fail;
      }
 -
 -
-+        
-+/*
-     // world_link->keyvalue_tags
-     if (!world_link->keyvalue_tags) {
+-    // world_link->keyvalue_tags
+-    if (!world_link->keyvalue_tags) {
++    if (cJSON_AddStringToObject(item, "unit", unit_str) == NULL) {
          goto fail;
-@@ -250,7 +231,7 @@ cJSON *world_link_convertToJSON(world_link_t *world_link) {
-     list_ForEach(keyvalue_tagsListEntry, world_link->keyvalue_tags) {
-         keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
      }
+-    cJSON *keyvalue_tags = cJSON_AddObjectToObject(item, "keyvalueTags");
+-    if(keyvalue_tags == NULL) {
+-        goto fail; //primitive map container
++    if(item->child == NULL) {
++        goto fail;
+     }
+-    cJSON *localMapObject = keyvalue_tags;
+-    listEntry_t *keyvalue_tagsListEntry;
++        
++
++    // world_link->keyvalue_tags
+     if (world_link->keyvalue_tags) {
+-    list_ForEach(keyvalue_tagsListEntry, world_link->keyvalue_tags) {
+-        keyValuePair_t *localKeyValue = (keyValuePair_t*)keyvalue_tagsListEntry->data;
+-    }
 -    }
-+    }*/
++            cJSON *keyvalue_tags_JSON = cJSON_CreateObject();
++            listEntry_t *listEntry = NULL;
++            list_ForEach(listEntry, world_link->keyvalue_tags) {
++                
++                keyValuePair_t *pair = (keyValuePair_t *)listEntry->data;
++                if (pair && pair->value) {
++                    cJSON *values_array = cJSON_CreateArray();
++                    listEntry_t *valueEntry = NULL;
++                    list_ForEach(valueEntry, (list_t*)pair->value) {
++                        char *value = (char *)valueEntry->data;
++                        cJSON_AddItemToArray(values_array, cJSON_CreateString(value));
++                    }
++                    cJSON_AddItemToObject(keyvalue_tags_JSON, pair->key, values_array);
++                }
++            }
++            cJSON_AddItemToObject(item, "keyvalueTags", keyvalue_tags_JSON);
++        }
  
      return item;
  fail:
-@@ -325,22 +306,24 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
+@@ -325,22 +310,24 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
      }
  
      // world_link->type_from
@@ -231,7 +253,7 @@ index 82f9653..102a149 100644
  
      // world_link->transform
      cJSON *transform = cJSON_GetObjectItemCaseSensitive(world_linkJSON, "transform");
-@@ -371,16 +354,17 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
+@@ -371,38 +358,56 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
      }
  
      // world_link->unit
@@ -247,28 +269,69 @@ index 82f9653..102a149 100644
 +   *unit_local_nonprim = unit_system_unit_system_parseFromJSON(unit); //custom
 +    
      // world_link->keyvalue_tags
--    cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_linkJSON, "keyvalueTags");
-+   /* cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_linkJSON, "keyvalueTags");
-     if (!keyvalue_tags) {
-         goto end;
-     }
-@@ -402,7 +386,7 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
+     cJSON *keyvalue_tags = cJSON_GetObjectItemCaseSensitive(world_linkJSON, "keyvalueTags");
+-    if (!keyvalue_tags) {
+-        goto end;
+-    }
+-
+-    
+-    cJSON *keyvalue_tags_local_map = NULL;
+-    if(!cJSON_IsObject(keyvalue_tags) && !cJSON_IsNull(keyvalue_tags))
+-    {
+-        goto end;//primitive map container
+-    }
+-    if(cJSON_IsObject(keyvalue_tags))
+-    {
++    if (keyvalue_tags) {
++        if (!cJSON_IsObject(keyvalue_tags)) {
++            goto end;
++        }
+         keyvalue_tagsList = list_createList();
+-        keyValuePair_t *localMapKeyPair;
+-        cJSON_ArrayForEach(keyvalue_tags_local_map, keyvalue_tags)
+-        {
+-            cJSON *localMapObject = keyvalue_tags_local_map;
+-            list_addElement(keyvalue_tagsList , localMapKeyPair);
++        if (!keyvalue_tagsList) {
++            goto end;
++        }
++        cJSON *key = NULL;
++        cJSON_ArrayForEach(key, keyvalue_tags) {
++            if (cJSON_IsArray(key)) {
++                list_t *valuesList = list_createList();
++                if (!valuesList) {
++                    goto end;
++                }
++                cJSON *value = NULL;
++                cJSON_ArrayForEach(value, key) {
++                    if (cJSON_IsString(value)) {
++                        char *valueString = strdup(value->valuestring);
++                        if (!valueString) {
++                            goto end;
++                        }
++                        list_addElement(valuesList, valueString);
++                    }
++                }
++                keyValuePair_t *pair = malloc(sizeof(keyValuePair_t));
++                if (!pair) {
++                    goto end;
++                }
++                pair->key = strdup(key->string);
++                if (!pair->key) {
++                    free(pair);
++                    goto end;
++                }
++                pair->value = valuesList;
++                list_addElement(keyvalue_tagsList, pair);
++            }
          }
      }
- 
 -
-+*/
+-
      world_link_local_var = world_link_create (
          uuid && !cJSON_IsNull(uuid) ? strdup(uuid->valuestring) : NULL,
          strdup(creator_uuid->valuestring),
-@@ -412,17 +396,17 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
-         type_to_local_nonprim,
-         transformList,
-         unit_local_nonprim,
--        keyvalue_tagsList
-+        NULL//  keyvalue_tagsList
-         );
- 
+@@ -418,11 +423,11 @@ world_link_t *world_link_parseFromJSON(cJSON *world_linkJSON){
      return world_link_local_var;
  end:
      if (type_from_local_nonprim) {
@@ -282,7 +345,7 @@ index 82f9653..102a149 100644
          type_to_local_nonprim = NULL;
      }
      if (transformList) {
-@@ -435,7 +419,7 @@ end:
+@@ -435,7 +440,7 @@ end:
          transformList = NULL;
      }
      if (unit_local_nonprim) {
-- 
GitLab