From d5122365f40d9701b7e00993133d1b9c5e569dc7 Mon Sep 17 00:00:00 2001 From: chendejin Date: Sat, 12 Oct 2024 15:18:53 +0800 Subject: [PATCH] components/esp_matter: fix json parsing for large num --- components/esp_matter/utils/json_to_tlv.cpp | 24 +++++++++++++++------ docs/en/developing.rst | 5 +++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/components/esp_matter/utils/json_to_tlv.cpp b/components/esp_matter/utils/json_to_tlv.cpp index aa3372713..47da1431a 100644 --- a/components/esp_matter/utils/json_to_tlv.cpp +++ b/components/esp_matter/utils/json_to_tlv.cpp @@ -258,9 +258,15 @@ static esp_err_t encode_tlv_element(const cJSON *val, TLV::TLVWriter &writer, co break; } case TLVElementType::Int64: { - ESP_RETURN_ON_FALSE(val->type == cJSON_Number, ESP_ERR_INVALID_ARG, TAG, "Invalid type"); - int64_t int64_val = - (val->valueint < INT32_MAX && val->valueint > INT32_MIN) ? val->valueint : (int64_t)val->valuedouble; + ESP_RETURN_ON_FALSE(val->type == cJSON_Number || val->type == cJSON_String, ESP_ERR_INVALID_ARG, TAG, + "Invalid type"); + int64_t int64_val = 0; + if (val->type == cJSON_Number) { + int64_val = + (val->valueint < INT32_MAX && val->valueint > INT32_MIN) ? val->valueint : (int64_t)val->valuedouble; + } else { + int64_val = strtoll(val->valuestring, nullptr, 10); + } ESP_RETURN_ON_FALSE(writer.Put(tag, int64_val) == CHIP_NO_ERROR, ESP_FAIL, TAG, "Failed to encode"); break; } @@ -288,9 +294,15 @@ static esp_err_t encode_tlv_element(const cJSON *val, TLV::TLVWriter &writer, co break; } case TLVElementType::UInt64: { - ESP_RETURN_ON_FALSE(val->type == cJSON_Number, ESP_ERR_INVALID_ARG, TAG, "Invalid type"); - ESP_RETURN_ON_FALSE(val->valueint >= 0, ESP_ERR_INVALID_ARG, TAG, "Invalid range"); - uint64_t uint64_val = val->valueint < INT32_MAX ? val->valueint : (uint64_t)val->valuedouble; + ESP_RETURN_ON_FALSE(val->type == cJSON_Number || val->type == cJSON_String, ESP_ERR_INVALID_ARG, TAG, + "Invalid type"); + uint64_t uint64_val = 0; + if (val->type == cJSON_Number) { + ESP_RETURN_ON_FALSE(val->valueint >= 0, ESP_ERR_INVALID_ARG, TAG, "Invalid range"); + uint64_val = val->valueint < INT32_MAX ? val->valueint : (uint64_t)val->valuedouble; + } else { + uint64_val = strtoull(val->valuestring, nullptr, 10); + } ESP_RETURN_ON_FALSE(writer.Put(tag, uint64_val) == CHIP_NO_ERROR, ESP_FAIL, TAG, "Failed to encode"); break; } diff --git a/docs/en/developing.rst b/docs/en/developing.rst index 3ac219549..f12093511 100644 --- a/docs/en/developing.rst +++ b/docs/en/developing.rst @@ -1415,6 +1415,11 @@ For ACL attribute of AccessControl cluster, you should use the following JSON st matter esp controller write-attr 31 0 "{\"0:ARR-OBJ\":[{\"1:U8\": 5, \"2:U8\": 2, \"3:ARR-U64\": [112233], \"4:NULL\": null}, {\"1:U8\": 4, \"2:U8\": 3, \"3:ARR-U64\": [1], \"4:NULL\": null}]}" +For attributes of type uint64_t or int64_t, if the absolute value is greater than (2^53), you should use string to represent number in JSON structure for precision + :: + + matter esp controller write-attr 42 0 "{\"0:ARR-OBJ\":[{\"1:U64\": \"9007199254740993\", \"2:U8\": 0}]}" + 2.10.6 Subscribe commands ~~~~~~~~~~~~~~~~~~~~~~~~~ The ``subscribe_command`` class is used for sending subscribe commands to other end-devices. Its constructor function could accept four callback inputs: