Skip to content

Commit

Permalink
Merge pull request #45 from IRNAS/release/v1.6.0
Browse files Browse the repository at this point in the history
Release v1.6.0
  • Loading branch information
TjazVracko authored May 12, 2023
2 parents b6bbf01 + 442df0f commit 02b7847
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 32 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

## [1.6.0] - 2023-05-12

### Added

- user_settings_set_changed_with_key and user_settings_set_changed_with_id functions.
- always_mark_changed parameter to user_settings_set_from_json function.
- The "has_changed_recently" flag is now stored persistently.
- Shell commands to list only changed settings and to clear the changed flag.

## [1.5.0] - 2023-04-11

### Added
Expand Down Expand Up @@ -90,7 +99,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Basic sample.
- Callbacks sample.

[Unreleased]: https://github.com/IRNAS/irnas-usersettings-lib/compare/v1.5.0...HEAD
[Unreleased]: https://github.com/IRNAS/irnas-usersettings-lib/compare/v1.6.0...HEAD

[1.6.0]: https://github.com/IRNAS/irnas-usersettings-lib/compare/v1.5.0...v1.6.0

[1.5.0]: https://github.com/IRNAS/irnas-usersettings-lib/compare/v1.4.0...v1.5.0

Expand Down
22 changes: 22 additions & 0 deletions library/include/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,28 @@ bool user_settings_iter_next(char **key, uint16_t *id);
*/
bool user_settings_iter_next_changed(char **key, uint16_t *id);

/**
* @brief Set the "has_changed_recently" flag
*
* This will assert if no setting with the provided key exists.
* If the key input for this function is unknown to the application (i.e. parsed from user), then
* it should first be checked with user_settings_exists_with_key().
*
* @param[in] key A valid user setting key
*/
void user_settings_set_changed_with_key(char *key);

/**
* @brief Set the "has_changed_recently" flag
*
* This will assert if no setting with the provided id exists.
* If the ID input for this function is unknown to the application (i.e. parsed from user), then
* it should first be checked with user_settings_exists_with_id().
*
* @param[in] key A valid user setting id
*/
void user_settings_set_changed_with_id(uint16_t id);

/**
* @brief Clear "has_changed_recently" flag
*
Expand Down
12 changes: 8 additions & 4 deletions library/include/user_settings_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@ extern "C" {
* }
*
* @param[in] settings The settings to apply
* @param[in] always_mark_changed If true, always mark settings as changed, even if the new value is
* the same as the old one. If false, a setting will only be marked
* changed if the new value is different from the old one.
*
* @retval 0 On success
* @retval -ENOMEM If the new value is larger than the max_size
* @retval -EIO if the setting value could not be stored to NVS
* @retval -EINVAL if the invalid json structure
*/
int user_settings_set_from_json(const cJSON *settings);
int user_settings_set_from_json(const cJSON *settings, bool always_mark_changed);

/**
* @brief Create a JSON with containing only settings marked changed.
* Function will not clear changed flag.
*
* The caller is expected to free the created cJSON structure.
* Calling this function will not clear the changed flag of any user setting.
*
* The caller is expected to free the created cJSON structure.
*
* @param[out] settings Created json
* @retval 0 On success
Expand All @@ -55,7 +59,7 @@ int user_settings_get_changed_json(cJSON **settings);
/**
* @brief Create a JSON with containing all settings.
*
* The caller is expected to free the created cJSON structure.
* The caller is expected to free the created cJSON structure.
*
* @param[out] settings Created json
* @retval 0 On success
Expand Down
132 changes: 124 additions & 8 deletions library/user_settings/user_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ LOG_MODULE_REGISTER(user_settings, CONFIG_USER_SETTINGS_LOG_LEVEL);
#define INIT_ASSERT_TEXT "user_settings_init should be called before this function"
#define LOAD_ASSERT_TEXT "user_settings_load should be called before this function"

#define USER_SETTINGS_PREFIX "user"
#define USER_SETTINGS_DEFAULT_PREFIX "user_default"
#define USER_SETTINGS_PREFIX "user"
#define USER_SETTINGS_DEFAULT_PREFIX "user_default"
#define USER_SETTINGS_CHANGED_FLAG_PREFIX "user_changed"

/* External callback */
static user_settings_on_change_t prv_global_on_change_cb;
Expand Down Expand Up @@ -117,6 +118,36 @@ static int prv_value_set_cb(const char *key, size_t len, settings_read_cb read_c
return 0;
}

/**
* @brief This is called when we call settings_runtime_set on the changed prefix
*/
static int prv_changed_flag_set_cb(const char *key, size_t len, settings_read_cb read_cb,
void *cb_arg)
{
int rc;

/* Check if key exists in the settings list */
struct user_setting *setting = user_settings_list_get_by_key(key);
if (!setting) {
return -ENOENT;
}

/* Read the flag from NVS */
rc = read_cb(cb_arg, &setting->has_changed_recently, sizeof(setting->has_changed_recently));
if (rc < 0) {
LOG_ERR("read_cb, err: %d", rc);
return rc;
} else if (rc == 0) {
LOG_ERR("read_cb, this key value pair was deleted");
return 0;
}

LOG_DBG("Setting %s has_changed_recently flag was read: %d", setting->key,
setting->has_changed_recently);

return 0;
}

int user_settings_init(void)
{
static struct settings_handler prv_default_sh = {
Expand All @@ -129,6 +160,11 @@ int user_settings_init(void)
.h_set = prv_value_set_cb,
};

static struct settings_handler prv_changed_sh = {
.name = USER_SETTINGS_CHANGED_FLAG_PREFIX,
.h_set = prv_changed_flag_set_cb,
};

__ASSERT(!prv_is_inited, "user_settings_init should only be called once");

int err;
Expand Down Expand Up @@ -156,6 +192,13 @@ int user_settings_init(void)
return -EIO;
}

/* register handler for changed flag */
err = settings_register(&prv_changed_sh);
if (err) {
LOG_ERR("settings_register, err: %d", err);
return -EIO;
}

prv_is_inited = true;

return 0;
Expand Down Expand Up @@ -183,8 +226,6 @@ int user_settings_load(void)
{
__ASSERT(prv_is_inited, INIT_ASSERT_TEXT);

prv_is_loaded = true;

int err;

/* load all default values */
Expand All @@ -201,6 +242,15 @@ int user_settings_load(void)
return -EIO;
}

/* load changed recently flags */
err = settings_load_subtree(USER_SETTINGS_CHANGED_FLAG_PREFIX);
if (err) {
LOG_ERR("Failed loading user_settings_changed_recently subtree, err: %d", err);
return -EIO;
}

prv_is_loaded = true;

return 0;
}

Expand Down Expand Up @@ -272,6 +322,48 @@ int user_settings_set_default_with_id(uint16_t id, void *data, size_t len)
return prv_user_settings_set_default(s, data, len);
}

/**
* @brief Persistently set the changed recently flag for a setting.
*
* @param[in] s The setting to set the flag for.
* @param[in] has_changed_recently The value of the flag.
*
* @return int 0 on success, negative errno code otherwise.
*/
static int prv_set_changed_recently_flag(struct user_setting *s, bool has_changed_recently)
{
__ASSERT(prv_is_loaded, LOAD_ASSERT_TEXT);

int err;

/* Check if value is the same */
if (has_changed_recently == s->has_changed_recently) {
LOG_DBG("Setting has_changed_recently flag to same value.");
return 0;
}

/* Use settings_runtime_set() so that prv_changed_flag_set_cb gets called, which will
* set the flag in the settings list */
char key_with_prefix[SETTINGS_MAX_NAME_LEN + 1] = {0};
sprintf(key_with_prefix, USER_SETTINGS_CHANGED_FLAG_PREFIX "/%s", s->key);
err = settings_runtime_set(key_with_prefix, &has_changed_recently,
sizeof(has_changed_recently));
if (err) {
LOG_ERR("settings_runtime_set, err: %d", err);
return -EIO;
}

/* Use settings_save_one() so that the flag is stored to NVS */
err = settings_save_one(key_with_prefix, &has_changed_recently,
sizeof(has_changed_recently));
if (err) {
LOG_ERR("settings_save, err: %d", err);
return -EIO;
}

return 0;
}

static int prv_user_settings_set(struct user_setting *s, void *data, size_t len)
{
__ASSERT(prv_is_loaded, LOAD_ASSERT_TEXT);
Expand Down Expand Up @@ -308,7 +400,11 @@ static int prv_user_settings_set(struct user_setting *s, void *data, size_t len)
}

/* Modify has changed flag */
s->has_changed_recently = 1;
err = prv_set_changed_recently_flag(s, true);
if (err) {
LOG_ERR("prv_set_changed_recently_flag, err: %d", err);
return -EIO;
}

return 0;
}
Expand Down Expand Up @@ -633,14 +729,34 @@ bool user_settings_iter_next_changed(char **key, uint16_t *id)
return true;
}

void user_settings_set_changed_with_key(char *key)
{
__ASSERT(prv_is_loaded, LOAD_ASSERT_TEXT);

struct user_setting *s = user_settings_list_get_by_key(key);
__ASSERT(s, "Key does not exists: %s", key);

prv_set_changed_recently_flag(s, true);
}

void user_settings_set_changed_with_id(uint16_t id)
{
__ASSERT(prv_is_loaded, LOAD_ASSERT_TEXT);

struct user_setting *s = user_settings_list_get_by_id(id);
__ASSERT(s, "Id does not exists: %d", id);

prv_set_changed_recently_flag(s, true);
}

void user_settings_clear_changed_with_key(char *key)
{
__ASSERT(prv_is_loaded, LOAD_ASSERT_TEXT);

struct user_setting *s = user_settings_list_get_by_key(key);
__ASSERT(s, "Key does not exists: %s", key);

s->has_changed_recently = 0;
prv_set_changed_recently_flag(s, 0);
}

void user_settings_clear_changed_with_id(uint16_t id)
Expand All @@ -650,7 +766,7 @@ void user_settings_clear_changed_with_id(uint16_t id)
struct user_setting *s = user_settings_list_get_by_id(id);
__ASSERT(s, "Id does not exists: %d", id);

s->has_changed_recently = 0;
prv_set_changed_recently_flag(s, 0);
}

void user_settings_clear_changed(void)
Expand All @@ -660,7 +776,7 @@ void user_settings_clear_changed(void)
user_settings_list_iter_start();
struct user_setting *setting;
while ((setting = user_settings_list_iter_next()) != NULL) {
setting->has_changed_recently = 0;
prv_set_changed_recently_flag(setting, 0);
}
}

Expand Down
Loading

0 comments on commit 02b7847

Please sign in to comment.