diff --git a/components/esp_rainmaker/CHANGELOG.md b/components/esp_rainmaker/CHANGELOG.md index fcc87fc..47151d0 100644 --- a/components/esp_rainmaker/CHANGELOG.md +++ b/components/esp_rainmaker/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 1.8.1 + +### New Feature + +- Added optional `readme` field to node info: Allows example projects to include + a README URL in the node configuration. The readme field will be included in + node config only if its value is not NULL and not an empty string. This can + be set using the `esp_rmaker_node_add_readme()` API. + +## 1.8.0 + +### Changes +- Decouple esp_rcp_update from esp_rainmaker and it is not a core functionality of RainMaker + ## 1.7.9 ### New Feature @@ -8,7 +22,7 @@ ## 1.7.8 ## Changes -- Make version dependency for network_provisioning more flexible +- Make version dependency for network_provisioning more flexible ## 1.7.7 @@ -26,7 +40,7 @@ - Some guards for `CONFIG_ESP_RMAKER_CMD_RESP_ENABLE` and `CONFIG_ESP_RMAKER_PARAM_CMD_RESP_ENABLE` were missing. ### Other changes -- Changed default MQTT Host URL to mqtt.rainmaker.espressif.com to match the domain conigured on public RainMaker. +- Changed default MQTT Host URL to mqtt.rainmaker.espressif.com to match the domain conigured on public RainMaker. ## 1.7.4 diff --git a/components/esp_rainmaker/idf_component.yml b/components/esp_rainmaker/idf_component.yml index f17bdfb..5fea947 100644 --- a/components/esp_rainmaker/idf_component.yml +++ b/components/esp_rainmaker/idf_component.yml @@ -1,5 +1,5 @@ ## IDF Component Manager Manifest File -version: "1.8.0" +version: "1.8.1" description: ESP RainMaker firmware agent url: https://github.com/espressif/esp-rainmaker/tree/master/components/esp_rainmaker repository: https://github.com/espressif/esp-rainmaker.git diff --git a/components/esp_rainmaker/include/esp_rmaker_core.h b/components/esp_rainmaker/include/esp_rmaker_core.h index 5753ae5..169a832 100644 --- a/components/esp_rainmaker/include/esp_rmaker_core.h +++ b/components/esp_rainmaker/include/esp_rmaker_core.h @@ -61,6 +61,8 @@ typedef struct { char *model; /** Subtype (Optional). */ char *subtype; + /** Readme URL (Optional). Typically points to a readme URL. Will be included in node config only if not NULL and not empty. */ + char *readme; /** An array of digests read from efuse. Should be freed after use*/ char **secure_boot_digest; } esp_rmaker_node_info_t; @@ -523,6 +525,16 @@ esp_err_t esp_rmaker_node_add_model(const esp_rmaker_node_t *node, const char *m */ esp_err_t esp_rmaker_node_add_subtype(const esp_rmaker_node_t *node, const char *subtype); +/** Add readme URL for a node + * + * @param node Node handle. + * @param[in] readme Readme URL string. Typically points to a readme URL. Will be included in node config only if not NULL and not empty. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t esp_rmaker_node_add_readme(const esp_rmaker_node_t *node, const char *readme); + /** * Create a Device * diff --git a/components/esp_rainmaker/src/core/esp_rmaker_node.c b/components/esp_rainmaker/src/core/esp_rmaker_node.c index dae7b77..cc118c2 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_node.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_node.c @@ -42,6 +42,9 @@ static void esp_rmaker_node_info_free(esp_rmaker_node_info_t *info) if (info->subtype) { free(info->subtype); } + if (info->readme) { + free(info->readme); + } if (info->secure_boot_digest) { esp_rmaker_secure_boot_digest_free(info->secure_boot_digest); info->secure_boot_digest = NULL; @@ -214,6 +217,28 @@ esp_err_t esp_rmaker_node_add_subtype(const esp_rmaker_node_t *node, const char return ESP_OK; } +esp_err_t esp_rmaker_node_add_readme(const esp_rmaker_node_t *node, const char *readme) +{ + if (!node || !readme) { + ESP_LOGE(TAG, "Node handle or readme cannot be NULL."); + return ESP_ERR_INVALID_ARG; + } + esp_rmaker_node_info_t *info = esp_rmaker_node_get_info(node); + if (!info) { + ESP_LOGE(TAG, "Failed to get Node Info."); + return ESP_ERR_INVALID_ARG; + } + if (info->readme) { + free(info->readme); + } + info->readme = strdup(readme); + if (!info->readme) { + ESP_LOGE(TAG, "Failed to allocate memory for node readme."); + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} + esp_err_t esp_rmaker_node_add_or_edit_attribute(const esp_rmaker_node_t *node, const char *attr_name, const char *value, bool edit) { if (!node || !attr_name || !value) { diff --git a/components/esp_rainmaker/src/core/esp_rmaker_node_config.c b/components/esp_rainmaker/src/core/esp_rmaker_node_config.c index 372a6ec..7c9f2e2 100644 --- a/components/esp_rainmaker/src/core/esp_rmaker_node_config.c +++ b/components/esp_rainmaker/src/core/esp_rmaker_node_config.c @@ -40,6 +40,9 @@ static esp_err_t esp_rmaker_report_info(json_gen_str_t *jptr) if (info->subtype) { json_gen_obj_set_string(jptr, "subtype", info->subtype); } + if (info->readme && strlen(info->readme) > 0) { + json_gen_obj_set_string(jptr, "readme", info->readme); + } json_gen_obj_set_string(jptr, "model", info->model); const esp_app_desc_t *app_desc; app_desc = esp_app_get_description();