From ef2c3e4d8bdb307803218db41294c158f6734ddd Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Wed, 12 Apr 2023 17:53:46 +0530 Subject: [PATCH] core: Use NVS APIs to get/set attributes with primitive datatype Added the config option to all examples' sdkconfig.defaults --- RELEASE_NOTES.md | 10 + components/esp_matter/Kconfig | 12 ++ components/esp_matter/esp_matter_core.cpp | 207 +++++++++++++++++++++ examples/blemesh_bridge/sdkconfig.defaults | 3 + examples/controller/sdkconfig.defaults | 3 + examples/generic_switch/sdkconfig.defaults | 3 + examples/light/sdkconfig.defaults | 3 + examples/light_switch/sdkconfig.defaults | 3 + examples/zigbee_bridge/sdkconfig.defaults | 3 + 9 files changed, 247 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e97a2b4dc..0de309d90 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,13 @@ +# 14-April-2023 + +#### *Changed how attribute data is stored in NVS* +By default primitive data types are stored as blob and that consumes more space in NVS. +Added a configuration option (`CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE`) which uses +the primitive data type specific NVS APIs to store the attribute. This saves space in NVS partition. + +Newer developements shall enable option `ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE` to save on NVS space. +All the examples have this option enabled. + # 7-April-2023 - `tools/mfg_tool/mfg_tool.py` now uses `connectedhomeip/connectedhomeip/src/setup_payload/python/generate_setup_payload.py` instead of previously used compiled `chip-tool` binary executable which additionally depends on `python-stdnum` module. diff --git a/components/esp_matter/Kconfig b/components/esp_matter/Kconfig index e06327353..ec9cac0b1 100644 --- a/components/esp_matter/Kconfig +++ b/components/esp_matter/Kconfig @@ -99,4 +99,16 @@ menu "ESP Matter" endchoice #ESP_MATTER_MEM_ALLOC_MODE + config ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE + bool "Use compact attribute storage" + default n + help + Attributes can be stored as primitive data type or blob in NVS. + This option lets you select which one to use. + + If enabled, attributes are stored as primitive data types in NVS. + If disabled, then attributes are stored as blob which consumes more space in NVS. + + This option is kept disabled by default to maintain the backward compatibility. + endmenu diff --git a/components/esp_matter/esp_matter_core.cpp b/components/esp_matter/esp_matter_core.cpp index 3b7072617..07cb040ef 100644 --- a/components/esp_matter/esp_matter_core.cpp +++ b/components/esp_matter/esp_matter_core.cpp @@ -1054,6 +1054,7 @@ attribute_t *create(cluster_t *cluster, uint32_t attribute_id, uint8_t flags, es if (attribute->flags & ATTRIBUTE_FLAG_NONVOLATILE) { esp_matter_attr_val_t val_nvs = esp_matter_invalid(NULL); + val_nvs.type = val.type; esp_err_t err = get_val_from_nvs((attribute_t *)attribute, &val_nvs); if (err == ESP_OK) { set_val((attribute_t *)attribute, &val_nvs); @@ -1326,7 +1327,108 @@ esp_err_t store_val_in_nvs(attribute_t *attribute) err = ESP_OK; } } else { + // Handling how to store attributes in NVS based on config option. +#if CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE + // This switch case handles primitive data types + switch (current_attribute->val.type) + { + case ESP_MATTER_VAL_TYPE_BOOLEAN: + { + err = nvs_set_u8(handle, attribute_key, current_attribute->val.val.b != 0); + break; + } + + case ESP_MATTER_VAL_TYPE_INTEGER: + case ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER: + { + err = nvs_set_i32(handle, attribute_key, current_attribute->val.val.i); + break; + } + + // no nvs api to store float, storing as blob + case ESP_MATTER_VAL_TYPE_FLOAT: + case ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT: + { + err = nvs_set_blob(handle, attribute_key, ¤t_attribute->val.val.f, sizeof(current_attribute->val.val.f)); + break; + } + + case ESP_MATTER_VAL_TYPE_INT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT8: + { + err = nvs_set_i8(handle, attribute_key, current_attribute->val.val.i8); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT8: + case ESP_MATTER_VAL_TYPE_ENUM8: + case ESP_MATTER_VAL_TYPE_BITMAP8: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8: + { + err = nvs_set_u8(handle, attribute_key, current_attribute->val.val.u8); + break; + } + + case ESP_MATTER_VAL_TYPE_INT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT16: + { + err = nvs_set_i16(handle, attribute_key, current_attribute->val.val.i16); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT16: + case ESP_MATTER_VAL_TYPE_BITMAP16: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16: + { + err = nvs_set_u16(handle, attribute_key, current_attribute->val.val.u16); + break; + } + + case ESP_MATTER_VAL_TYPE_INT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT32: + { + err = nvs_set_i32(handle, attribute_key, current_attribute->val.val.i32); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT32: + case ESP_MATTER_VAL_TYPE_BITMAP32: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32: + { + err = nvs_set_u32(handle, attribute_key, current_attribute->val.val.u32); + break; + } + + case ESP_MATTER_VAL_TYPE_INT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT64: + { + err = nvs_set_i64(handle, attribute_key, current_attribute->val.val.i64); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT64: + { + err = nvs_set_u64(handle, attribute_key, current_attribute->val.val.u64); + break; + } + + default: + { + // handle the case where the type is not recognized + err = ESP_ERR_INVALID_ARG; + ESP_LOGE(TAG, "Invalid attribute type: %u", current_attribute->val.type); + break; + } + } +#else err = nvs_set_blob(handle, attribute_key, ¤t_attribute->val, sizeof(esp_matter_attr_val_t)); +#endif // CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE + nvs_commit(handle); } nvs_close(handle); @@ -1375,8 +1477,113 @@ esp_err_t get_val_from_nvs(attribute_t *attribute, esp_matter_attr_val_t *val) } } } else { + // Handling how to get attributes in NVS based on config option. +#if CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE + // This switch case handles primitive data types + switch (current_attribute->val.type) + { + case ESP_MATTER_VAL_TYPE_BOOLEAN: + { + uint8_t b_val; + if ((err = nvs_get_u8(handle, attribute_key, &b_val)) == ESP_OK) + { + val->val.b = (b_val != 0); + } + break; + } + + case ESP_MATTER_VAL_TYPE_INTEGER: + case ESP_MATTER_VAL_TYPE_NULLABLE_INTEGER: + { + err = nvs_get_i32(handle, attribute_key, reinterpret_cast(&val->val.i)); + break; + } + + // no nvs api to read float, since it is stored as blob, reading as blob + case ESP_MATTER_VAL_TYPE_FLOAT: + case ESP_MATTER_VAL_TYPE_NULLABLE_FLOAT: + { + size_t length = sizeof(val->val.f); + err = nvs_get_blob(handle, attribute_key, &val->val.f, &length); + break; + } + + case ESP_MATTER_VAL_TYPE_INT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT8: + { + err = nvs_get_i8(handle, attribute_key, &val->val.i8); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT8: + case ESP_MATTER_VAL_TYPE_ENUM8: + case ESP_MATTER_VAL_TYPE_BITMAP8: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT8: + case ESP_MATTER_VAL_TYPE_NULLABLE_ENUM8: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP8: + { + err = nvs_get_u8(handle, attribute_key, &val->val.u8); + break; + } + + case ESP_MATTER_VAL_TYPE_INT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT16: + { + err = nvs_get_i16(handle, attribute_key, &val->val.i16); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT16: + case ESP_MATTER_VAL_TYPE_BITMAP16: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT16: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP16: + { + err = nvs_get_u16(handle, attribute_key, &val->val.u16); + break; + } + + case ESP_MATTER_VAL_TYPE_INT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT32: + { + err = nvs_get_i32(handle, attribute_key, &val->val.i32); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT32: + case ESP_MATTER_VAL_TYPE_BITMAP32: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT32: + case ESP_MATTER_VAL_TYPE_NULLABLE_BITMAP32: + { + err = nvs_get_u32(handle, attribute_key, &val->val.u32); + break; + } + + case ESP_MATTER_VAL_TYPE_INT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_INT64: + { + err = nvs_get_i64(handle, attribute_key, &val->val.i64); + break; + } + + case ESP_MATTER_VAL_TYPE_UINT64: + case ESP_MATTER_VAL_TYPE_NULLABLE_UINT64: + { + err = nvs_get_u64(handle, attribute_key, &val->val.u64); + break; + } + + default: + { + // handle the case where the type is not recognized + err = ESP_ERR_INVALID_ARG; + ESP_LOGE(TAG, "Invalid attribute type: %u", current_attribute->val.type); + break; + } + } +#else size_t len = sizeof(esp_matter_attr_val_t); err = nvs_get_blob(handle, attribute_key, val, &len); +#endif // CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE } nvs_close(handle); return err; diff --git a/examples/blemesh_bridge/sdkconfig.defaults b/examples/blemesh_bridge/sdkconfig.defaults index 710a6b74e..22299a769 100644 --- a/examples/blemesh_bridge/sdkconfig.defaults +++ b/examples/blemesh_bridge/sdkconfig.defaults @@ -53,3 +53,6 @@ CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n # Disable DS Peripheral CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/examples/controller/sdkconfig.defaults b/examples/controller/sdkconfig.defaults index abb53c66d..460b99181 100644 --- a/examples/controller/sdkconfig.defaults +++ b/examples/controller/sdkconfig.defaults @@ -39,3 +39,6 @@ CONFIG_NUM_UDP_ENDPOINTS=16 # Enable Controller and commissioner CONFIG_ESP_MATTER_CONTROLLER_ENABLE=y CONFIG_ESP_MATTER_COMMISSIONER_ENABLE=y + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/examples/generic_switch/sdkconfig.defaults b/examples/generic_switch/sdkconfig.defaults index a759ded2d..f856903c3 100644 --- a/examples/generic_switch/sdkconfig.defaults +++ b/examples/generic_switch/sdkconfig.defaults @@ -40,3 +40,6 @@ CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n # Enable for fixed-label CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER=y CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER=y + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/examples/light/sdkconfig.defaults b/examples/light/sdkconfig.defaults index 1fa8a9ff4..e34ed965b 100644 --- a/examples/light/sdkconfig.defaults +++ b/examples/light/sdkconfig.defaults @@ -37,3 +37,6 @@ CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n # Disable DS Peripheral CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/examples/light_switch/sdkconfig.defaults b/examples/light_switch/sdkconfig.defaults index 1fa8a9ff4..e34ed965b 100644 --- a/examples/light_switch/sdkconfig.defaults +++ b/examples/light_switch/sdkconfig.defaults @@ -37,3 +37,6 @@ CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n # Disable DS Peripheral CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y diff --git a/examples/zigbee_bridge/sdkconfig.defaults b/examples/zigbee_bridge/sdkconfig.defaults index a7a632238..5570a1956 100644 --- a/examples/zigbee_bridge/sdkconfig.defaults +++ b/examples/zigbee_bridge/sdkconfig.defaults @@ -40,3 +40,6 @@ CONFIG_ZB_RADIO_MACSPLIT_UART=y # Disable DS Peripheral CONFIG_ESP_SECURE_CERT_DS_PERIPHERAL=n + +# Use compact attribute storage mode +CONFIG_ESP_MATTER_NVS_USE_COMPACT_ATTR_STORAGE=y