mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
Merge branch 'feature/long_char_str' into 'main'
esp-matter: Add support for long char string and long octet string See merge request app-frameworks/esp-matter!441
This commit is contained in:
@@ -432,6 +432,23 @@ esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size)
|
||||
return attr_val;
|
||||
}
|
||||
|
||||
esp_matter_attr_val_t esp_matter_long_char_str(char *val, uint16_t data_size)
|
||||
{
|
||||
uint16_t data_size_len = 2; /* Number of bytes used to store the length */
|
||||
esp_matter_attr_val_t attr_val = {
|
||||
.type = ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING,
|
||||
.val = {
|
||||
.a = {
|
||||
.b = (uint8_t *)val,
|
||||
.s = data_size,
|
||||
.n = data_size,
|
||||
.t = (uint16_t)(data_size + data_size_len),
|
||||
},
|
||||
},
|
||||
};
|
||||
return attr_val;
|
||||
}
|
||||
|
||||
esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size)
|
||||
{
|
||||
uint16_t data_size_len = 1; /* Number of bytes used to store the length */
|
||||
@@ -449,6 +466,23 @@ esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size)
|
||||
return attr_val;
|
||||
}
|
||||
|
||||
esp_matter_attr_val_t esp_matter_long_octet_str(uint8_t *val, uint16_t data_size)
|
||||
{
|
||||
uint16_t data_size_len = 2; /* Number of bytes used to store the length */
|
||||
esp_matter_attr_val_t attr_val = {
|
||||
.type = ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING,
|
||||
.val = {
|
||||
.a = {
|
||||
.b = val,
|
||||
.s = data_size,
|
||||
.n = data_size,
|
||||
.t = (uint16_t)(data_size + data_size_len),
|
||||
},
|
||||
},
|
||||
};
|
||||
return attr_val;
|
||||
}
|
||||
|
||||
esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count)
|
||||
{
|
||||
uint16_t data_size_len = 2; /* Number of bytes used to store the length */
|
||||
@@ -598,6 +632,9 @@ static esp_err_t console_set_handler(int argc, char **argv)
|
||||
} else if (type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
|
||||
char *value = argv[3];
|
||||
val = esp_matter_char_str(value, strlen(value));
|
||||
} else if (type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING) {
|
||||
char *value = argv[3];
|
||||
val = esp_matter_long_char_str(value, strlen(value));
|
||||
} else if (type == ESP_MATTER_VAL_TYPE_BITMAP8) {
|
||||
if (matter_attribute->IsNullable()) {
|
||||
if (strncmp(argv[3], "null", sizeof("null")) == 0) {
|
||||
@@ -990,10 +1027,18 @@ static esp_matter_val_type_t get_val_type_from_attribute_type(int attribute_type
|
||||
return ESP_MATTER_VAL_TYPE_CHAR_STRING;
|
||||
break;
|
||||
|
||||
case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE:
|
||||
return ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING;
|
||||
break;
|
||||
|
||||
case ZCL_OCTET_STRING_ATTRIBUTE_TYPE:
|
||||
return ESP_MATTER_VAL_TYPE_OCTET_STRING;
|
||||
break;
|
||||
|
||||
case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE:
|
||||
return ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING;
|
||||
break;
|
||||
|
||||
case ZCL_INT8S_ATTRIBUTE_TYPE:
|
||||
return ESP_MATTER_VAL_TYPE_INT8;
|
||||
break;
|
||||
@@ -1179,6 +1224,20 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING:
|
||||
if (attribute_type) {
|
||||
*attribute_type = ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE;
|
||||
}
|
||||
if (attribute_size) {
|
||||
*attribute_size = val->val.a.t;
|
||||
}
|
||||
if (value) {
|
||||
int data_size_len = val->val.a.t - val->val.a.s;
|
||||
memcpy(value, (uint8_t *)&val->val.a.s, data_size_len);
|
||||
memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len));
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_MATTER_VAL_TYPE_OCTET_STRING:
|
||||
if (attribute_type) {
|
||||
*attribute_type = ZCL_OCTET_STRING_ATTRIBUTE_TYPE;
|
||||
@@ -1193,6 +1252,20 @@ esp_err_t get_data_from_attr_val(esp_matter_attr_val_t *val, EmberAfAttributeTyp
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING:
|
||||
if (attribute_type) {
|
||||
*attribute_type = ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE;
|
||||
}
|
||||
if (attribute_size) {
|
||||
*attribute_size = val->val.a.t;
|
||||
}
|
||||
if (value) {
|
||||
int data_size_len = val->val.a.t - val->val.a.s;
|
||||
memcpy(value, (uint8_t *)&val->val.a.s, data_size_len);
|
||||
memcpy((value + data_size_len), (uint8_t *)val->val.a.b, (*attribute_size - data_size_len));
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_MATTER_VAL_TYPE_INT8:
|
||||
case ESP_MATTER_VAL_TYPE_NULLABLE_INT8:
|
||||
if (attribute_type) {
|
||||
@@ -1466,6 +1539,15 @@ static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttri
|
||||
break;
|
||||
}
|
||||
|
||||
case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: {
|
||||
*val = esp_matter_long_char_str(NULL, 0);
|
||||
int data_size_len = val->val.a.t - val->val.a.s;
|
||||
int data_count = 0;
|
||||
memcpy(&data_count, &value[0], data_size_len);
|
||||
*val = esp_matter_long_char_str((char *)(value + data_size_len), data_count);
|
||||
break;
|
||||
}
|
||||
|
||||
case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: {
|
||||
*val = esp_matter_octet_str(NULL, 0);
|
||||
int data_size_len = val->val.a.t - val->val.a.s;
|
||||
@@ -1475,6 +1557,15 @@ static esp_err_t get_attr_val_from_data(esp_matter_attr_val_t *val, EmberAfAttri
|
||||
break;
|
||||
}
|
||||
|
||||
case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: {
|
||||
*val = esp_matter_long_octet_str(NULL, 0);
|
||||
int data_size_len = val->val.a.t - val->val.a.s;
|
||||
int data_count = 0;
|
||||
memcpy(&data_count, &value[0], data_size_len);
|
||||
*val = esp_matter_long_octet_str((value + data_size_len), data_count);
|
||||
break;
|
||||
}
|
||||
|
||||
case ZCL_INT8S_ATTRIBUTE_TYPE: {
|
||||
using Traits = chip::app::NumericAttributeTraits<int8_t>;
|
||||
Traits::StorageType attribute_value;
|
||||
@@ -1727,6 +1818,9 @@ void val_print(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_CHAR_STRING) {
|
||||
ESP_LOGI(TAG, "********** %c : Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32 "'s Attribute 0x%08" PRIX32 " is %.*s **********", action,
|
||||
endpoint_id, cluster_id, attribute_id, val->val.a.s, val->val.a.b);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING) {
|
||||
ESP_LOGI(TAG, "********** %c : Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32 "'s Attribute 0x%08" PRIX32 " is %.*s **********", action,
|
||||
endpoint_id, cluster_id, attribute_id, val->val.a.s, val->val.a.b);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "********** %c : Endpoint 0x%04" PRIX16 "'s Cluster 0x%08" PRIX32 "'s Attribute 0x%08" PRIX32 " is <invalid type: %d> **********", action,
|
||||
endpoint_id, cluster_id, attribute_id, val->type);
|
||||
|
||||
@@ -50,9 +50,9 @@ typedef enum {
|
||||
ESP_MATTER_VAL_TYPE_FLOAT = 3,
|
||||
/** Array Eg. [1,2,3] */
|
||||
ESP_MATTER_VAL_TYPE_ARRAY = 4,
|
||||
/** Char String Eg. "123" */
|
||||
/** Char String Eg. "123", Max length 0xFE */
|
||||
ESP_MATTER_VAL_TYPE_CHAR_STRING = 5,
|
||||
/** Octet String Eg. [0x01, 0x20] */
|
||||
/** Octet String Eg. [0x01, 0x20], Max length 0xFE */
|
||||
ESP_MATTER_VAL_TYPE_OCTET_STRING = 6,
|
||||
/** 8 bit signed integer */
|
||||
ESP_MATTER_VAL_TYPE_INT8 = 7,
|
||||
@@ -80,6 +80,11 @@ typedef enum {
|
||||
ESP_MATTER_VAL_TYPE_BITMAP32 = 18,
|
||||
/** 16 bit enum */
|
||||
ESP_MATTER_VAL_TYPE_ENUM16 = 19,
|
||||
/** Long Char String, Max length 0xFFFE **/
|
||||
ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING = 20,
|
||||
/** Long Octet String, Max length 0xFFFE **/
|
||||
ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING = 21,
|
||||
|
||||
/** nullable types **/
|
||||
ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER = ESP_MATTER_VAL_TYPE_INTEGER + ESP_MATTER_VAL_NULLABLE_BASE,
|
||||
ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT = ESP_MATTER_VAL_TYPE_FLOAT + ESP_MATTER_VAL_NULLABLE_BASE,
|
||||
@@ -298,9 +303,11 @@ esp_matter_attr_val_t esp_matter_nullable_bitmap32(nullable<uint32_t> val);
|
||||
|
||||
/** Character string */
|
||||
esp_matter_attr_val_t esp_matter_char_str(char *val, uint16_t data_size);
|
||||
esp_matter_attr_val_t esp_matter_long_char_str(char *val, uint16_t data_size);
|
||||
|
||||
/** Octet string */
|
||||
esp_matter_attr_val_t esp_matter_octet_str(uint8_t *val, uint16_t data_size);
|
||||
esp_matter_attr_val_t esp_matter_long_octet_str(uint8_t *val, uint16_t data_size);
|
||||
|
||||
/** Array */
|
||||
esp_matter_attr_val_t esp_matter_array(uint8_t *val, uint16_t data_size, uint16_t count);
|
||||
|
||||
@@ -1097,7 +1097,9 @@ attribute_t *create(cluster_t *cluster, uint32_t attribute_id, uint8_t flags, es
|
||||
// After reboot, string and array are treated as Invalid. So need to store val.type and size of attribute value.
|
||||
attribute->val.type = val.type;
|
||||
if (val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
attribute->val.val.a.s = val.val.a.s;
|
||||
attribute->val.val.a.n = val.val.a.n;
|
||||
@@ -1148,7 +1150,9 @@ static esp_err_t destroy(attribute_t *attribute)
|
||||
|
||||
/* Delete val here, if required */
|
||||
if (current_attribute->val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
/* Free buf */
|
||||
if (current_attribute->val.val.a.b) {
|
||||
@@ -1221,6 +1225,7 @@ esp_err_t set_val(attribute_t *attribute, esp_matter_attr_val_t *val)
|
||||
}
|
||||
_attribute_t *current_attribute = (_attribute_t *)attribute;
|
||||
if (val->type == ESP_MATTER_VAL_TYPE_CHAR_STRING || val->type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
val->type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING || val->type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
val->type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
/* Free old buf */
|
||||
if (current_attribute->val.val.a.b) {
|
||||
@@ -1275,7 +1280,9 @@ esp_err_t add_bounds(attribute_t *attribute, esp_matter_attr_val_t min, esp_matt
|
||||
|
||||
/* Check if bounds can be set */
|
||||
if (current_attribute->val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
current_attribute->val.type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
ESP_LOGE(TAG, "Bounds cannot be set for string/array type attributes");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
@@ -42,7 +42,9 @@ esp_err_t get_val_from_nvs(uint16_t endpoint_id, uint32_t cluster_id, uint32_t a
|
||||
ESP_LOGD(TAG, "read attribute from nvs: endpoint_id-0x%" PRIx16 ", cluster_id-0x%" PRIx32 ", attribute_id-0x%" PRIx32 "",
|
||||
endpoint_id, cluster_id, attribute_id);
|
||||
if (val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
size_t len = 0;
|
||||
if ((err = nvs_get_blob(handle, attribute_key, NULL, &len)) == ESP_OK) {
|
||||
@@ -185,7 +187,9 @@ esp_err_t store_val_in_nvs(uint16_t endpoint_id, uint32_t cluster_id, uint32_t a
|
||||
ESP_LOGD(TAG, "Store attribute in nvs: endpoint_id-0x%" PRIx16 ", cluster_id-0x%" PRIx32 ", attribute_id-0x%" PRIx32 "",
|
||||
endpoint_id, cluster_id, attribute_id);
|
||||
if (val.type == ESP_MATTER_VAL_TYPE_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING ||
|
||||
val.type == ESP_MATTER_VAL_TYPE_ARRAY) {
|
||||
/* Store only if value is not NULL */
|
||||
if (val.val.a.b) {
|
||||
|
||||
Reference in New Issue
Block a user