You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/01/29 21:50:20 UTC

[1/3] incubator-mynewt-larva git commit: Add '?' to list all available commands.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master d8852809d -> ccda6d4b1


Add '?' to list all available commands.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/8007c194
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/8007c194
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/8007c194

Branch: refs/heads/master
Commit: 8007c194eb04b906df2c0ca567d2a31206c8fe2f
Parents: d885280
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jan 29 12:47:59 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jan 29 12:47:59 2016 -0800

----------------------------------------------------------------------
 libs/shell/src/shell.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/8007c194/libs/shell/src/shell.c
----------------------------------------------------------------------
diff --git a/libs/shell/src/shell.c b/libs/shell/src/shell.c
index 80c578a..d0de7f1 100644
--- a/libs/shell/src/shell.c
+++ b/libs/shell/src/shell.c
@@ -32,8 +32,10 @@ static void *g_shell_nlip_in_arg;
 static struct os_mqueue g_shell_nlip_mq;
 
 #define OS_EVENT_T_CONSOLE_RDY (OS_EVENT_T_PERUSER)
+#define SHELL_HELP_PER_LINE	6
 
 static struct shell_cmd g_shell_echo_cmd;
+static struct shell_cmd g_shell_help_cmd;
 
 static struct os_task shell_task;
 static struct os_eventq shell_evq;
@@ -437,6 +439,31 @@ shell_echo_cmd(int argc, char **argv)
     return (0);
 }
 
+static int
+shell_help_cmd(int argc, char **argv)
+{
+    int rc;
+    int i = 0;
+    struct shell_cmd *sc;
+
+    rc = shell_cmd_list_lock();
+    if (rc != 0) {
+        return -1;
+    }
+
+    STAILQ_FOREACH(sc, &g_shell_cmd_list, sc_next) {
+        console_printf("%s \t", sc->sc_cmd);
+        if (i++ % SHELL_HELP_PER_LINE == SHELL_HELP_PER_LINE - 1) {
+            console_printf("\n");
+        }
+    }
+    if (i % SHELL_HELP_PER_LINE) {
+        console_printf("\n");
+    }
+    shell_cmd_list_unlock();
+
+    return (0);
+}
 
 int 
 shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size)
@@ -453,6 +480,11 @@ shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size)
         goto err;
     }
 
+    rc = shell_cmd_register(&g_shell_help_cmd, "?", shell_help_cmd);
+    if (rc != 0) {
+        goto err;
+    }
+
     rc = os_task_init(&shell_task, "shell", shell_task_func, 
             NULL, prio, OS_WAIT_FOREVER, stack, stack_size);
     if (rc != 0) {


[2/3] incubator-mynewt-larva git commit: Add error code OS_ENOENT.

Posted by ma...@apache.org.
Add error code OS_ENOENT.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/6689163e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/6689163e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/6689163e

Branch: refs/heads/master
Commit: 6689163ef5315e52acd28136918832c03e751b5c
Parents: 8007c19
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jan 29 12:48:21 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jan 29 12:48:21 2016 -0800

----------------------------------------------------------------------
 libs/os/include/os/os.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/6689163e/libs/os/include/os/os.h
----------------------------------------------------------------------
diff --git a/libs/os/include/os/os.h b/libs/os/include/os/os.h
index 938f8b7..eb63253 100644
--- a/libs/os/include/os/os.h
+++ b/libs/os/include/os/os.h
@@ -53,7 +53,7 @@ int os_started(void);
 
 /* OS error enumerations */
 enum os_error {
-    OS_OK = 0, 
+    OS_OK = 0,
     OS_ENOMEM = 1,
     OS_EINVAL = 2,
     OS_INVALID_PARM = 3,
@@ -63,6 +63,7 @@ enum os_error {
     OS_ERR_IN_ISR = 7,      /* Function cannot be called from ISR */
     OS_ERR_PRIV = 8,        /* Privileged access error */
     OS_NOT_STARTED = 9,     /* Operating must be started to call this function, but isn't */
+    OS_ENOENT = 10,         /* No such thing */
 };
 
 #define OS_WAIT_FOREVER (-1) 


Re: [3/3] incubator-mynewt-larva git commit: Second take on the config system.

Posted by marko kiiskila <ma...@runtime.io>.
Sorry for belated response.

> On Jan 30, 2016, at 2:34 PM, Sterling Hughes <st...@apache.org> wrote:
> 
> 
> 
> On 1/29/16 6:25 PM, marko kiiskila wrote:
>> Hi all,
>> 
>> I was not happy with my first attempt at the interface between config and subsystems.
>> So here’s a 2nd version.
>> 
>> 
...
>> 
>> There is still no persistent storage of config. We should have at least 2 options for this:
>> storage of config in files, or in a raw flash region (when FS is not available).
>> I’m thinking the API should be similar for both, so decision of which one to use will be
>> a simple build time knob.
>> 
> 
> +1 to this.
> 
> How does configuration get registered with the system?   i.e. If I wanted to dump the current state of all configuration in the system, how would that happen using the above APIs?

That would be through the commit(). If you’re trying to persist data, it would go to
your persistent storage of choice. If you’re trying to view it, it would come out to
console or somewhere else.

> Should commit() have the notion of a commit ID + timestamp?  That way for a given set of variables, you can know when they were changed.

You could build it into persistent storage interface, if deemed necessary.
—
M


Re: Fwd: [3/3] incubator-mynewt-larva git commit: Second take on the config system.

Posted by Sterling Hughes <st...@apache.org>.

On 1/29/16 6:25 PM, marko kiiskila wrote:
> Hi all,
>
> I was not happy with my first attempt at the interface between config and subsystems.
> So here’s a 2nd version.
>
> The config items are still identified as strings.
>
> Subsystem registers a set of handlers, and a root for it’s config tree.
>
> struct conf_handler {
>      SLIST_ENTRY(conf_handler) ch_list;
>      char *ch_name;
>      char *(*ch_get)(int argc, char **argv, char *val, int val_len_max);
>      int (*ch_set)(int argc, char **argv, char *val);
>      int (*ch_commit)();
> };
>
> ch_name would be aforementioned root for subsystem config.
>
> ch_get/ch_set do the obvious thing; get is for getting the current value, set is used in setting a value.
> Config items have names like subsystem/item1, or subsystem/item2/item3.
> ‘/‘ would be used as a delimiter between components of the name. This name gets split into
> components and gets passed in as argc/argv value to subsystem handler.
>
> When a blob of configuration comes in, it would be translated into a bunch of calls to set(),
> followed by commit.
> The idea is to have set() validate the input, stash the value, and then ‘apply’ it when commit
> gets called.
>
> As you can see, the value also is passed in a form of a string. There’s some helper functions
> that you can use to translate between string and integers and so forth. Use of those is
> optional, but probably a good idea.
>
> There is still no persistent storage of config. We should have at least 2 options for this:
> storage of config in files, or in a raw flash region (when FS is not available).
> I’m thinking the API should be similar for both, so decision of which one to use will be
> a simple build time knob.
>

+1 to this.

How does configuration get registered with the system?   i.e. If I 
wanted to dump the current state of all configuration in the system, how 
would that happen using the above APIs?

Should commit() have the notion of a commit ID + timestamp?  That way 
for a given set of variables, you can know when they were changed.

> There was a request to be able to load configuration from multiple sources; e.g. from
> a number of files and from the flash variable as well.
> Any system will have some config items that are going to be set at manufacturing time
> (serial numbers, for example) and then there will items that change more often.
> So one could for example have the manufacturing config live somewhere else from
> everything else. This way reverting back to manufacturing config should be easy.
>

+1

I think some thought needs to be put into how to manage a manufacturing 
configuration, and the overlap between that and active configuration.

I don't know if folks on the list have thoughts on this.

Sterling

Fwd: [3/3] incubator-mynewt-larva git commit: Second take on the config system.

Posted by marko kiiskila <ma...@runtime.io>.
Hi all,

I was not happy with my first attempt at the interface between config and subsystems.
So here’s a 2nd version.

The config items are still identified as strings.

Subsystem registers a set of handlers, and a root for it’s config tree.

struct conf_handler {
    SLIST_ENTRY(conf_handler) ch_list;
    char *ch_name;
    char *(*ch_get)(int argc, char **argv, char *val, int val_len_max);
    int (*ch_set)(int argc, char **argv, char *val);
    int (*ch_commit)();
};

ch_name would be aforementioned root for subsystem config.

ch_get/ch_set do the obvious thing; get is for getting the current value, set is used in setting a value.
Config items have names like subsystem/item1, or subsystem/item2/item3.
‘/‘ would be used as a delimiter between components of the name. This name gets split into
components and gets passed in as argc/argv value to subsystem handler.

When a blob of configuration comes in, it would be translated into a bunch of calls to set(),
followed by commit.
The idea is to have set() validate the input, stash the value, and then ‘apply’ it when commit
gets called.

As you can see, the value also is passed in a form of a string. There’s some helper functions
that you can use to translate between string and integers and so forth. Use of those is
optional, but probably a good idea.

There is still no persistent storage of config. We should have at least 2 options for this:
storage of config in files, or in a raw flash region (when FS is not available).
I’m thinking the API should be similar for both, so decision of which one to use will be
a simple build time knob.

There was a request to be able to load configuration from multiple sources; e.g. from
a number of files and from the flash variable as well.
Any system will have some config items that are going to be set at manufacturing time
(serial numbers, for example) and then there will items that change more often.
So one could for example have the manufacturing config live somewhere else from
everything else. This way reverting back to manufacturing config should be easy.

I hope folks can take a look at what’s there now, and give feedback on this.

Thanks,
M

> Begin forwarded message:
> 
> From: marko@apache.org
> Subject: [3/3] incubator-mynewt-larva git commit: Second take on the config system.
> Date: January 29, 2016 at 12:50:22 PM PST
> To: commits@mynewt.incubator.apache.org
> Reply-To: dev@mynewt.incubator.apache.org
> 
> Second take on the config system.
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
> Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/ccda6d4b
> Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/ccda6d4b
> Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/ccda6d4b
> 
> Branch: refs/heads/master
> Commit: ccda6d4b166c1034cb7ec1dacd88378ffa6b7b56
> Parents: 6689163
> Author: Marko Kiiskila <ma...@runtime.io>
> Authored: Fri Jan 29 12:49:47 2016 -0800
> Committer: Marko Kiiskila <ma...@runtime.io>
> Committed: Fri Jan 29 12:49:47 2016 -0800
> 
> ----------------------------------------------------------------------
> project/blinky/src/main.c          |   2 +-
> project/slinky/src/main.c          |  74 +++++----
> sys/config/include/config/config.h |  48 +++---
> sys/config/src/config.c            | 218 ++++++++++++++++----------
> sys/config/src/config_cli.c        |  43 ++----
> sys/config/src/config_nmgr.c       |  34 +---
> sys/config/src/config_priv.h       |   1 +
> sys/config/src/test/conf_test.c    | 266 +++++++++++++-------------------
> 8 files changed, 326 insertions(+), 360 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/project/blinky/src/main.c
> ----------------------------------------------------------------------
> diff --git a/project/blinky/src/main.c b/project/blinky/src/main.c
> index 43b985e..81637c6 100755
> --- a/project/blinky/src/main.c
> +++ b/project/blinky/src/main.c
> @@ -158,7 +158,7 @@ main(int argc, char **argv)
>     mcu_sim_parse_args(argc, argv);
> #endif
> 
> -    conf_module_init();
> +    conf_init();
> 
>     cbmem_init(&log_mem, log_buf, sizeof(log_buf));
>     util_log_cbmem_handler_init(&log_mem_handler, &log_mem);
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/project/slinky/src/main.c
> ----------------------------------------------------------------------
> diff --git a/project/slinky/src/main.c b/project/slinky/src/main.c
> index f0c8f7a..dd2ffad 100755
> --- a/project/slinky/src/main.c
> +++ b/project/slinky/src/main.c
> @@ -85,35 +85,54 @@ uint8_t default_mbuf_mpool_data[DEFAULT_MBUF_MPOOL_BUF_LEN *
> struct os_mbuf_pool default_mbuf_pool;
> struct os_mempool default_mbuf_mpool;
> 
> +static char *test_conf_get(int argc, char **argv, char *val, int max_len);
> +static int test_conf_set(int argc, char **argv, char *val);
> +static int test_conf_commit(void);
> +
> +static struct conf_handler test_conf_handler = {
> +    .ch_name = "test",
> +    .ch_get = test_conf_get,
> +    .ch_set = test_conf_set,
> +    .ch_commit = test_conf_commit
> +};
> +
> static uint8_t test8;
> +static uint8_t test8_shadow;
> static char test_str[32];
> 
> -static const struct conf_entry test_conf_array[2] = {
> -    [0] = {
> -        .c_name = "8",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &test8
> -    },
> -    [1] = {
> -        .c_name = "str",
> -        .c_type = CONF_STRING,
> -        .c_val.array.val = test_str,
> -        .c_val.array.maxlen = sizeof(test_str)
> +static char *
> +test_conf_get(int argc, char **argv, char *buf, int max_len)
> +{
> +    if (argc == 1) {
> +        if (!strcmp(argv[0], "8")) {
> +            return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
> +        } else if (!strcmp(argv[0], "str")) {
> +            return test_str;
> +        }
>     }
> -};
> -static struct conf_node test_conf_array_node = {
> -    .cn_cnt = 2,
> -    .cn_array = (struct conf_entry *)test_conf_array
> -};
> +    return NULL;
> +}
> 
> -static const struct conf_entry test_conf_dir = {
> -    .c_name = "test",
> -    .c_type = CONF_DIR
> -};
> -static struct conf_node test_conf_dir_node = {
> -    .cn_cnt = 1,
> -    .cn_array = (struct conf_entry *)&test_conf_dir
> -};
> +static int
> +test_conf_set(int argc, char **argv, char *val)
> +{
> +    if (argc == 1) {
> +        if (!strcmp(argv[0], "8")) {
> +            return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
> +        } else if (!strcmp(argv[0], "str")) {
> +            return CONF_VALUE_SET(val, CONF_STRING, test_str);
> +        }
> +    }
> +    return OS_ENOENT;
> +}
> +
> +static int
> +test_conf_commit(void)
> +{
> +    test8 = test8_shadow;
> +
> +    return 0;
> +}
> 
> void
> task1_handler(void *arg)
> @@ -205,11 +224,8 @@ main(int argc, char **argv)
>     mcu_sim_parse_args(argc, argv);
> #endif
> 
> -    conf_module_init();
> -    rc = conf_register(NULL, &test_conf_dir_node);
> -    assert(rc == 0);
> -
> -    rc = conf_register(&test_conf_dir_node, &test_conf_array_node);
> +    conf_init();
> +    rc = conf_register(&test_conf_handler);
>     assert(rc == 0);
> 
>     cbmem_init(&log_mem, log_buf, sizeof(log_buf));
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/include/config/config.h
> ----------------------------------------------------------------------
> diff --git a/sys/config/include/config/config.h b/sys/config/include/config/config.h
> index 59b68b2..717f711 100644
> --- a/sys/config/include/config/config.h
> +++ b/sys/config/include/config/config.h
> @@ -37,39 +37,27 @@ enum conf_type {
>     CONF_DOUBLE
> } __attribute__((__packed__));
> 
> -struct conf_entry {
> -    const char *c_name;
> -    enum conf_type c_type;
> -    union {
> -        struct {	/* INT8, INT16, INT32, INT64, FLOAT, DOUBLE */
> -            void *val;
> -        } single;
> -        struct {	/* STRING, BYTES */
> -            uint16_t maxlen;
> -            uint16_t len;
> -            void *val;
> -        } array;
> -    } c_val;
> +struct conf_handler {
> +    SLIST_ENTRY(conf_handler) ch_list;
> +    char *ch_name;
> +    char *(*ch_get)(int argc, char **argv, char *val, int val_len_max);
> +    int (*ch_set)(int argc, char **argv, char *val);
> +    int (*ch_commit)();
> };
> 
> -struct conf_entry_dir {
> -    const char *c_name;
> -    enum conf_type c_type;	/* DIR */
> -};
> -
> -struct conf_node {
> -    SLIST_ENTRY(conf_node) cn_next;
> -    SLIST_HEAD(, conf_node) cn_children;
> -    struct conf_entry *cn_array;
> -    int cn_cnt;
> -};
> +int conf_init(void);
> +int conf_register(struct conf_handler *);
> +int conf_load(void);
> 
> -int conf_module_init(void);
> -int conf_register(struct conf_node *parent, struct conf_node *child);
> -struct conf_entry *conf_lookup(int argc, char **argv);
> +int conf_set_value(char *name, char *val_str);
> +char *conf_get_value(char *name, char *buf, int buf_len);
> +int conf_commit(char *name);
> 
> -int conf_parse_name(char *name, int *name_argc, char *name_argv[]);
> -int conf_set_value(struct conf_entry *ce, char *val_str);
> -char *conf_get_value(struct conf_entry *ce, char *buf, int buf_len);
> +int conf_value_from_str(char *val_str, enum conf_type type, void *vp,
> +  int maxlen);
> +char *conf_str_from_value(enum conf_type type, void *vp, char *buf,
> +  int buf_len);
> +#define CONF_VALUE_SET(str, type, val)                                  \
> +    conf_value_from_str((str), (type), &(val), sizeof(val))
> 
> #endif /* __UTIL_CONFIG_H_ */
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config.c
> ----------------------------------------------------------------------
> diff --git a/sys/config/src/config.c b/sys/config/src/config.c
> index d7f6d54..ff2b6ab 100644
> --- a/sys/config/src/config.c
> +++ b/sys/config/src/config.c
> @@ -17,77 +17,61 @@
> #include <string.h>
> #include <stdio.h>
> 
> -#include "config/config.h"
> +#include <os/os.h>
> 
> -#ifdef SHELL_PRESENT
> -#include <shell/shell.h>
> -#include <console/console.h>
> -#endif
> +#include "config/config.h"
> +#include "config_priv.h"
> 
> -static struct conf_node g_conf_root;
> +static SLIST_HEAD(, conf_handler) conf_handlers =
> +    SLIST_HEAD_INITIALIZER(&conf_handlers);
> 
> -static struct conf_entry *
> -conf_node_match(struct conf_node *cn, const char *name)
> +int
> +conf_init(void)
> {
> -    int i;
> +    int rc = 0;
> 
> -    for (i = 0; i < cn->cn_cnt; i++) {
> -        if (!strcmp(name, cn->cn_array[i].c_name)) {
> -            return &cn->cn_array[i];
> -        }
> -    }
> -    return NULL;
> +#ifdef SHELL_PRESENT
> +    rc = conf_cli_register();
> +#endif
> +#ifdef NEWTMGR_PRESENT
> +    rc = conf_nmgr_register();
> +#endif
> +    return rc;
> }
> 
> -/*
> - * Register config node to a specific spot in the tree.
> - */
> int
> -conf_register(struct conf_node *parent, struct conf_node *child)
> +conf_register(struct conf_handler *handler)
> {
> -    struct conf_node *cn;
> -    int i;
> -
> -    if (!parent) {
> -        parent = &g_conf_root;
> -    }
> +    SLIST_INSERT_HEAD(&conf_handlers, handler, ch_list);
> +    return 0;
> +}
> 
> -    for (i = 0; i < child->cn_cnt; i++) {
> -        SLIST_FOREACH(cn, &parent->cn_children, cn_next) {
> -            if (conf_node_match(cn, child->cn_array[i].c_name)) {
> -                return -1;
> -            }
> -        }
> -    }
> -    SLIST_INSERT_HEAD(&parent->cn_children, child, cn_next);
> +int
> +conf_load(void)
> +{
> +    /*
> +     * for every config source
> +     *    load config
> +     *    apply config
> +     *    commit all
> +     */
>     return 0;
> }
> 
> /*
> - * Lookup conf_entry based on name.
> + * Find conf_handler based on name.
>  */
> -struct conf_entry *
> -conf_lookup(int argc, char **argv)
> +struct conf_handler *
> +conf_handler_lookup(char *name)
> {
> -    int i;
> -    struct conf_node *parent = &g_conf_root;
> -    struct conf_entry *ret = NULL;
> -    struct conf_node *cn;
> -
> -    for (i = 0; i < argc; i++) {
> -        ret = NULL;
> -        SLIST_FOREACH(cn, &parent->cn_children, cn_next) {
> -            ret = conf_node_match(cn, argv[i]);
> -            if (ret) {
> -                break;
> -            }
> -        }
> -        parent = cn;
> -        if (!parent) {
> -            return NULL;
> +    struct conf_handler *ch;
> +
> +    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
> +        if (!strcmp(name, ch->ch_name)) {
> +            return ch;
>         }
>     }
> -    return ret;
> +    return NULL;
> }
> 
> /*
> @@ -113,13 +97,25 @@ conf_parse_name(char *name, int *name_argc, char *name_argv[])
>     return 0;
> }
> 
> +static struct conf_handler *
> +conf_parse_and_lookup(char *name, int *name_argc, char *name_argv[])
> +{
> +    int rc;
> +
> +    rc = conf_parse_name(name, name_argc, name_argv);
> +    if (rc) {
> +        return NULL;
> +    }
> +    return conf_handler_lookup(name_argv[0]);
> +}
> +
> int
> -conf_set_value(struct conf_entry *ce, char *val_str)
> +conf_value_from_str(char *val_str, enum conf_type type, void *vp, int maxlen)
> {
>     int32_t val;
>     char *eptr;
> 
> -    switch (ce->c_type) {
> +    switch (type) {
>     case CONF_INT8:
>     case CONF_INT16:
>     case CONF_INT32:
> @@ -127,61 +123,53 @@ conf_set_value(struct conf_entry *ce, char *val_str)
>         if (*eptr != '\0') {
>             goto err;
>         }
> -        if (ce->c_type == CONF_INT8) {
> +        if (type == CONF_INT8) {
>             if (val < INT8_MIN || val > UINT8_MAX) {
>                 goto err;
>             }
> -            *(int8_t *)ce->c_val.single.val = val;
> -        } else if (ce->c_type == CONF_INT16) {
> +            *(int8_t *)vp = val;
> +        } else if (type == CONF_INT16) {
>             if (val < INT16_MIN || val > UINT16_MAX) {
>                 goto err;
>             }
> -            *(int16_t *)ce->c_val.single.val = val;
> -        } else if (ce->c_type == CONF_INT32) {
> -            *(int32_t *)ce->c_val.single.val = val;
> +            *(int16_t *)vp = val;
> +        } else if (type == CONF_INT32) {
> +            *(int32_t *)vp = val;
>         }
>         break;
>     case CONF_STRING:
>         val = strlen(val_str);
> -        if (val + 1 > ce->c_val.array.maxlen) {
> +        if (val + 1 > maxlen) {
>             goto err;
>         }
> -        strcpy(ce->c_val.array.val, val_str);
> -        ce->c_val.array.len = val;
> +        strcpy(vp, val_str);
>         break;
>     default:
> -        console_printf("Can't parse type %d\n", ce->c_type);
> -        break;
> +        goto err;
>     }
>     return 0;
> err:
> -    return -1;
> +    return OS_INVALID_PARM;
> }
> 
> -/*
> - * Get value in printable string form. If value is not string, the value
> - * will be filled in *buf.
> - * Return value will be pointer to beginning of that buffer,
> - * except for string it will pointer to beginning of string.
> - */
> char *
> -conf_get_value(struct conf_entry *ce, char *buf, int buf_len)
> +conf_str_from_value(enum conf_type type, void *vp, char *buf, int buf_len)
> {
>     int32_t val;
> 
> -    if (ce->c_type == CONF_STRING) {
> -        return ce->c_val.array.val;
> +    if (type == CONF_STRING) {
> +        return vp;
>     }
> -    switch (ce->c_type) {
> +    switch (type) {
>     case CONF_INT8:
>     case CONF_INT16:
>     case CONF_INT32:
> -        if (ce->c_type == CONF_INT8) {
> -            val = *(int8_t *)ce->c_val.single.val;
> -        } else if (ce->c_type == CONF_INT16) {
> -            val = *(int16_t *)ce->c_val.single.val;
> +        if (type == CONF_INT8) {
> +            val = *(int8_t *)vp;
> +        } else if (type == CONF_INT16) {
> +            val = *(int16_t *)vp;
>         } else {
> -            val = *(int32_t *)ce->c_val.single.val;
> +            val = *(int32_t *)vp;
>         }
>         snprintf(buf, buf_len, "%ld", (long)val);
>         return buf;
> @@ -190,3 +178,69 @@ conf_get_value(struct conf_entry *ce, char *buf, int buf_len)
>     }
> }
> 
> +int
> +conf_set_value(char *name, char *val_str)
> +{
> +    int name_argc;
> +    char *name_argv[CONF_MAX_DIR_DEPTH];
> +    struct conf_handler *ch;
> +
> +    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
> +    if (!ch) {
> +        return OS_INVALID_PARM;
> +    }
> +
> +    return ch->ch_set(name_argc - 1, &name_argv[1], val_str);
> +}
> +
> +/*
> + * Get value in printable string form. If value is not string, the value
> + * will be filled in *buf.
> + * Return value will be pointer to beginning of that buffer,
> + * except for string it will pointer to beginning of string.
> + */
> +char *
> +conf_get_value(char *name, char *buf, int buf_len)
> +{
> +    int name_argc;
> +    char *name_argv[CONF_MAX_DIR_DEPTH];
> +    struct conf_handler *ch;
> +
> +    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
> +    if (!ch) {
> +        return NULL;
> +    }
> +
> +    return ch->ch_get(name_argc - 1, &name_argv[1], buf, buf_len);
> +}
> +
> +int
> +conf_commit(char *name)
> +{
> +    int name_argc;
> +    char *name_argv[CONF_MAX_DIR_DEPTH];
> +    struct conf_handler *ch;
> +    int rc;
> +
> +    if (name) {
> +        ch = conf_parse_and_lookup(name, &name_argc, name_argv);
> +        if (!ch) {
> +            return OS_INVALID_PARM;
> +        }
> +        if (ch->ch_commit) {
> +            return ch->ch_commit();
> +        } else {
> +            return 0;
> +        }
> +    } else {
> +        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
> +            if (ch->ch_commit) {
> +                rc = ch->ch_commit();
> +                if (rc) {
> +                    return rc;
> +                }
> +            }
> +        }
> +        return 0;
> +    }
> +}
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_cli.c
> ----------------------------------------------------------------------
> diff --git a/sys/config/src/config_cli.c b/sys/config/src/config_cli.c
> index b0a2891..bfe1966 100644
> --- a/sys/config/src/config_cli.c
> +++ b/sys/config/src/config_cli.c
> @@ -32,15 +32,10 @@ shell_conf_command(int argc, char **argv)
> {
>     char *name = NULL;
>     char *val = NULL;
> -    char *name_argv[CONF_MAX_DIR_DEPTH];
>     char tmp_buf[16];
> -    int name_argc;
>     int rc;
> -    struct conf_entry *ce;
> 
>     switch (argc) {
> -    case 1:
> -        break;
>     case 2:
>         name = argv[1];
>         break;
> @@ -52,26 +47,25 @@ shell_conf_command(int argc, char **argv)
>         goto err;
>     }
> 
> -    rc = conf_parse_name(name, &name_argc, name_argv);
> -    if (rc) {
> -        goto err;
> -    }
> -
> -    ce = conf_lookup(name_argc, name_argv);
> -    if (!ce) {
> -        console_printf("No such config variable\n");
> -        goto err;
> +    if (!strcmp(name, "commit")) {
> +        rc = conf_commit(val);
> +        if (rc) {
> +            val = "Failed to commit\n";
> +        } else {
> +            val = "Done\n";
> +        }
> +        console_printf(val);
> +        return 0;
>     }
> -
>     if (!val) {
> -        val = conf_get_value(ce, tmp_buf, sizeof(tmp_buf));
> +        val = conf_get_value(name, tmp_buf, sizeof(tmp_buf));
>         if (!val) {
>             console_printf("Cannot display value\n");
>             goto err;
>         }
> -        console_printf("%s", val);
> +        console_printf("%s\n", val);
>     } else {
> -        rc = conf_set_value(ce, val);
> +        rc = conf_set_value(name, val);
>         if (rc) {
>             console_printf("Failed to set\n");
>             goto err;
> @@ -82,16 +76,11 @@ err:
>     console_printf("Invalid args\n");
>     return 0;
> }
> -#endif
> 
> -int conf_module_init(void)
> +int
> +conf_cli_register(void)
> {
> -#ifdef SHELL_PRESENT
> -    shell_cmd_register(&shell_conf_cmd, "config", shell_conf_command);
> -#endif
> -#ifdef NEWTMGR_PRESENT
> -    conf_nmgr_register();
> -#endif
> -    return 0;
> +    return shell_cmd_register(&shell_conf_cmd, "config", shell_conf_command);
> }
> +#endif
> 
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_nmgr.c
> ----------------------------------------------------------------------
> diff --git a/sys/config/src/config_nmgr.c b/sys/config/src/config_nmgr.c
> index 8d0cf34..81004d8 100644
> --- a/sys/config/src/config_nmgr.c
> +++ b/sys/config/src/config_nmgr.c
> @@ -42,9 +42,6 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
> {
>     char tmp_str[max(CONF_MAX_DIR_DEPTH * 8, 16)];
>     char *val_str;
> -    char *name_argv[CONF_MAX_DIR_DEPTH];
> -    int name_argc;
> -    struct conf_entry *ce;
>     const struct json_attr_t attr[2] = {
>         [0] = {
>             .attribute = "name",
> @@ -64,16 +61,7 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
>         return OS_EINVAL;
>     }
> 
> -    if (conf_parse_name(tmp_str, &name_argc, name_argv)) {
> -        return OS_EINVAL;
> -    }
> -
> -    ce = conf_lookup(name_argc, name_argv);
> -    if (!ce) {
> -        return OS_EINVAL;
> -    }
> -
> -    val_str = conf_get_value(ce, tmp_str, sizeof(tmp_str));
> +    val_str = conf_get_value(tmp_str, tmp_str, sizeof(tmp_str));
>     if (!val_str) {
>         return OS_EINVAL;
>     }
> @@ -89,17 +77,14 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
> static int
> conf_nmgr_write(struct nmgr_jbuf *njb)
> {
> -    char tmp_str[CONF_MAX_DIR_DEPTH * 8];
> +    char name_str[CONF_MAX_DIR_DEPTH * 8];
>     char val_str[256];
> -    char *name_argv[CONF_MAX_DIR_DEPTH];
> -    int name_argc;
> -    struct conf_entry *ce;
>     struct json_attr_t attr[3] = {
>         [0] = {
>             .attribute = "name",
>             .type = t_string,
> -            .addr.string = tmp_str,
> -            .len = sizeof(tmp_str)
> +            .addr.string = name_str,
> +            .len = sizeof(name_str)
>         },
>         [1] = {
>             .attribute = "val",
> @@ -118,16 +103,7 @@ conf_nmgr_write(struct nmgr_jbuf *njb)
>         return OS_EINVAL;
>     }
> 
> -    if (conf_parse_name(tmp_str, &name_argc, name_argv)) {
> -        return OS_EINVAL;
> -    }
> -
> -    ce = conf_lookup(name_argc, name_argv);
> -    if (!ce) {
> -        return OS_EINVAL;
> -    }
> -
> -    rc = conf_set_value(ce, val_str);
> +    rc = conf_set_value(name_str, val_str);
>     if (rc) {
>         return OS_EINVAL;
>     }
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_priv.h
> ----------------------------------------------------------------------
> diff --git a/sys/config/src/config_priv.h b/sys/config/src/config_priv.h
> index a457eb9..6217fee 100644
> --- a/sys/config/src/config_priv.h
> +++ b/sys/config/src/config_priv.h
> @@ -17,6 +17,7 @@
> #ifndef __CONFIG_PRIV_H_
> #define __CONFIG_PRIV_H_
> 
> +int conf_cli_register(void);
> int conf_nmgr_register(void);
> 
> #endif /* __CONFIG_PRIV_H_ */
> 
> http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/test/conf_test.c
> ----------------------------------------------------------------------
> diff --git a/sys/config/src/test/conf_test.c b/sys/config/src/test/conf_test.c
> index 5d0a4a0..8556275 100644
> --- a/sys/config/src/test/conf_test.c
> +++ b/sys/config/src/test/conf_test.c
> @@ -20,212 +20,154 @@
> #include <testutil/testutil.h>
> #include <config/config.h>
> 
> -uint8_t val8;
> +static uint8_t val8;
> 
> -static struct conf_entry ce1 = {
> -    .c_name = "ce1",
> -    .c_type = CONF_INT8,
> -    .c_val.single.val = &val8
> -};
> -
> -static struct conf_node cn1 = {
> -    .cn_cnt = 1,
> -    .cn_array = &ce1
> -};
> -
> -static struct conf_entry ce2 = {
> -    .c_name = "ce2",
> -    .c_type = CONF_INT8,
> -    .c_val.single.val = &val8
> -};
> -
> -static struct conf_node cn2 = {
> -    .cn_cnt = 1,
> -    .cn_array = &ce2
> -};
> +static int test_get_called;
> +static int test_set_called;
> +static int test_commit_called;
> 
> -static struct conf_entry ce_arr1[2] = {
> -    [0] = {
> -        .c_name = "cea1",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> -    },
> -    [1] = {
> -        .c_name = "cea2",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> +static char *
> +ctest_handle_get(int argc, char **argv, char *val, int val_len_max)
> +{
> +    test_get_called = 1;
> +    if (argc == 1 && !strcmp(argv[0], "mybar")) {
> +        return conf_str_from_value(CONF_INT8, &val8, val, val_len_max);
>     }
> -};
> +    return NULL;
> +}
> 
> -static struct conf_node cn_arr1 = {
> -    .cn_cnt = 2,
> -    .cn_array = ce_arr1
> -};
> +static int
> +ctest_handle_set(int argc, char **argv, char *val)
> +{
> +    uint8_t newval;
> +    int rc;
> 
> -static struct conf_entry ce_arr2[2] = {
> -    [0] = {
> -        .c_name = "ce21",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> -    },
> -    [1] = {
> -        .c_name = "cea2",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> +    test_set_called = 1;
> +    if (argc == 1 && !strcmp(argv[0], "mybar")) {
> +        rc = CONF_VALUE_SET(val, CONF_INT8, newval);
> +        TEST_ASSERT(rc == 0);
> +        val8 = newval;
> +        return 0;
>     }
> -};
> -
> -static struct conf_node cn_arr2 = {
> -    .cn_cnt = 2,
> -    .cn_array = ce_arr2
> -};
> +    return OS_ENOENT;
> +}
> 
> -static struct conf_entry_dir ce_dir = {
> -    .c_name = "foo",
> -    .c_type = CONF_DIR
> -};
> +static int
> +ctest_handle_commit(void)
> +{
> +    test_commit_called = 1;
> +    return 0;
> +}
> 
> -static struct conf_node cn_dir = {
> -    .cn_cnt = 1,
> -    .cn_array = (struct conf_entry *)&ce_dir
> +struct conf_handler config_test_handler = {
> +    .ch_name = "myfoo",
> +    .ch_get = ctest_handle_get,
> +    .ch_set = ctest_handle_set,
> +    .ch_commit = ctest_handle_commit
> };
> 
> -static struct conf_entry ce_foo_arr1[2] = {
> -    [0] = {
> -        .c_name = "foo1",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> -    },
> -    [1] = {
> -        .c_name = "foo2",
> -        .c_type = CONF_INT8,
> -        .c_val.single.val = &val8
> -    }
> -};
> +static void
> +ctest_clear_call_state(void)
> +{
> +    test_get_called = 0;
> +    test_set_called = 0;
> +    test_commit_called = 0;
> +}
> 
> -static struct conf_node cn_foo_arr1 = {
> -    .cn_cnt = 2,
> -    .cn_array = ce_foo_arr1
> -};
> +static int
> +ctest_get_call_state(void)
> +{
> +    return test_get_called + test_set_called + test_commit_called;
> +}
> 
> TEST_CASE(config_empty_lookups)
> {
> -    struct conf_entry *ce;
> -    char *names1[] = { "foo", "bar" };
> -
> -    ce = conf_lookup(0, NULL);
> -    TEST_ASSERT(ce == NULL);
> +    int rc;
> +    char tmp[64], *str;
> 
> -    ce = conf_lookup(1, names1);
> -    TEST_ASSERT(ce == NULL);
> +    rc = conf_set_value("foo/bar", "tmp");
> +    TEST_ASSERT(rc != 0);
> 
> -    ce = conf_lookup(2, names1);
> -    TEST_ASSERT(ce == NULL);
> +    str = conf_get_value("foo/bar", tmp, sizeof(tmp));
> +    TEST_ASSERT(str == NULL);
> }
> 
> TEST_CASE(config_test_insert)
> {
>     int rc;
> 
> -    /*
> -     * Add 2 new ones
> -     */
> -    rc = conf_register(NULL, &cn1);
> +    rc = conf_register(&config_test_handler);
>     TEST_ASSERT(rc == 0);
> -    rc = conf_register(NULL, &cn2);
> -    TEST_ASSERT(rc == 0);
> -
> -    /*
> -     * Fail adding same ones again
> -     */
> -    rc = conf_register(NULL, &cn1);
> -    TEST_ASSERT(rc != 0);
> -    rc = conf_register(NULL, &cn2);
> -    TEST_ASSERT(rc != 0);
> -
> -    /*
> -     * Add with multiple conf_entries
> -     */
> -    rc = conf_register(NULL, &cn_arr1);
> -    TEST_ASSERT(rc == 0);
> -
> -    /*
> -     * Cannot add it again
> -     */
> -    rc = conf_register(NULL, &cn_arr1);
> -    TEST_ASSERT(rc != 0);
> -
> -    /*
> -     * Should fail right away
> -     */
> -    rc = conf_register(NULL, &cn_arr2);
> -    TEST_ASSERT(rc != 0);
> -
> }
> 
> -TEST_CASE(config_test_lookup)
> +TEST_CASE(config_test_getset_unknown)
> {
> -    struct conf_entry *ce;
> -    char *names1[] = { "foo", "bar" };
> -    char *names2[] = { "ce1" };
> -    char *names3[] = { "cea2" };
> -
> -    ce = conf_lookup(0, NULL);
> -    TEST_ASSERT(ce == NULL);
> +    char tmp[64], *str;
> +    int rc;
> 
> -    ce = conf_lookup(1, names1);
> -    TEST_ASSERT(ce == NULL);
> +    rc = conf_set_value("foo/bar", "tmp");
> +    TEST_ASSERT(rc != 0);
> +    TEST_ASSERT(ctest_get_call_state() == 0);
> 
> -    ce = conf_lookup(2, names1);
> -    TEST_ASSERT(ce == NULL);
> +    str = conf_get_value("foo/bar", tmp, sizeof(tmp));
> +    TEST_ASSERT(str == NULL);
> +    TEST_ASSERT(ctest_get_call_state() == 0);
> 
> -    ce = conf_lookup(1, names2);
> -    TEST_ASSERT(ce != NULL);
> -    TEST_ASSERT(!strcmp(ce->c_name, names2[0]));
> +    rc = conf_set_value("myfoo/bar", "tmp");
> +    TEST_ASSERT(rc == OS_ENOENT);
> +    TEST_ASSERT(test_set_called == 1);
> +    ctest_clear_call_state();
> 
> -    ce = conf_lookup(1, names3);
> -    TEST_ASSERT(ce != NULL);
> -    TEST_ASSERT(!strcmp(ce->c_name, names3[0]));
> +    str = conf_get_value("myfoo/bar", tmp, sizeof(tmp));
> +    TEST_ASSERT(str == NULL);
> +    TEST_ASSERT(test_get_called == 1);
> +    ctest_clear_call_state();
> }
> 
> -TEST_CASE(config_test_dir)
> +TEST_CASE(config_test_getset_int)
> {
> +    char tmp[64], *str;
>     int rc;
> -    struct conf_entry *ce;
> -    char *names1[] = { "foo", "foo1" };
> -    char *names2[] = { "foo", "foo2" };
> -    char *names3[] = { "foo", "foo3" };
> -
> -    /*
> -     * Add directory node, and node under.
> -     */
> -    rc = conf_register(NULL, &cn_dir);
> -    TEST_ASSERT(rc == 0);
> -    rc = conf_register(&cn_dir, &cn_foo_arr1);
> +
> +    rc = conf_set_value("myfoo/mybar", "42");
>     TEST_ASSERT(rc == 0);
> +    TEST_ASSERT(test_set_called == 1);
> +    TEST_ASSERT(val8 == 42);
> +    ctest_clear_call_state();
> +
> +    str = conf_get_value("myfoo/mybar", tmp, sizeof(tmp));
> +    TEST_ASSERT(str);
> +    TEST_ASSERT(test_get_called == 1);
> +    TEST_ASSERT(!strcmp("42", tmp));
> +    ctest_clear_call_state();
> +}
> 
> -    ce = conf_lookup(1, names1);
> -    TEST_ASSERT(ce != NULL);
> -    TEST_ASSERT(ce->c_type == CONF_DIR);
> +TEST_CASE(config_test_commit)
> +{
> +    int rc;
> 
> -    ce = conf_lookup(2, names1);
> -    TEST_ASSERT(ce != NULL);
> -    TEST_ASSERT(!strcmp(ce->c_name, names1[1]));
> +    rc = conf_commit("bar");
> +    TEST_ASSERT(rc == 0);
> +    TEST_ASSERT(ctest_get_call_state());
> 
> -    ce = conf_lookup(2, names2);
> -    TEST_ASSERT(ce != NULL);
> -    TEST_ASSERT(!strcmp(ce->c_name, names2[1]));
> +    rc = conf_commit(NULL);
> +    TEST_ASSERT(rc == 0);
> +    TEST_ASSERT(test_commit_called == 1);
> +    ctest_clear_call_state();
> 
> -    ce = conf_lookup(2, names3);
> -    TEST_ASSERT(ce == NULL);
> +    rc = conf_commit("myfoo");
> +    TEST_ASSERT(rc == 0);
> +    TEST_ASSERT(test_commit_called == 1);
> +    ctest_clear_call_state();
> }
> 
> TEST_SUITE(config_test_suite)
> {
>     config_empty_lookups();
>     config_test_insert();
> -    config_test_lookup();
> -    config_test_dir();
> +    config_test_getset_unknown();
> +    config_test_getset_int();
> +    config_test_commit();
> }
> 
> #ifdef PKG_TEST
> @@ -236,7 +178,7 @@ main(int argc, char **argv)
>     tu_config.tc_print_results = 1;
>     tu_init();
> 
> -    config_test_suite();
> +    conf_init();
> 
>     return tu_any_failed;
> }
> 


[3/3] incubator-mynewt-larva git commit: Second take on the config system.

Posted by ma...@apache.org.
Second take on the config system.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/ccda6d4b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/ccda6d4b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/ccda6d4b

Branch: refs/heads/master
Commit: ccda6d4b166c1034cb7ec1dacd88378ffa6b7b56
Parents: 6689163
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Jan 29 12:49:47 2016 -0800
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Jan 29 12:49:47 2016 -0800

----------------------------------------------------------------------
 project/blinky/src/main.c          |   2 +-
 project/slinky/src/main.c          |  74 +++++----
 sys/config/include/config/config.h |  48 +++---
 sys/config/src/config.c            | 218 ++++++++++++++++----------
 sys/config/src/config_cli.c        |  43 ++----
 sys/config/src/config_nmgr.c       |  34 +---
 sys/config/src/config_priv.h       |   1 +
 sys/config/src/test/conf_test.c    | 266 +++++++++++++-------------------
 8 files changed, 326 insertions(+), 360 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/project/blinky/src/main.c
----------------------------------------------------------------------
diff --git a/project/blinky/src/main.c b/project/blinky/src/main.c
index 43b985e..81637c6 100755
--- a/project/blinky/src/main.c
+++ b/project/blinky/src/main.c
@@ -158,7 +158,7 @@ main(int argc, char **argv)
     mcu_sim_parse_args(argc, argv);
 #endif
 
-    conf_module_init();
+    conf_init();
 
     cbmem_init(&log_mem, log_buf, sizeof(log_buf));
     util_log_cbmem_handler_init(&log_mem_handler, &log_mem);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/project/slinky/src/main.c
----------------------------------------------------------------------
diff --git a/project/slinky/src/main.c b/project/slinky/src/main.c
index f0c8f7a..dd2ffad 100755
--- a/project/slinky/src/main.c
+++ b/project/slinky/src/main.c
@@ -85,35 +85,54 @@ uint8_t default_mbuf_mpool_data[DEFAULT_MBUF_MPOOL_BUF_LEN *
 struct os_mbuf_pool default_mbuf_pool;
 struct os_mempool default_mbuf_mpool;
 
+static char *test_conf_get(int argc, char **argv, char *val, int max_len);
+static int test_conf_set(int argc, char **argv, char *val);
+static int test_conf_commit(void);
+
+static struct conf_handler test_conf_handler = {
+    .ch_name = "test",
+    .ch_get = test_conf_get,
+    .ch_set = test_conf_set,
+    .ch_commit = test_conf_commit
+};
+
 static uint8_t test8;
+static uint8_t test8_shadow;
 static char test_str[32];
 
-static const struct conf_entry test_conf_array[2] = {
-    [0] = {
-        .c_name = "8",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &test8
-    },
-    [1] = {
-        .c_name = "str",
-        .c_type = CONF_STRING,
-        .c_val.array.val = test_str,
-        .c_val.array.maxlen = sizeof(test_str)
+static char *
+test_conf_get(int argc, char **argv, char *buf, int max_len)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
+        } else if (!strcmp(argv[0], "str")) {
+            return test_str;
+        }
     }
-};
-static struct conf_node test_conf_array_node = {
-    .cn_cnt = 2,
-    .cn_array = (struct conf_entry *)test_conf_array
-};
+    return NULL;
+}
 
-static const struct conf_entry test_conf_dir = {
-    .c_name = "test",
-    .c_type = CONF_DIR
-};
-static struct conf_node test_conf_dir_node = {
-    .cn_cnt = 1,
-    .cn_array = (struct conf_entry *)&test_conf_dir
-};
+static int
+test_conf_set(int argc, char **argv, char *val)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
+        } else if (!strcmp(argv[0], "str")) {
+            return CONF_VALUE_SET(val, CONF_STRING, test_str);
+        }
+    }
+    return OS_ENOENT;
+}
+
+static int
+test_conf_commit(void)
+{
+    test8 = test8_shadow;
+
+    return 0;
+}
 
 void
 task1_handler(void *arg)
@@ -205,11 +224,8 @@ main(int argc, char **argv)
     mcu_sim_parse_args(argc, argv);
 #endif
 
-    conf_module_init();
-    rc = conf_register(NULL, &test_conf_dir_node);
-    assert(rc == 0);
-
-    rc = conf_register(&test_conf_dir_node, &test_conf_array_node);
+    conf_init();
+    rc = conf_register(&test_conf_handler);
     assert(rc == 0);
 
     cbmem_init(&log_mem, log_buf, sizeof(log_buf));

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/include/config/config.h
----------------------------------------------------------------------
diff --git a/sys/config/include/config/config.h b/sys/config/include/config/config.h
index 59b68b2..717f711 100644
--- a/sys/config/include/config/config.h
+++ b/sys/config/include/config/config.h
@@ -37,39 +37,27 @@ enum conf_type {
     CONF_DOUBLE
 } __attribute__((__packed__));
 
-struct conf_entry {
-    const char *c_name;
-    enum conf_type c_type;
-    union {
-        struct {	/* INT8, INT16, INT32, INT64, FLOAT, DOUBLE */
-            void *val;
-        } single;
-        struct {	/* STRING, BYTES */
-            uint16_t maxlen;
-            uint16_t len;
-            void *val;
-        } array;
-    } c_val;
+struct conf_handler {
+    SLIST_ENTRY(conf_handler) ch_list;
+    char *ch_name;
+    char *(*ch_get)(int argc, char **argv, char *val, int val_len_max);
+    int (*ch_set)(int argc, char **argv, char *val);
+    int (*ch_commit)();
 };
 
-struct conf_entry_dir {
-    const char *c_name;
-    enum conf_type c_type;	/* DIR */
-};
-
-struct conf_node {
-    SLIST_ENTRY(conf_node) cn_next;
-    SLIST_HEAD(, conf_node) cn_children;
-    struct conf_entry *cn_array;
-    int cn_cnt;
-};
+int conf_init(void);
+int conf_register(struct conf_handler *);
+int conf_load(void);
 
-int conf_module_init(void);
-int conf_register(struct conf_node *parent, struct conf_node *child);
-struct conf_entry *conf_lookup(int argc, char **argv);
+int conf_set_value(char *name, char *val_str);
+char *conf_get_value(char *name, char *buf, int buf_len);
+int conf_commit(char *name);
 
-int conf_parse_name(char *name, int *name_argc, char *name_argv[]);
-int conf_set_value(struct conf_entry *ce, char *val_str);
-char *conf_get_value(struct conf_entry *ce, char *buf, int buf_len);
+int conf_value_from_str(char *val_str, enum conf_type type, void *vp,
+  int maxlen);
+char *conf_str_from_value(enum conf_type type, void *vp, char *buf,
+  int buf_len);
+#define CONF_VALUE_SET(str, type, val)                                  \
+    conf_value_from_str((str), (type), &(val), sizeof(val))
 
 #endif /* __UTIL_CONFIG_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config.c
----------------------------------------------------------------------
diff --git a/sys/config/src/config.c b/sys/config/src/config.c
index d7f6d54..ff2b6ab 100644
--- a/sys/config/src/config.c
+++ b/sys/config/src/config.c
@@ -17,77 +17,61 @@
 #include <string.h>
 #include <stdio.h>
 
-#include "config/config.h"
+#include <os/os.h>
 
-#ifdef SHELL_PRESENT
-#include <shell/shell.h>
-#include <console/console.h>
-#endif
+#include "config/config.h"
+#include "config_priv.h"
 
-static struct conf_node g_conf_root;
+static SLIST_HEAD(, conf_handler) conf_handlers =
+    SLIST_HEAD_INITIALIZER(&conf_handlers);
 
-static struct conf_entry *
-conf_node_match(struct conf_node *cn, const char *name)
+int
+conf_init(void)
 {
-    int i;
+    int rc = 0;
 
-    for (i = 0; i < cn->cn_cnt; i++) {
-        if (!strcmp(name, cn->cn_array[i].c_name)) {
-            return &cn->cn_array[i];
-        }
-    }
-    return NULL;
+#ifdef SHELL_PRESENT
+    rc = conf_cli_register();
+#endif
+#ifdef NEWTMGR_PRESENT
+    rc = conf_nmgr_register();
+#endif
+    return rc;
 }
 
-/*
- * Register config node to a specific spot in the tree.
- */
 int
-conf_register(struct conf_node *parent, struct conf_node *child)
+conf_register(struct conf_handler *handler)
 {
-    struct conf_node *cn;
-    int i;
-
-    if (!parent) {
-        parent = &g_conf_root;
-    }
+    SLIST_INSERT_HEAD(&conf_handlers, handler, ch_list);
+    return 0;
+}
 
-    for (i = 0; i < child->cn_cnt; i++) {
-        SLIST_FOREACH(cn, &parent->cn_children, cn_next) {
-            if (conf_node_match(cn, child->cn_array[i].c_name)) {
-                return -1;
-            }
-        }
-    }
-    SLIST_INSERT_HEAD(&parent->cn_children, child, cn_next);
+int
+conf_load(void)
+{
+    /*
+     * for every config source
+     *    load config
+     *    apply config
+     *    commit all
+     */
     return 0;
 }
 
 /*
- * Lookup conf_entry based on name.
+ * Find conf_handler based on name.
  */
-struct conf_entry *
-conf_lookup(int argc, char **argv)
+struct conf_handler *
+conf_handler_lookup(char *name)
 {
-    int i;
-    struct conf_node *parent = &g_conf_root;
-    struct conf_entry *ret = NULL;
-    struct conf_node *cn;
-
-    for (i = 0; i < argc; i++) {
-        ret = NULL;
-        SLIST_FOREACH(cn, &parent->cn_children, cn_next) {
-            ret = conf_node_match(cn, argv[i]);
-            if (ret) {
-                break;
-            }
-        }
-        parent = cn;
-        if (!parent) {
-            return NULL;
+    struct conf_handler *ch;
+
+    SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+        if (!strcmp(name, ch->ch_name)) {
+            return ch;
         }
     }
-    return ret;
+    return NULL;
 }
 
 /*
@@ -113,13 +97,25 @@ conf_parse_name(char *name, int *name_argc, char *name_argv[])
     return 0;
 }
 
+static struct conf_handler *
+conf_parse_and_lookup(char *name, int *name_argc, char *name_argv[])
+{
+    int rc;
+
+    rc = conf_parse_name(name, name_argc, name_argv);
+    if (rc) {
+        return NULL;
+    }
+    return conf_handler_lookup(name_argv[0]);
+}
+
 int
-conf_set_value(struct conf_entry *ce, char *val_str)
+conf_value_from_str(char *val_str, enum conf_type type, void *vp, int maxlen)
 {
     int32_t val;
     char *eptr;
 
-    switch (ce->c_type) {
+    switch (type) {
     case CONF_INT8:
     case CONF_INT16:
     case CONF_INT32:
@@ -127,61 +123,53 @@ conf_set_value(struct conf_entry *ce, char *val_str)
         if (*eptr != '\0') {
             goto err;
         }
-        if (ce->c_type == CONF_INT8) {
+        if (type == CONF_INT8) {
             if (val < INT8_MIN || val > UINT8_MAX) {
                 goto err;
             }
-            *(int8_t *)ce->c_val.single.val = val;
-        } else if (ce->c_type == CONF_INT16) {
+            *(int8_t *)vp = val;
+        } else if (type == CONF_INT16) {
             if (val < INT16_MIN || val > UINT16_MAX) {
                 goto err;
             }
-            *(int16_t *)ce->c_val.single.val = val;
-        } else if (ce->c_type == CONF_INT32) {
-            *(int32_t *)ce->c_val.single.val = val;
+            *(int16_t *)vp = val;
+        } else if (type == CONF_INT32) {
+            *(int32_t *)vp = val;
         }
         break;
     case CONF_STRING:
         val = strlen(val_str);
-        if (val + 1 > ce->c_val.array.maxlen) {
+        if (val + 1 > maxlen) {
             goto err;
         }
-        strcpy(ce->c_val.array.val, val_str);
-        ce->c_val.array.len = val;
+        strcpy(vp, val_str);
         break;
     default:
-        console_printf("Can't parse type %d\n", ce->c_type);
-        break;
+        goto err;
     }
     return 0;
 err:
-    return -1;
+    return OS_INVALID_PARM;
 }
 
-/*
- * Get value in printable string form. If value is not string, the value
- * will be filled in *buf.
- * Return value will be pointer to beginning of that buffer,
- * except for string it will pointer to beginning of string.
- */
 char *
-conf_get_value(struct conf_entry *ce, char *buf, int buf_len)
+conf_str_from_value(enum conf_type type, void *vp, char *buf, int buf_len)
 {
     int32_t val;
 
-    if (ce->c_type == CONF_STRING) {
-        return ce->c_val.array.val;
+    if (type == CONF_STRING) {
+        return vp;
     }
-    switch (ce->c_type) {
+    switch (type) {
     case CONF_INT8:
     case CONF_INT16:
     case CONF_INT32:
-        if (ce->c_type == CONF_INT8) {
-            val = *(int8_t *)ce->c_val.single.val;
-        } else if (ce->c_type == CONF_INT16) {
-            val = *(int16_t *)ce->c_val.single.val;
+        if (type == CONF_INT8) {
+            val = *(int8_t *)vp;
+        } else if (type == CONF_INT16) {
+            val = *(int16_t *)vp;
         } else {
-            val = *(int32_t *)ce->c_val.single.val;
+            val = *(int32_t *)vp;
         }
         snprintf(buf, buf_len, "%ld", (long)val);
         return buf;
@@ -190,3 +178,69 @@ conf_get_value(struct conf_entry *ce, char *buf, int buf_len)
     }
 }
 
+int
+conf_set_value(char *name, char *val_str)
+{
+    int name_argc;
+    char *name_argv[CONF_MAX_DIR_DEPTH];
+    struct conf_handler *ch;
+
+    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
+    if (!ch) {
+        return OS_INVALID_PARM;
+    }
+
+    return ch->ch_set(name_argc - 1, &name_argv[1], val_str);
+}
+
+/*
+ * Get value in printable string form. If value is not string, the value
+ * will be filled in *buf.
+ * Return value will be pointer to beginning of that buffer,
+ * except for string it will pointer to beginning of string.
+ */
+char *
+conf_get_value(char *name, char *buf, int buf_len)
+{
+    int name_argc;
+    char *name_argv[CONF_MAX_DIR_DEPTH];
+    struct conf_handler *ch;
+
+    ch = conf_parse_and_lookup(name, &name_argc, name_argv);
+    if (!ch) {
+        return NULL;
+    }
+
+    return ch->ch_get(name_argc - 1, &name_argv[1], buf, buf_len);
+}
+
+int
+conf_commit(char *name)
+{
+    int name_argc;
+    char *name_argv[CONF_MAX_DIR_DEPTH];
+    struct conf_handler *ch;
+    int rc;
+
+    if (name) {
+        ch = conf_parse_and_lookup(name, &name_argc, name_argv);
+        if (!ch) {
+            return OS_INVALID_PARM;
+        }
+        if (ch->ch_commit) {
+            return ch->ch_commit();
+        } else {
+            return 0;
+        }
+    } else {
+        SLIST_FOREACH(ch, &conf_handlers, ch_list) {
+            if (ch->ch_commit) {
+                rc = ch->ch_commit();
+                if (rc) {
+                    return rc;
+                }
+            }
+        }
+        return 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_cli.c
----------------------------------------------------------------------
diff --git a/sys/config/src/config_cli.c b/sys/config/src/config_cli.c
index b0a2891..bfe1966 100644
--- a/sys/config/src/config_cli.c
+++ b/sys/config/src/config_cli.c
@@ -32,15 +32,10 @@ shell_conf_command(int argc, char **argv)
 {
     char *name = NULL;
     char *val = NULL;
-    char *name_argv[CONF_MAX_DIR_DEPTH];
     char tmp_buf[16];
-    int name_argc;
     int rc;
-    struct conf_entry *ce;
 
     switch (argc) {
-    case 1:
-        break;
     case 2:
         name = argv[1];
         break;
@@ -52,26 +47,25 @@ shell_conf_command(int argc, char **argv)
         goto err;
     }
 
-    rc = conf_parse_name(name, &name_argc, name_argv);
-    if (rc) {
-        goto err;
-    }
-
-    ce = conf_lookup(name_argc, name_argv);
-    if (!ce) {
-        console_printf("No such config variable\n");
-        goto err;
+    if (!strcmp(name, "commit")) {
+        rc = conf_commit(val);
+        if (rc) {
+            val = "Failed to commit\n";
+        } else {
+            val = "Done\n";
+        }
+        console_printf(val);
+        return 0;
     }
-
     if (!val) {
-        val = conf_get_value(ce, tmp_buf, sizeof(tmp_buf));
+        val = conf_get_value(name, tmp_buf, sizeof(tmp_buf));
         if (!val) {
             console_printf("Cannot display value\n");
             goto err;
         }
-        console_printf("%s", val);
+        console_printf("%s\n", val);
     } else {
-        rc = conf_set_value(ce, val);
+        rc = conf_set_value(name, val);
         if (rc) {
             console_printf("Failed to set\n");
             goto err;
@@ -82,16 +76,11 @@ err:
     console_printf("Invalid args\n");
     return 0;
 }
-#endif
 
-int conf_module_init(void)
+int
+conf_cli_register(void)
 {
-#ifdef SHELL_PRESENT
-    shell_cmd_register(&shell_conf_cmd, "config", shell_conf_command);
-#endif
-#ifdef NEWTMGR_PRESENT
-    conf_nmgr_register();
-#endif
-    return 0;
+    return shell_cmd_register(&shell_conf_cmd, "config", shell_conf_command);
 }
+#endif
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_nmgr.c
----------------------------------------------------------------------
diff --git a/sys/config/src/config_nmgr.c b/sys/config/src/config_nmgr.c
index 8d0cf34..81004d8 100644
--- a/sys/config/src/config_nmgr.c
+++ b/sys/config/src/config_nmgr.c
@@ -42,9 +42,6 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
 {
     char tmp_str[max(CONF_MAX_DIR_DEPTH * 8, 16)];
     char *val_str;
-    char *name_argv[CONF_MAX_DIR_DEPTH];
-    int name_argc;
-    struct conf_entry *ce;
     const struct json_attr_t attr[2] = {
         [0] = {
             .attribute = "name",
@@ -64,16 +61,7 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
         return OS_EINVAL;
     }
 
-    if (conf_parse_name(tmp_str, &name_argc, name_argv)) {
-        return OS_EINVAL;
-    }
-
-    ce = conf_lookup(name_argc, name_argv);
-    if (!ce) {
-        return OS_EINVAL;
-    }
-
-    val_str = conf_get_value(ce, tmp_str, sizeof(tmp_str));
+    val_str = conf_get_value(tmp_str, tmp_str, sizeof(tmp_str));
     if (!val_str) {
         return OS_EINVAL;
     }
@@ -89,17 +77,14 @@ conf_nmgr_read(struct nmgr_jbuf *njb)
 static int
 conf_nmgr_write(struct nmgr_jbuf *njb)
 {
-    char tmp_str[CONF_MAX_DIR_DEPTH * 8];
+    char name_str[CONF_MAX_DIR_DEPTH * 8];
     char val_str[256];
-    char *name_argv[CONF_MAX_DIR_DEPTH];
-    int name_argc;
-    struct conf_entry *ce;
     struct json_attr_t attr[3] = {
         [0] = {
             .attribute = "name",
             .type = t_string,
-            .addr.string = tmp_str,
-            .len = sizeof(tmp_str)
+            .addr.string = name_str,
+            .len = sizeof(name_str)
         },
         [1] = {
             .attribute = "val",
@@ -118,16 +103,7 @@ conf_nmgr_write(struct nmgr_jbuf *njb)
         return OS_EINVAL;
     }
 
-    if (conf_parse_name(tmp_str, &name_argc, name_argv)) {
-        return OS_EINVAL;
-    }
-
-    ce = conf_lookup(name_argc, name_argv);
-    if (!ce) {
-        return OS_EINVAL;
-    }
-
-    rc = conf_set_value(ce, val_str);
+    rc = conf_set_value(name_str, val_str);
     if (rc) {
         return OS_EINVAL;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/config_priv.h
----------------------------------------------------------------------
diff --git a/sys/config/src/config_priv.h b/sys/config/src/config_priv.h
index a457eb9..6217fee 100644
--- a/sys/config/src/config_priv.h
+++ b/sys/config/src/config_priv.h
@@ -17,6 +17,7 @@
 #ifndef __CONFIG_PRIV_H_
 #define __CONFIG_PRIV_H_
 
+int conf_cli_register(void);
 int conf_nmgr_register(void);
 
 #endif /* __CONFIG_PRIV_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/ccda6d4b/sys/config/src/test/conf_test.c
----------------------------------------------------------------------
diff --git a/sys/config/src/test/conf_test.c b/sys/config/src/test/conf_test.c
index 5d0a4a0..8556275 100644
--- a/sys/config/src/test/conf_test.c
+++ b/sys/config/src/test/conf_test.c
@@ -20,212 +20,154 @@
 #include <testutil/testutil.h>
 #include <config/config.h>
 
-uint8_t val8;
+static uint8_t val8;
 
-static struct conf_entry ce1 = {
-    .c_name = "ce1",
-    .c_type = CONF_INT8,
-    .c_val.single.val = &val8
-};
-
-static struct conf_node cn1 = {
-    .cn_cnt = 1,
-    .cn_array = &ce1
-};
-
-static struct conf_entry ce2 = {
-    .c_name = "ce2",
-    .c_type = CONF_INT8,
-    .c_val.single.val = &val8
-};
-
-static struct conf_node cn2 = {
-    .cn_cnt = 1,
-    .cn_array = &ce2
-};
+static int test_get_called;
+static int test_set_called;
+static int test_commit_called;
 
-static struct conf_entry ce_arr1[2] = {
-    [0] = {
-        .c_name = "cea1",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
-    },
-    [1] = {
-        .c_name = "cea2",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
+static char *
+ctest_handle_get(int argc, char **argv, char *val, int val_len_max)
+{
+    test_get_called = 1;
+    if (argc == 1 && !strcmp(argv[0], "mybar")) {
+        return conf_str_from_value(CONF_INT8, &val8, val, val_len_max);
     }
-};
+    return NULL;
+}
 
-static struct conf_node cn_arr1 = {
-    .cn_cnt = 2,
-    .cn_array = ce_arr1
-};
+static int
+ctest_handle_set(int argc, char **argv, char *val)
+{
+    uint8_t newval;
+    int rc;
 
-static struct conf_entry ce_arr2[2] = {
-    [0] = {
-        .c_name = "ce21",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
-    },
-    [1] = {
-        .c_name = "cea2",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
+    test_set_called = 1;
+    if (argc == 1 && !strcmp(argv[0], "mybar")) {
+        rc = CONF_VALUE_SET(val, CONF_INT8, newval);
+        TEST_ASSERT(rc == 0);
+        val8 = newval;
+        return 0;
     }
-};
-
-static struct conf_node cn_arr2 = {
-    .cn_cnt = 2,
-    .cn_array = ce_arr2
-};
+    return OS_ENOENT;
+}
 
-static struct conf_entry_dir ce_dir = {
-    .c_name = "foo",
-    .c_type = CONF_DIR
-};
+static int
+ctest_handle_commit(void)
+{
+    test_commit_called = 1;
+    return 0;
+}
 
-static struct conf_node cn_dir = {
-    .cn_cnt = 1,
-    .cn_array = (struct conf_entry *)&ce_dir
+struct conf_handler config_test_handler = {
+    .ch_name = "myfoo",
+    .ch_get = ctest_handle_get,
+    .ch_set = ctest_handle_set,
+    .ch_commit = ctest_handle_commit
 };
 
-static struct conf_entry ce_foo_arr1[2] = {
-    [0] = {
-        .c_name = "foo1",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
-    },
-    [1] = {
-        .c_name = "foo2",
-        .c_type = CONF_INT8,
-        .c_val.single.val = &val8
-    }
-};
+static void
+ctest_clear_call_state(void)
+{
+    test_get_called = 0;
+    test_set_called = 0;
+    test_commit_called = 0;
+}
 
-static struct conf_node cn_foo_arr1 = {
-    .cn_cnt = 2,
-    .cn_array = ce_foo_arr1
-};
+static int
+ctest_get_call_state(void)
+{
+    return test_get_called + test_set_called + test_commit_called;
+}
 
 TEST_CASE(config_empty_lookups)
 {
-    struct conf_entry *ce;
-    char *names1[] = { "foo", "bar" };
-
-    ce = conf_lookup(0, NULL);
-    TEST_ASSERT(ce == NULL);
+    int rc;
+    char tmp[64], *str;
 
-    ce = conf_lookup(1, names1);
-    TEST_ASSERT(ce == NULL);
+    rc = conf_set_value("foo/bar", "tmp");
+    TEST_ASSERT(rc != 0);
 
-    ce = conf_lookup(2, names1);
-    TEST_ASSERT(ce == NULL);
+    str = conf_get_value("foo/bar", tmp, sizeof(tmp));
+    TEST_ASSERT(str == NULL);
 }
 
 TEST_CASE(config_test_insert)
 {
     int rc;
 
-    /*
-     * Add 2 new ones
-     */
-    rc = conf_register(NULL, &cn1);
+    rc = conf_register(&config_test_handler);
     TEST_ASSERT(rc == 0);
-    rc = conf_register(NULL, &cn2);
-    TEST_ASSERT(rc == 0);
-
-    /*
-     * Fail adding same ones again
-     */
-    rc = conf_register(NULL, &cn1);
-    TEST_ASSERT(rc != 0);
-    rc = conf_register(NULL, &cn2);
-    TEST_ASSERT(rc != 0);
-
-    /*
-     * Add with multiple conf_entries
-     */
-    rc = conf_register(NULL, &cn_arr1);
-    TEST_ASSERT(rc == 0);
-
-    /*
-     * Cannot add it again
-     */
-    rc = conf_register(NULL, &cn_arr1);
-    TEST_ASSERT(rc != 0);
-
-    /*
-     * Should fail right away
-     */
-    rc = conf_register(NULL, &cn_arr2);
-    TEST_ASSERT(rc != 0);
-
 }
 
-TEST_CASE(config_test_lookup)
+TEST_CASE(config_test_getset_unknown)
 {
-    struct conf_entry *ce;
-    char *names1[] = { "foo", "bar" };
-    char *names2[] = { "ce1" };
-    char *names3[] = { "cea2" };
-
-    ce = conf_lookup(0, NULL);
-    TEST_ASSERT(ce == NULL);
+    char tmp[64], *str;
+    int rc;
 
-    ce = conf_lookup(1, names1);
-    TEST_ASSERT(ce == NULL);
+    rc = conf_set_value("foo/bar", "tmp");
+    TEST_ASSERT(rc != 0);
+    TEST_ASSERT(ctest_get_call_state() == 0);
 
-    ce = conf_lookup(2, names1);
-    TEST_ASSERT(ce == NULL);
+    str = conf_get_value("foo/bar", tmp, sizeof(tmp));
+    TEST_ASSERT(str == NULL);
+    TEST_ASSERT(ctest_get_call_state() == 0);
 
-    ce = conf_lookup(1, names2);
-    TEST_ASSERT(ce != NULL);
-    TEST_ASSERT(!strcmp(ce->c_name, names2[0]));
+    rc = conf_set_value("myfoo/bar", "tmp");
+    TEST_ASSERT(rc == OS_ENOENT);
+    TEST_ASSERT(test_set_called == 1);
+    ctest_clear_call_state();
 
-    ce = conf_lookup(1, names3);
-    TEST_ASSERT(ce != NULL);
-    TEST_ASSERT(!strcmp(ce->c_name, names3[0]));
+    str = conf_get_value("myfoo/bar", tmp, sizeof(tmp));
+    TEST_ASSERT(str == NULL);
+    TEST_ASSERT(test_get_called == 1);
+    ctest_clear_call_state();
 }
 
-TEST_CASE(config_test_dir)
+TEST_CASE(config_test_getset_int)
 {
+    char tmp[64], *str;
     int rc;
-    struct conf_entry *ce;
-    char *names1[] = { "foo", "foo1" };
-    char *names2[] = { "foo", "foo2" };
-    char *names3[] = { "foo", "foo3" };
-
-    /*
-     * Add directory node, and node under.
-     */
-    rc = conf_register(NULL, &cn_dir);
-    TEST_ASSERT(rc == 0);
-    rc = conf_register(&cn_dir, &cn_foo_arr1);
+
+    rc = conf_set_value("myfoo/mybar", "42");
     TEST_ASSERT(rc == 0);
+    TEST_ASSERT(test_set_called == 1);
+    TEST_ASSERT(val8 == 42);
+    ctest_clear_call_state();
+
+    str = conf_get_value("myfoo/mybar", tmp, sizeof(tmp));
+    TEST_ASSERT(str);
+    TEST_ASSERT(test_get_called == 1);
+    TEST_ASSERT(!strcmp("42", tmp));
+    ctest_clear_call_state();
+}
 
-    ce = conf_lookup(1, names1);
-    TEST_ASSERT(ce != NULL);
-    TEST_ASSERT(ce->c_type == CONF_DIR);
+TEST_CASE(config_test_commit)
+{
+    int rc;
 
-    ce = conf_lookup(2, names1);
-    TEST_ASSERT(ce != NULL);
-    TEST_ASSERT(!strcmp(ce->c_name, names1[1]));
+    rc = conf_commit("bar");
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(ctest_get_call_state());
 
-    ce = conf_lookup(2, names2);
-    TEST_ASSERT(ce != NULL);
-    TEST_ASSERT(!strcmp(ce->c_name, names2[1]));
+    rc = conf_commit(NULL);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(test_commit_called == 1);
+    ctest_clear_call_state();
 
-    ce = conf_lookup(2, names3);
-    TEST_ASSERT(ce == NULL);
+    rc = conf_commit("myfoo");
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(test_commit_called == 1);
+    ctest_clear_call_state();
 }
 
 TEST_SUITE(config_test_suite)
 {
     config_empty_lookups();
     config_test_insert();
-    config_test_lookup();
-    config_test_dir();
+    config_test_getset_unknown();
+    config_test_getset_int();
+    config_test_commit();
 }
 
 #ifdef PKG_TEST
@@ -236,7 +178,7 @@ main(int argc, char **argv)
     tu_config.tc_print_results = 1;
     tu_init();
 
-    config_test_suite();
+    conf_init();
 
     return tu_any_failed;
 }