sys/log; move log module to sys/log/full.
This package exports api 'log'.
Packages which used to depend on 'sys/log' now depend on that API.
Update apps/unit tests to depend on sys/log/full.


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

Branch: refs/heads/develop
Commit: 008962911000947171c4a0be9216aff6c4fbf27c
Parents: 5d40716
Author: Marko Kiiskila <[email protected]>
Authored: Tue Jan 17 15:42:40 2017 -0800
Committer: Marko Kiiskila <[email protected]>
Committed: Tue Jan 17 15:42:40 2017 -0800

----------------------------------------------------------------------
 apps/blecent/pkg.yml                            |   3 +-
 apps/bleprph/pkg.yml                            |   2 +-
 apps/bletest/pkg.yml                            |   2 +-
 apps/bletiny/pkg.yml                            |   2 +-
 apps/bleuart/pkg.yml                            |   3 +-
 apps/fat2native/pkg.yml                         |   2 +
 apps/ffs2native/pkg.yml                         |   1 +
 apps/ocf_sample/pkg.yml                         |   2 +-
 apps/slinky/pkg.yml                             |   2 +-
 apps/slinky_oic/pkg.yml                         |   2 +-
 apps/spitest/pkg.yml                            |   2 +-
 apps/splitty/pkg.yml                            |   2 +-
 apps/testbench/pkg.yml                          |   2 +-
 apps/timtest/pkg.yml                            |   2 +-
 fs/fatfs/pkg.yml                                |   2 +-
 fs/nffs/pkg.yml                                 |   2 +-
 fs/nffs/test/pkg.yml                            |   2 +
 net/nimble/host/pkg.yml                         |   2 +-
 net/nimble/host/test/pkg.yml                    |   2 +
 net/oic/pkg.yml                                 |   2 +-
 net/oic/test/pkg.yml                            |   3 +-
 sys/config/test-nffs/pkg.yml                    |   2 +
 sys/log/full/include/log/ignore.h               |  64 +++
 sys/log/full/include/log/log.h                  | 233 +++++++++
 sys/log/full/pkg.yml                            |  44 ++
 sys/log/full/src/log.c                          | 236 +++++++++
 sys/log/full/src/log_cbmem.c                    | 129 +++++
 sys/log/full/src/log_console.c                  |  75 +++
 sys/log/full/src/log_fcb.c                      | 285 ++++++++++
 sys/log/full/src/log_nmgr.c                     | 516 +++++++++++++++++++
 sys/log/full/src/log_shell.c                    | 101 ++++
 sys/log/full/syscfg.yml                         |  37 ++
 sys/log/full/test/pkg.yml                       |  30 ++
 sys/log/full/test/src/log_test.c                | 109 ++++
 sys/log/full/test/src/log_test.h                |  54 ++
 .../full/test/src/testcases/log_append_fcb.c    |  33 ++
 sys/log/full/test/src/testcases/log_flush_fcb.c |  31 ++
 sys/log/full/test/src/testcases/log_setup_fcb.c |  39 ++
 sys/log/full/test/src/testcases/log_walk_fcb.c  |  30 ++
 sys/log/full/test/syscfg.yml                    |  22 +
 sys/log/include/log/ignore.h                    |  64 ---
 sys/log/include/log/log.h                       | 233 ---------
 sys/log/pkg.yml                                 |  41 --
 sys/log/src/log.c                               | 236 ---------
 sys/log/src/log_cbmem.c                         | 129 -----
 sys/log/src/log_console.c                       |  75 ---
 sys/log/src/log_fcb.c                           | 285 ----------
 sys/log/src/log_nmgr.c                          | 516 -------------------
 sys/log/src/log_shell.c                         | 101 ----
 sys/log/syscfg.yml                              |  37 --
 sys/log/test/pkg.yml                            |  30 --
 sys/log/test/src/log_test.c                     | 109 ----
 sys/log/test/src/log_test.h                     |  54 --
 sys/log/test/src/testcases/log_append_fcb.c     |  33 --
 sys/log/test/src/testcases/log_flush_fcb.c      |  31 --
 sys/log/test/src/testcases/log_setup_fcb.c      |  39 --
 sys/log/test/src/testcases/log_walk_fcb.c       |  30 --
 sys/log/test/syscfg.yml                         |  22 -
 sys/reboot/pkg.yml                              |   2 +-
 59 files changed, 2098 insertions(+), 2083 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/blecent/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/blecent/pkg.yml b/apps/blecent/pkg.yml
index bfe24c9..48d3887 100644
--- a/apps/blecent/pkg.yml
+++ b/apps/blecent/pkg.yml
@@ -24,7 +24,6 @@ pkg.keywords:
 
 pkg.deps: 
     - kernel/os 
-    - sys/log
     - net/nimble/controller
     - net/nimble/host
     - net/nimble/host/services/gap
@@ -32,4 +31,6 @@ pkg.deps:
     - net/nimble/host/store/ram
     - net/nimble/transport/ram
     - sys/console/full
+    - sys/log/full
+    - sys/stats/full
     - libc/baselibc

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/bleprph/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml
index a5ad1d6..ddc30e2 100644
--- a/apps/bleprph/pkg.yml
+++ b/apps/bleprph/pkg.yml
@@ -25,7 +25,7 @@ pkg.keywords:
 pkg.deps: 
     - boot/split
     - kernel/os 
-    - sys/log
+    - sys/log/full
     - mgmt/newtmgr
     - mgmt/newtmgr/transport/ble
     - net/nimble/controller

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/bletest/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bletest/pkg.yml b/apps/bletest/pkg.yml
index bc4a111..929480d 100644
--- a/apps/bletest/pkg.yml
+++ b/apps/bletest/pkg.yml
@@ -32,6 +32,6 @@ pkg.deps:
     - sys/console/full
     - sys/shell
     - sys/config
-    - sys/log
+    - sys/log/full
     - sys/stats/full
 pkg.cflags: -DBLETEST

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/bletiny/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml
index 7bb5047..0d70a9d 100644
--- a/apps/bletiny/pkg.yml
+++ b/apps/bletiny/pkg.yml
@@ -24,7 +24,6 @@ pkg.keywords:
 
 pkg.deps: 
     - kernel/os 
-    - sys/log
     - net/nimble/controller
     - net/nimble/host
     - net/nimble/host/services/ans
@@ -33,5 +32,6 @@ pkg.deps:
     - net/nimble/host/store/ram
     - net/nimble/transport/ram
     - sys/console/full
+    - sys/log/full
     - sys/stats/full
     - sys/shell

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/bleuart/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/bleuart/pkg.yml b/apps/bleuart/pkg.yml
index 2b026de..c5fbf5a 100644
--- a/apps/bleuart/pkg.yml
+++ b/apps/bleuart/pkg.yml
@@ -24,7 +24,6 @@ pkg.keywords:
 
 pkg.deps:
     - kernel/os
-    - sys/log
     - net/nimble/controller
     - net/nimble/host
     - net/nimble/host/services/gap
@@ -32,6 +31,8 @@ pkg.deps:
     - net/nimble/host/store/ram
     - net/nimble/transport/ram
     - sys/console/full
+    - sys/log/full
+    - sys/stats/full
     - libc/baselibc
     - mgmt/newtmgr
     - mgmt/newtmgr/transport/ble

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/fat2native/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/fat2native/pkg.yml b/apps/fat2native/pkg.yml
index a047373..1ba07f1 100644
--- a/apps/fat2native/pkg.yml
+++ b/apps/fat2native/pkg.yml
@@ -28,4 +28,6 @@ pkg.deps:
     - fs/fatfs
     - hw/hal
     - sys/console/full
+    - sys/log/full
+    - sys/stats/stub
     - kernel/os

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/ffs2native/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/ffs2native/pkg.yml b/apps/ffs2native/pkg.yml
index 94c38fd..aecb7fd 100644
--- a/apps/ffs2native/pkg.yml
+++ b/apps/ffs2native/pkg.yml
@@ -28,5 +28,6 @@ pkg.deps:
     - fs/nffs
     - hw/hal
     - sys/console/full
+    - sys/log/full
     - sys/stats/stub
     - kernel/os

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/ocf_sample/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/ocf_sample/pkg.yml b/apps/ocf_sample/pkg.yml
index 339811b..6acc16b 100644
--- a/apps/ocf_sample/pkg.yml
+++ b/apps/ocf_sample/pkg.yml
@@ -26,10 +26,10 @@ pkg.keywords:
 
 pkg.deps:
     - kernel/os
-    - sys/log
     - net/oic
     - encoding/cborattr
     - sys/console/full
+    - sys/log/full
     - sys/stats/full
 
 pkg.deps.OC_TRANSPORT_SERIAL:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/slinky/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/slinky/pkg.yml b/apps/slinky/pkg.yml
index 41f44c5..3159cb9 100644
--- a/apps/slinky/pkg.yml
+++ b/apps/slinky/pkg.yml
@@ -35,7 +35,7 @@ pkg.deps:
     - sys/config
     - sys/console/full
     - sys/id
-    - sys/log
+    - sys/log/full
     - sys/stats/full
     - boot/split
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/slinky_oic/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/slinky_oic/pkg.yml b/apps/slinky_oic/pkg.yml
index 1c778de..283984a 100644
--- a/apps/slinky_oic/pkg.yml
+++ b/apps/slinky_oic/pkg.yml
@@ -33,7 +33,7 @@ pkg.deps:
     - sys/config
     - sys/console/full
     - sys/id
-    - sys/log
+    - sys/log/full
     - sys/stats/full
     - boot/split
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/spitest/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/spitest/pkg.yml b/apps/spitest/pkg.yml
index dfab7e9..d16497f 100644
--- a/apps/spitest/pkg.yml
+++ b/apps/spitest/pkg.yml
@@ -29,5 +29,5 @@ pkg.deps:
     - kernel/os
     - sys/shell
     - sys/config
-    - sys/log
+    - sys/log/full
     - sys/stats/full

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/splitty/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/splitty/pkg.yml b/apps/splitty/pkg.yml
index 15ec2dd..6f2ca6f 100644
--- a/apps/splitty/pkg.yml
+++ b/apps/splitty/pkg.yml
@@ -35,6 +35,6 @@ pkg.deps:
     - sys/config
     - sys/console/full
     - sys/id
-    - sys/log
+    - sys/log/full
     - sys/shell
     - sys/stats/full

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/testbench/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/testbench/pkg.yml b/apps/testbench/pkg.yml
index 720700d..92d4cff 100644
--- a/apps/testbench/pkg.yml
+++ b/apps/testbench/pkg.yml
@@ -35,7 +35,7 @@ pkg.deps:
 #    - sys/shell
     - sys/config
     - sys/id
-    - sys/log
+    - sys/log/full
     - sys/stats/full
     - sys/flash_map
     - sys/flash_map/test

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/apps/timtest/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/timtest/pkg.yml b/apps/timtest/pkg.yml
index be42735..330a142 100644
--- a/apps/timtest/pkg.yml
+++ b/apps/timtest/pkg.yml
@@ -29,5 +29,5 @@ pkg.deps:
     - kernel/os
     - sys/shell
     - sys/config
-    - sys/log
+    - sys/log/full
     - sys/stats/full

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/fs/fatfs/pkg.yml
----------------------------------------------------------------------
diff --git a/fs/fatfs/pkg.yml b/fs/fatfs/pkg.yml
index 61ac6f8..64fa8f3 100644
--- a/fs/fatfs/pkg.yml
+++ b/fs/fatfs/pkg.yml
@@ -32,8 +32,8 @@ pkg.deps:
     - kernel/os
     - test/testutil
     - sys/flash_map
-    - sys/log
 pkg.req_apis:
+    - log
     - stats
 
 pkg.init_function: fatfs_pkg_init

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/fs/nffs/pkg.yml
----------------------------------------------------------------------
diff --git a/fs/nffs/pkg.yml b/fs/nffs/pkg.yml
index 1be62cf..7ce2c2c 100644
--- a/fs/nffs/pkg.yml
+++ b/fs/nffs/pkg.yml
@@ -33,8 +33,8 @@ pkg.deps:
     - kernel/os
     - test/testutil
     - sys/flash_map
-    - sys/log
 pkg.req_apis:
+    - log
     - stats
 
 pkg.init_function: nffs_pkg_init

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/fs/nffs/test/pkg.yml
----------------------------------------------------------------------
diff --git a/fs/nffs/test/pkg.yml b/fs/nffs/test/pkg.yml
index 750247b..c7e9d99 100644
--- a/fs/nffs/test/pkg.yml
+++ b/fs/nffs/test/pkg.yml
@@ -28,3 +28,5 @@ pkg.deps:
 
 pkg.deps.SELFTEST:
     - sys/console/stub
+    - sys/log/full
+    - sys/stats/stub

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/net/nimble/host/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/pkg.yml b/net/nimble/host/pkg.yml
index 1ae103f..f7539a4 100644
--- a/net/nimble/host/pkg.yml
+++ b/net/nimble/host/pkg.yml
@@ -28,7 +28,6 @@ pkg.keywords:
 pkg.deps:
     - kernel/os
     - net/nimble
-    - sys/log
     - util/mem
 
 pkg.deps.BLE_SM_LEGACY:
@@ -40,6 +39,7 @@ pkg.deps.BLE_SM_SC:
 pkg.req_apis:
     - ble_transport
     - console
+    - log
     - stats
 
 pkg.init_function: "ble_hs_init"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/net/nimble/host/test/pkg.yml
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/pkg.yml b/net/nimble/host/test/pkg.yml
index c8553ef..cd77a34 100644
--- a/net/nimble/host/test/pkg.yml
+++ b/net/nimble/host/test/pkg.yml
@@ -29,4 +29,6 @@ pkg.deps:
 
 pkg.deps.SELFTEST:
     - sys/console/stub
+    - sys/log/full
+    - sys/stats/stub
     - net/nimble/transport/ram

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/net/oic/pkg.yml
----------------------------------------------------------------------
diff --git a/net/oic/pkg.yml b/net/oic/pkg.yml
index a5c9bae..43a8376 100644
--- a/net/oic/pkg.yml
+++ b/net/oic/pkg.yml
@@ -27,8 +27,8 @@ pkg.deps:
     - "encoding/cborattr"
     - "encoding/tinycbor"
     - "kernel/os"
-    - "sys/log"
 pkg.req_apis:
+    - log
     - stats
 
 pkg.deps.OC_TRANSPORT_GATT:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/net/oic/test/pkg.yml
----------------------------------------------------------------------
diff --git a/net/oic/test/pkg.yml b/net/oic/test/pkg.yml
index 9790b31..3036343 100644
--- a/net/oic/test/pkg.yml
+++ b/net/oic/test/pkg.yml
@@ -27,7 +27,8 @@ pkg.deps:
     - encoding/tinycbor
     - encoding/cborattr
     - test/testutil
-    - sys/stats/full
 
 pkg.deps.SELFTEST:
     - sys/console/stub
+    - sys/log/full
+    - sys/stats/full

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/config/test-nffs/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/config/test-nffs/pkg.yml b/sys/config/test-nffs/pkg.yml
index 87f6161..4b48b69 100644
--- a/sys/config/test-nffs/pkg.yml
+++ b/sys/config/test-nffs/pkg.yml
@@ -29,3 +29,5 @@ pkg.deps:
 pkg.deps.SELFTEST:
     - fs/nffs
     - sys/console/stub
+    - sys/log/full
+    - sys/stats/stub

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/include/log/ignore.h
----------------------------------------------------------------------
diff --git a/sys/log/full/include/log/ignore.h 
b/sys/log/full/include/log/ignore.h
new file mode 100644
index 0000000..46282a0
--- /dev/null
+++ b/sys/log/full/include/log/ignore.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_IGNORE_
+#define H_IGNORE_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * These macros prevent the "set but not used" warnings for log writes below
+ * the log level.
+ */
+
+#define IGN_1(X) ((void)(X))
+#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__)
+#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__)
+#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__)
+#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__)
+#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__)
+#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__)
+#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__)
+#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__)
+#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__)
+#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__)
+#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__)
+#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__)
+#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__)
+#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__)
+#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__)
+#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__)
+#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__)
+#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__)
+#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__)
+
+#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
+                  _13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME
+#define IGNORE(...) \
+    GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \
+              IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \
+              IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/include/log/log.h
----------------------------------------------------------------------
diff --git a/sys/log/full/include/log/log.h b/sys/log/full/include/log/log.h
new file mode 100644
index 0000000..271312f
--- /dev/null
+++ b/sys/log/full/include/log/log.h
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef __SYS_LOG_FULL_H__
+#define __SYS_LOG_FULL_H__
+
+#include "syscfg/syscfg.h"
+#include "log/ignore.h"
+#include "cbmem/cbmem.h"
+
+#include <os/queue.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Global log info */
+struct log_info {
+    int64_t li_timestamp;
+    uint8_t li_index;
+    uint8_t li_version;
+};
+#define LOG_VERSION_V2  2
+#define LOG_VERSION_V1  1
+
+extern struct log_info g_log_info;
+
+struct log;
+
+typedef int (*log_walk_func_t)(struct log *, void *arg, void *offset,
+        uint16_t len);
+
+typedef int (*lh_read_func_t)(struct log *, void *dptr, void *buf,
+        uint16_t offset, uint16_t len);
+typedef int (*lh_append_func_t)(struct log *, void *buf, int len);
+typedef int (*lh_walk_func_t)(struct log *,
+        log_walk_func_t walk_func, void *arg);
+typedef int (*lh_flush_func_t)(struct log *);
+/*
+ * This function pointer points to a function that restores the numebr
+ * of entries that are specified while erasing
+ */
+typedef int (*lh_rtr_erase_func_t)(struct log *, void *arg);
+
+#define LOG_TYPE_STREAM  (0)
+#define LOG_TYPE_MEMORY  (1)
+#define LOG_TYPE_STORAGE (2)
+
+struct log_handler {
+    int log_type;
+    lh_read_func_t log_read;
+    lh_append_func_t log_append;
+    lh_walk_func_t log_walk;
+    lh_flush_func_t log_flush;
+    lh_rtr_erase_func_t log_rtr_erase;
+};
+
+struct log_entry_hdr {
+    int64_t ue_ts;
+    uint16_t ue_index;
+    uint8_t ue_module;
+    uint8_t ue_level;
+}__attribute__((__packed__));
+#define LOG_ENTRY_HDR_SIZE (sizeof(struct log_entry_hdr))
+
+/*
+ * Encode request - packages log entry request and response
+ */
+struct encode_off {
+    void *eo_encoder; /* typecast CborEncoder */
+    int64_t eo_ts;
+    uint8_t eo_index;
+    uint32_t rsp_len;
+};
+
+#define LOG_LEVEL_DEBUG    (0)
+#define LOG_LEVEL_INFO     (1)
+#define LOG_LEVEL_WARN     (2)
+#define LOG_LEVEL_ERROR    (3)
+#define LOG_LEVEL_CRITICAL (4)
+/* Up to 7 custom log levels. */
+#define LOG_LEVEL_MAX      (UINT8_MAX)
+
+#define LOG_LEVEL_STR(level) \
+    (LOG_LEVEL_DEBUG    == level ? "DEBUG"    :\
+    (LOG_LEVEL_INFO     == level ? "INFO"     :\
+    (LOG_LEVEL_WARN     == level ? "WARN"     :\
+    (LOG_LEVEL_ERROR    == level ? "ERROR"    :\
+    (LOG_LEVEL_CRITICAL == level ? "CRITICAL" :\
+     "UNKNOWN")))))
+
+/* Log module, eventually this can be a part of the filter. */
+#define LOG_MODULE_DEFAULT          (0)
+#define LOG_MODULE_OS               (1)
+#define LOG_MODULE_NEWTMGR          (2)
+#define LOG_MODULE_NIMBLE_CTLR      (3)
+#define LOG_MODULE_NIMBLE_HOST      (4)
+#define LOG_MODULE_NFFS             (5)
+#define LOG_MODULE_REBOOT           (6)
+#define LOG_MODULE_IOTIVITY         (7)
+#define LOG_MODULE_TEST             (8)
+#define LOG_MODULE_PERUSER          (64)
+#define LOG_MODULE_MAX              (255)
+
+#define LOG_MODULE_STR(module) \
+    (LOG_MODULE_DEFAULT     == module ? "DEFAULT"     :\
+    (LOG_MODULE_OS          == module ? "OS"          :\
+    (LOG_MODULE_NEWTMGR     == module ? "NEWTMGR"     :\
+    (LOG_MODULE_NIMBLE_CTLR == module ? "NIMBLE_CTLR" :\
+    (LOG_MODULE_NIMBLE_HOST == module ? "NIMBLE_HOST" :\
+    (LOG_MODULE_NFFS        == module ? "NFFS"        :\
+    (LOG_MODULE_REBOOT      == module ? "REBOOT"      :\
+    (LOG_MODULE_IOTIVITY    == module ? "IOTIVITY"    :\
+    (LOG_MODULE_TEST        == module ? "TEST"        :\
+     "UNKNOWN")))))))))
+
+/*
+ * Logging Implementations
+ */
+#define LOG_STORE_CONSOLE    1
+#define LOG_STORE_CBMEM      2
+#define LOG_STORE_FCB        3
+
+/* UTC Timestamnp for Jan 2016 00:00:00 */
+#define UTC01_01_2016    1451606400
+
+#define LOG_NAME_MAX_LEN    (64)
+
+#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG
+#define LOG_DEBUG(__l, __mod, __msg, ...) log_printf(__l, __mod, \
+        LOG_LEVEL_DEBUG, __msg, ##__VA_ARGS__)
+#else
+#define LOG_DEBUG(__l, __mod, ...) IGNORE(__VA_ARGS__)
+#endif
+
+#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_INFO
+#define LOG_INFO(__l, __mod, __msg, ...) log_printf(__l, __mod, \
+        LOG_LEVEL_INFO, __msg, ##__VA_ARGS__)
+#else
+#define LOG_INFO(__l, __mod, ...) IGNORE(__VA_ARGS__)
+#endif
+
+#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_WARN
+#define LOG_WARN(__l, __mod, __msg, ...) log_printf(__l, __mod, \
+        LOG_LEVEL_WARN, __msg, ##__VA_ARGS__)
+#else
+#define LOG_WARN(__l, __mod, ...) IGNORE(__VA_ARGS__)
+#endif
+
+#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_ERROR
+#define LOG_ERROR(__l, __mod, __msg, ...) log_printf(__l, __mod, \
+        LOG_LEVEL_ERROR, __msg, ##__VA_ARGS__)
+#else
+#define LOG_ERROR(__l, __mod, ...) IGNORE(__VA_ARGS__)
+#endif
+
+#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_CRITICAL
+#define LOG_CRITICAL(__l, __mod, __msg, ...) log_printf(__l, __mod, \
+        LOG_LEVEL_CRITICAL, __msg, ##__VA_ARGS__)
+#else
+#define LOG_CRITICAL(__l, __mod, ...) IGNORE(__VA_ARGS__)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_LEVEL
+#define LOG_SYSLEVEL    ((uint8_t)0xff)
+#else
+#define LOG_SYSLEVEL    ((uint8_t)MYNEWT_VAL_LOG_LEVEL)
+#endif
+
+struct log {
+    char *l_name;
+    struct log_handler *l_log;
+    void *l_arg;
+    STAILQ_ENTRY(log) l_next;
+    uint8_t l_level;
+};
+
+/* Newtmgr Log opcodes */
+#define LOGS_NMGR_OP_READ         (0)
+#define LOGS_NMGR_OP_CLEAR        (1)
+#define LOGS_NMGR_OP_APPEND       (2)
+#define LOGS_NMGR_OP_MODULE_LIST  (3)
+#define LOGS_NMGR_OP_LEVEL_LIST   (4)
+#define LOGS_NMGR_OP_LOGS_LIST    (5)
+
+/* Log system level functions (for all logs.) */
+void log_init(void);
+struct log *log_list_get_next(struct log *);
+
+/* Log functions, manipulate a single log */
+int log_register(char *name, struct log *log, const struct log_handler *,
+                 void *arg, uint8_t level);
+int log_append(struct log *, uint16_t, uint16_t, void *, uint16_t);
+
+#define LOG_PRINTF_MAX_ENTRY_LEN (128)
+void log_printf(struct log *log, uint16_t, uint16_t, char *, ...);
+int log_read(struct log *log, void *dptr, void *buf, uint16_t off,
+        uint16_t len);
+int log_walk(struct log *log, log_walk_func_t walk_func,
+        void *arg);
+int log_flush(struct log *log);
+int log_rtr_erase(struct log *log, void *arg);
+
+/* Handler exports */
+extern const struct log_handler log_console_handler;
+extern const struct log_handler log_cbmem_handler;
+extern const struct log_handler log_fcb_handler;
+
+/* Private */
+#if MYNEWT_VAL(LOG_NEWTMGR)
+int log_nmgr_register_group(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYS_LOG_FULL_H__ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/log/full/pkg.yml b/sys/log/full/pkg.yml
new file mode 100644
index 0000000..b905076
--- /dev/null
+++ b/sys/log/full/pkg.yml
@@ -0,0 +1,44 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: sys/log/full
+pkg.description: Logging utilities for embedded systems.
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+    - logging
+
+pkg.deps:
+    - kernel/os
+    - sys/flash_map
+    - util/cbmem
+pkg.deps.LOG_FCB:
+    - hw/hal
+    - fs/fcb
+pkg.deps.LOG_CLI:
+    - sys/shell
+
+pkg.deps.LOG_NEWTMGR:
+    - mgmt/mgmt
+
+pkg.apis:
+    - log
+
+pkg.init_function: log_init
+pkg.init_stage: 1

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log.c b/sys/log/full/src/log.c
new file mode 100644
index 0000000..89f2741
--- /dev/null
+++ b/sys/log/full/src/log.c
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "os/os.h"
+#include "cbmem/cbmem.h"
+#include "log/log.h"
+
+#if MYNEWT_VAL(LOG_CLI)
+#include "shell/shell.h"
+#endif
+
+struct log_info g_log_info;
+
+static STAILQ_HEAD(, log) g_log_list = STAILQ_HEAD_INITIALIZER(g_log_list);
+static uint8_t log_inited;
+
+#if MYNEWT_VAL(LOG_CLI)
+int shell_log_dump_all_cmd(int, char **);
+struct shell_cmd g_shell_log_cmd = {
+    .sc_cmd = "log",
+    .sc_cmd_func = shell_log_dump_all_cmd
+};
+#endif
+
+void
+log_init(void)
+{
+    int rc;
+
+    /* Ensure this function only gets called by sysinit. */
+    SYSINIT_ASSERT_ACTIVE();
+
+    (void)rc;
+
+    if (log_inited) {
+        return;
+    }
+    log_inited = 1;
+
+    g_log_info.li_version = LOG_VERSION_V2;
+    g_log_info.li_index = 0;
+    g_log_info.li_timestamp = 0;
+
+#if MYNEWT_VAL(LOG_CLI)
+    shell_cmd_register(&g_shell_log_cmd);
+#endif
+
+#if MYNEWT_VAL(LOG_NEWTMGR)
+    rc = log_nmgr_register_group();
+    SYSINIT_PANIC_ASSERT(rc == 0);
+#endif
+}
+
+struct log *
+log_list_get_next(struct log *log)
+{
+    struct log *next;
+
+    if (log == NULL) {
+        next = STAILQ_FIRST(&g_log_list);
+    } else {
+        next = STAILQ_NEXT(log, l_next);
+    }
+
+    return (next);
+}
+
+/**
+ * Indicates whether the specified log has been regiestered.
+ */
+static int
+log_registered(struct log *log)
+{
+    struct log *cur;
+
+    STAILQ_FOREACH(cur, &g_log_list, l_next) {
+        if (cur == log) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Associate an instantiation of a log with the logging infrastructure
+ */
+int
+log_register(char *name, struct log *log, const struct log_handler *lh,
+             void *arg, uint8_t level)
+{
+    log->l_name = name;
+    log->l_log = (struct log_handler *)lh;
+    log->l_arg = arg;
+    log->l_level = level;
+
+    /*assert(!log_registered(log));*/
+    if (!log_registered(log)) {
+        STAILQ_INSERT_TAIL(&g_log_list, log, l_next);
+    }
+
+    return (0);
+}
+
+int
+log_append(struct log *log, uint16_t module, uint16_t level, void *data,
+        uint16_t len)
+{
+    struct log_entry_hdr *ue;
+    int rc;
+    struct os_timeval tv;
+
+    if (log->l_name == NULL || log->l_log == NULL) {
+        rc = -1;
+        goto err;
+    }
+
+    /*
+     * If the log message is below what this log instance is
+     * configured to accept, then just drop it.
+     */
+    if (level < log->l_level) {
+        rc = -1;
+        goto err;
+    }
+
+    ue = (struct log_entry_hdr *) data;
+
+    /* Could check for li_index wraparound here */
+    g_log_info.li_index++;
+
+    /* Try to get UTC Time */
+    rc = os_gettimeofday(&tv, NULL);
+    if (rc || tv.tv_sec < UTC01_01_2016) {
+        ue->ue_ts = os_get_uptime_usec();
+    } else {
+        ue->ue_ts = tv.tv_sec * 1000000 + tv.tv_usec;
+    }
+
+    g_log_info.li_timestamp = ue->ue_ts;
+    ue->ue_level = level;
+    ue->ue_module = module;
+    ue->ue_index = g_log_info.li_index;
+
+    rc = log->l_log->log_append(log, data, len + LOG_ENTRY_HDR_SIZE);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+void
+log_printf(struct log *log, uint16_t module, uint16_t level, char *msg, ...)
+{
+    va_list args;
+    char buf[LOG_ENTRY_HDR_SIZE + LOG_PRINTF_MAX_ENTRY_LEN];
+    int len;
+
+    va_start(args, msg);
+    len = vsnprintf(&buf[LOG_ENTRY_HDR_SIZE], LOG_PRINTF_MAX_ENTRY_LEN, msg,
+            args);
+    if (len >= LOG_PRINTF_MAX_ENTRY_LEN) {
+        len = LOG_PRINTF_MAX_ENTRY_LEN-1;
+    }
+
+    log_append(log, module, level, (uint8_t *) buf, len);
+}
+
+int
+log_walk(struct log *log, log_walk_func_t walk_func, void *arg)
+{
+    int rc;
+
+    rc = log->l_log->log_walk(log, walk_func, arg);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+log_read(struct log *log, void *dptr, void *buf, uint16_t off,
+        uint16_t len)
+{
+    int rc;
+
+    rc = log->l_log->log_read(log, dptr, buf, off, len);
+
+    return (rc);
+}
+
+int
+log_flush(struct log *log)
+{
+    int rc;
+
+    rc = log->l_log->log_flush(log);
+    if (rc != 0) {
+        goto err;
+    }
+
+    g_log_info.li_index = 0;
+
+    return (0);
+err:
+    return (rc);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log_cbmem.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_cbmem.c b/sys/log/full/src/log_cbmem.c
new file mode 100644
index 0000000..e512895
--- /dev/null
+++ b/sys/log/full/src/log_cbmem.c
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <os/os.h>
+#include <cbmem/cbmem.h>
+#include "log/log.h"
+
+static int
+log_cbmem_append(struct log *log, void *buf, int len)
+{
+    struct cbmem *cbmem;
+    int rc;
+
+    cbmem = (struct cbmem *) log->l_arg;
+
+    rc = cbmem_append(cbmem, buf, len);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+static int
+log_cbmem_read(struct log *log, void *dptr, void *buf, uint16_t offset,
+        uint16_t len)
+{
+    struct cbmem *cbmem;
+    struct cbmem_entry_hdr *hdr;
+    int rc;
+
+    cbmem = (struct cbmem *) log->l_arg;
+    hdr = (struct cbmem_entry_hdr *) dptr;
+
+    rc = cbmem_read(cbmem, hdr, buf, offset, len);
+
+    return (rc);
+}
+
+static int
+log_cbmem_walk(struct log *log, log_walk_func_t walk_func, void *arg)
+{
+    struct cbmem *cbmem;
+    struct cbmem_entry_hdr *hdr;
+    struct cbmem_iter iter;
+    struct encode_off *encode_off = (struct encode_off *)arg;
+    int rc;
+
+    cbmem = (struct cbmem *) log->l_arg;
+
+    rc = cbmem_lock_acquire(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    /*
+     * if timestamp for request is < 1, return last log entry
+     */
+    if (encode_off->eo_ts < 0) {
+        hdr = cbmem->c_entry_end;
+        rc = walk_func(log, arg, (void *)hdr, hdr->ceh_len);
+    } else {
+        cbmem_iter_start(cbmem, &iter);
+        while (1) {
+            hdr = cbmem_iter_next(cbmem, &iter);
+            if (!hdr) {
+                break;
+            }
+
+            rc = walk_func(log, arg, (void *)hdr, hdr->ceh_len);
+            if (rc == 1) {
+                break;
+            }
+        }
+    }
+
+    rc = cbmem_lock_release(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+static int
+log_cbmem_flush(struct log *log)
+{
+    struct cbmem *cbmem;
+    int rc;
+
+    cbmem = (struct cbmem *) log->l_arg;
+
+    rc = cbmem_flush(cbmem);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+const struct log_handler log_cbmem_handler = {
+    .log_type = LOG_TYPE_MEMORY,
+    .log_read = log_cbmem_read,
+    .log_append = log_cbmem_append,
+    .log_walk = log_cbmem_walk,
+    .log_flush = log_cbmem_flush,
+    .log_rtr_erase = NULL,
+};

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log_console.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_console.c b/sys/log/full/src/log_console.c
new file mode 100644
index 0000000..e9e5556
--- /dev/null
+++ b/sys/log/full/src/log_console.c
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <os/os.h>
+#include <cbmem/cbmem.h>
+#include <console/console.h>
+#include "log/log.h"
+
+static int
+log_console_append(struct log *log, void *buf, int len)
+{
+    struct log_entry_hdr *hdr;
+
+    if (!console_is_init()) {
+        return (0);
+    }
+
+    if (!console_is_midline) {
+        hdr = (struct log_entry_hdr *) buf;
+        console_printf("[ts=%lussb, mod=%u level=%u] ",
+                (unsigned long) hdr->ue_ts, hdr->ue_module,
+                hdr->ue_level);
+    }
+
+    console_write((char *) buf + LOG_ENTRY_HDR_SIZE, len - LOG_ENTRY_HDR_SIZE);
+
+    return (0);
+}
+
+static int
+log_console_read(struct log *log, void *dptr, void *buf, uint16_t offset,
+        uint16_t len)
+{
+    /* You don't read console, console read you */
+    return (OS_EINVAL);
+}
+
+static int
+log_console_walk(struct log *log, log_walk_func_t walk_func, void *arg)
+{
+    /* You don't walk console, console walk you. */
+    return (OS_EINVAL);
+}
+
+static int
+log_console_flush(struct log *log)
+{
+    /* You don't flush console, console flush you. */
+    return (OS_EINVAL);
+}
+
+const struct log_handler log_console_handler = {
+    .log_type = LOG_TYPE_STREAM,
+    .log_read = log_console_read,
+    .log_append = log_console_append,
+    .log_walk = log_console_walk,
+    .log_flush = log_console_flush,
+    .log_rtr_erase = NULL,
+};

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_fcb.c b/sys/log/full/src/log_fcb.c
new file mode 100644
index 0000000..1db2d92
--- /dev/null
+++ b/sys/log/full/src/log_fcb.c
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "syscfg/syscfg.h"
+#include "sysflash/sysflash.h"
+
+#if MYNEWT_VAL(LOG_FCB)
+
+#include <string.h>
+
+#include "os/os.h"
+
+#include "flash_map/flash_map.h"
+#include "fcb/fcb.h"
+#include "log/log.h"
+
+static struct flash_area sector;
+
+static int
+log_fcb_append(struct log *log, void *buf, int len)
+{
+    struct fcb *fcb;
+    struct fcb_entry loc;
+    struct fcb_log *fcb_log;
+    int rc;
+
+    fcb_log = (struct fcb_log *)log->l_arg;
+    fcb = &fcb_log->fl_fcb;
+
+    while (1) {
+        rc = fcb_append(fcb, len, &loc);
+        if (rc == 0) {
+            break;
+        }
+
+        if (rc != FCB_ERR_NOSPACE) {
+            goto err;
+        }
+
+        if (log->l_log->log_rtr_erase && fcb_log->fl_entries) {
+            rc = log->l_log->log_rtr_erase(log, fcb_log);
+            if (rc) {
+                goto err;
+            }
+            continue;
+        }
+
+        rc = fcb_rotate(fcb);
+        if (rc) {
+            goto err;
+        }
+    }
+
+    rc = flash_area_write(loc.fe_area, loc.fe_data_off, buf, len);
+    if (rc) {
+        goto err;
+    }
+
+    rc = fcb_append_finish(fcb, &loc);
+
+err:
+    return (rc);
+}
+
+static int
+log_fcb_read(struct log *log, void *dptr, void *buf, uint16_t offset,
+  uint16_t len)
+{
+    struct fcb_entry *loc;
+    int rc;
+
+    loc = (struct fcb_entry *)dptr;
+
+    if (offset + len > loc->fe_data_len) {
+        len = loc->fe_data_len - offset;
+    }
+    rc = flash_area_read(loc->fe_area, loc->fe_data_off + offset, buf, len);
+    if (rc == 0) {
+        return len;
+    } else {
+        return 0;
+    }
+}
+
+static int
+log_fcb_walk(struct log *log, log_walk_func_t walk_func, void *arg)
+{
+    struct fcb *fcb;
+    struct fcb_entry loc;
+    struct fcb_entry *locp;
+    struct encode_off *encode_off = (struct encode_off *)arg;
+    int rc;
+
+    rc = 0;
+    fcb = &((struct fcb_log *)log->l_arg)->fl_fcb;
+
+    memset(&loc, 0, sizeof(loc));
+
+    /*
+     * if timestamp for request is < 1, return last log entry
+     */
+    if (encode_off->eo_ts < 0) {
+        locp = &fcb->f_active;
+        rc = walk_func(log, arg, (void *)locp, locp->fe_data_len);
+    } else {
+        while (fcb_getnext(fcb, &loc) == 0) {
+            rc = walk_func(log, arg, (void *) &loc, loc.fe_data_len);
+            if (rc) {
+                break;
+            }
+        }
+    }
+    return (rc);
+}
+
+static int
+log_fcb_flush(struct log *log)
+{
+    return fcb_clear(&((struct fcb_log *)log->l_arg)->fl_fcb);
+}
+
+/**
+ * Copies one log entry from source fcb to destination fcb
+ * @param src_fcb, dst_fcb
+ * @return 0 on success; non-zero on error
+ */
+static int
+log_fcb_copy_entry(struct log *log, struct fcb_entry *entry,
+                   struct fcb *dst_fcb)
+{
+    struct log_entry_hdr ueh;
+    char data[LOG_PRINTF_MAX_ENTRY_LEN + sizeof(ueh)];
+    int dlen;
+    int rc;
+    struct fcb *fcb_tmp;
+
+    rc = log_fcb_read(log, entry, &ueh, 0, sizeof(ueh));
+    if (rc != sizeof(ueh)) {
+        goto err;
+    }
+
+    dlen = min(entry->fe_data_len, LOG_PRINTF_MAX_ENTRY_LEN + sizeof(ueh));
+
+    rc = log_fcb_read(log, entry, data, 0, dlen);
+    if (rc < 0) {
+        goto err;
+    }
+    data[rc] = '\0';
+
+    /* Changing the fcb to be logged to be dst fcb */
+    fcb_tmp = &((struct fcb_log *)log->l_arg)->fl_fcb;
+
+    log->l_arg = dst_fcb;
+    rc = log_fcb_append(log, data, dlen);
+    log->l_arg = fcb_tmp;
+    if (rc) {
+        goto err;
+    }
+
+err:
+    return (rc);
+}
+
+/**
+ * Copies log entries from source fcb to destination fcb
+ * @param src_fcb, dst_fcb, element offset to start copying
+ * @return 0 on success; non-zero on error
+ */
+static int
+log_fcb_copy(struct log *log, struct fcb *src_fcb, struct fcb *dst_fcb,
+             uint32_t offset)
+{
+    struct fcb_entry entry;
+    int rc;
+
+    rc = 0;
+
+    memset(&entry, 0, sizeof(entry));
+    while (!fcb_getnext(src_fcb, &entry)) {
+        if (entry.fe_elem_off < offset) {
+            continue;
+        }
+        rc = log_fcb_copy_entry(log, &entry, dst_fcb);
+        if (rc) {
+            break;
+        }
+    }
+
+    return (rc);
+}
+
+/**
+ * Flushes the log while restoring specified number of entries
+ * using image scratch
+ * @param src_fcb, dst_fcb
+ * @return 0 on success; non-zero on error
+ */
+static int
+log_fcb_rtr_erase(struct log *log, void *arg)
+{
+    struct fcb_log *fcb_log;
+    struct fcb fcb_scratch;
+    struct fcb *fcb;
+    const struct flash_area *ptr;
+    uint32_t offset;
+    int rc;
+
+    rc = 0;
+    offset = 0;
+    if (!log) {
+        rc = -1;
+        goto err;
+    }
+
+    fcb_log = (struct fcb_log *)arg;
+    fcb = (struct fcb *)fcb_log;
+
+    memset(&fcb_scratch, 0, sizeof(fcb_scratch));
+
+    if (flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &ptr)) {
+        goto err;
+    }
+    sector = *ptr;
+    fcb_scratch.f_sectors = &sector;
+    fcb_scratch.f_sector_cnt = 1;
+    fcb_scratch.f_magic = 0x7EADBADF;
+    fcb_scratch.f_version = g_log_info.li_version;
+
+    flash_area_erase(&sector, 0, sector.fa_size);
+    rc = fcb_init(&fcb_scratch);
+    if (rc) {
+        goto err;
+    }
+
+    /* Calculate offset of n-th last entry */
+    rc = fcb_offset_last_n(fcb, fcb_log->fl_entries, &offset);
+    if (rc) {
+        goto err;
+    }
+
+    /* Copy to scratch */
+    rc = log_fcb_copy(log, fcb, &fcb_scratch, offset);
+    if (rc) {
+        goto err;
+    }
+
+    /* Flush log */
+    rc = log_fcb_flush(log);
+    if (rc) {
+        goto err;
+    }
+
+    /* Copy back from scratch */
+    rc = log_fcb_copy(log, &fcb_scratch, fcb, 0);
+
+err:
+    return (rc);
+}
+
+const struct log_handler log_fcb_handler = {
+    .log_type = LOG_TYPE_STORAGE,
+    .log_read = log_fcb_read,
+    .log_append = log_fcb_append,
+    .log_walk = log_fcb_walk,
+    .log_flush = log_fcb_flush,
+    .log_rtr_erase = log_fcb_rtr_erase,
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log_nmgr.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_nmgr.c b/sys/log/full/src/log_nmgr.c
new file mode 100644
index 0000000..cc55fae
--- /dev/null
+++ b/sys/log/full/src/log_nmgr.c
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <os/os.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "syscfg/syscfg.h"
+
+#if MYNEWT_VAL(LOG_NEWTMGR)
+
+#include "mgmt/mgmt.h"
+#include "cborattr/cborattr.h"
+#include "tinycbor/cbor_cnt_writer.h"
+#include "log/log.h"
+
+/* Source code is only included if the newtmgr library is enabled.  Otherwise
+ * this file is compiled out for code size.
+ */
+
+static int log_nmgr_read(struct mgmt_cbuf *njb);
+static int log_nmgr_clear(struct mgmt_cbuf *njb);
+static int log_nmgr_module_list(struct mgmt_cbuf *njb);
+static int log_nmgr_level_list(struct mgmt_cbuf *njb);
+static int log_nmgr_logs_list(struct mgmt_cbuf *njb);
+static struct mgmt_group log_nmgr_group;
+
+
+/* ORDER MATTERS HERE.
+ * Each element represents the command ID, referenced from newtmgr.
+ */
+static struct mgmt_handler log_nmgr_group_handlers[] = {
+    [LOGS_NMGR_OP_READ] = {log_nmgr_read, log_nmgr_read},
+    [LOGS_NMGR_OP_CLEAR] = {log_nmgr_clear, log_nmgr_clear},
+    [LOGS_NMGR_OP_MODULE_LIST] = {log_nmgr_module_list, NULL},
+    [LOGS_NMGR_OP_LEVEL_LIST] = {log_nmgr_level_list, NULL},
+    [LOGS_NMGR_OP_LOGS_LIST] = {log_nmgr_logs_list, NULL}
+};
+
+/**
+ * Log encode entry
+ * @param log structure, arg:struct passed locally, dataptr, len
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_encode_entry(struct log *log, void *arg, void *dptr, uint16_t len)
+{
+    struct encode_off *encode_off = (struct encode_off *)arg;
+    struct log_entry_hdr ueh;
+    char data[128];
+    int dlen;
+    int rc;
+    int rsp_len;
+    CborError g_err = CborNoError;
+    CborEncoder *penc = (CborEncoder*)encode_off->eo_encoder;
+    CborEncoder rsp;
+    struct CborCntWriter cnt_writer;
+    CborEncoder cnt_encoder;
+
+    rc = log_read(log, dptr, &ueh, 0, sizeof(ueh));
+    if (rc != sizeof(ueh)) {
+        rc = OS_ENOENT;
+        goto err;
+    }
+    rc = OS_OK;
+
+    /* Matching timestamps and indices for sending a log entry */
+    if (ueh.ue_ts < encode_off->eo_ts   ||
+        (ueh.ue_ts == encode_off->eo_ts &&
+         ueh.ue_index <= encode_off->eo_index)) {
+        goto err;
+    }
+
+    dlen = min(len-sizeof(ueh), 128);
+
+    rc = log_read(log, dptr, data, sizeof(ueh), dlen);
+    if (rc < 0) {
+        rc = OS_ENOENT;
+        goto err;
+    }
+    data[rc] = 0;
+
+    /*calculate whether this would fit */
+    /* create a counting encoder for cbor */
+    cbor_cnt_writer_init(&cnt_writer);
+    cbor_encoder_init(&cnt_encoder, &cnt_writer.enc, 0);
+
+    /* NOTE This code should exactly match what is below */
+    g_err |= cbor_encoder_create_map(&cnt_encoder, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "msg");
+    g_err |= cbor_encode_text_stringz(&rsp, data);
+    g_err |= cbor_encode_text_stringz(&rsp, "ts");
+    g_err |= cbor_encode_int(&rsp, ueh.ue_ts);
+    g_err |= cbor_encode_text_stringz(&rsp, "level");
+    g_err |= cbor_encode_uint(&rsp, ueh.ue_level);
+    g_err |= cbor_encode_text_stringz(&rsp, "index");
+    g_err |= cbor_encode_uint(&rsp,  ueh.ue_index);
+    g_err |= cbor_encode_text_stringz(&rsp, "module");
+    g_err |= cbor_encode_uint(&rsp,  ueh.ue_module);
+    g_err |= cbor_encoder_close_container(&cnt_encoder, &rsp);
+    rsp_len = encode_off->rsp_len;
+    rsp_len += cbor_encode_bytes_written(&cnt_encoder);
+    if (rsp_len > 400) {
+        rc = OS_ENOMEM;
+        goto err;
+    }
+    encode_off->rsp_len = rsp_len;
+
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "msg");
+    g_err |= cbor_encode_text_stringz(&rsp, data);
+    g_err |= cbor_encode_text_stringz(&rsp, "ts");
+    g_err |= cbor_encode_int(&rsp, ueh.ue_ts);
+    g_err |= cbor_encode_text_stringz(&rsp, "level");
+    g_err |= cbor_encode_uint(&rsp, ueh.ue_level);
+    g_err |= cbor_encode_text_stringz(&rsp, "index");
+    g_err |= cbor_encode_uint(&rsp,  ueh.ue_index);
+    g_err |= cbor_encode_text_stringz(&rsp, "module");
+    g_err |= cbor_encode_uint(&rsp,  ueh.ue_module);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return (0);
+err:
+    return (rc);
+}
+
+/**
+ * Log encode entries
+ * @param log structure, the encoder, timestamp, index
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_encode_entries(struct log *log, CborEncoder *cb,
+                   int64_t ts, uint32_t index)
+{
+    int rc;
+    struct encode_off encode_off;
+    int rsp_len = 0;
+    CborEncoder entries;
+    CborError g_err = CborNoError;
+    struct CborCntWriter cnt_writer;
+    CborEncoder cnt_encoder;
+
+    memset(&encode_off, 0, sizeof(encode_off));
+
+    /* this code counts how long the message would be if we encoded
+     * this outer structure using cbor. */
+    cbor_cnt_writer_init(&cnt_writer);
+    cbor_encoder_init(&cnt_encoder, &cnt_writer.enc, 0);
+    g_err |= cbor_encode_text_stringz(&cnt_encoder, "entries");
+    g_err |= cbor_encoder_create_array(&cnt_encoder, &entries,
+                                       CborIndefiniteLength);
+    g_err |= cbor_encoder_close_container(&cnt_encoder, &entries);
+    rsp_len = cbor_encode_bytes_written(cb) +
+              cbor_encode_bytes_written(&cnt_encoder);
+    if (rsp_len > 400) {
+        rc = OS_ENOMEM;
+        goto err;
+    }
+
+    g_err |= cbor_encode_text_stringz(cb, "entries");
+    g_err |= cbor_encoder_create_array(cb, &entries, CborIndefiniteLength);
+
+    encode_off.eo_encoder  = (void*)&entries;
+    encode_off.eo_index    = index;
+    encode_off.eo_ts       = ts;
+    encode_off.rsp_len = rsp_len;
+
+    rc = log_walk(log, log_nmgr_encode_entry, &encode_off);
+
+    g_err |= cbor_encoder_close_container(cb, &entries);
+
+err:
+    return rc;
+}
+
+/**
+ * Log encode function
+ * @param log structure, the encoder, json_value,
+ *        timestamp, index
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_encode(struct log *log, CborEncoder *cb,
+            int64_t ts, uint32_t index)
+{
+    int rc;
+    CborEncoder logs;
+    CborError g_err = CborNoError;
+
+    g_err |= cbor_encoder_create_map(cb, &logs, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&logs, "name");
+    g_err |= cbor_encode_text_stringz(&logs, log->l_name);
+
+    g_err |= cbor_encode_text_stringz(&logs, "type");
+    g_err |= cbor_encode_uint(&logs, log->l_log->log_type);
+
+    rc = log_encode_entries(log, &logs, ts, index);
+    g_err |= cbor_encoder_close_container(cb, &logs);
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return rc;
+}
+
+/**
+ * Newtmgr Log read handler
+ * @param cbor buffer
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_read(struct mgmt_cbuf *cb)
+{
+    struct log *log;
+    int rc;
+    char name[LOG_NAME_MAX_LEN] = {0};
+    int name_len;
+    int64_t ts;
+    uint64_t index;
+    CborError g_err = CborNoError;
+    CborEncoder *penc = &cb->encoder;
+    CborEncoder rsp, logs;
+
+    const struct cbor_attr_t attr[4] = {
+        [0] = {
+            .attribute = "log_name",
+            .type = CborAttrTextStringType,
+            .addr.string = name,
+            .len = sizeof(name)
+        },
+        [1] = {
+            .attribute = "ts",
+            .type = CborAttrIntegerType,
+            .addr.integer = &ts
+        },
+        [2] = {
+            .attribute = "index",
+            .type = CborAttrUnsignedIntegerType,
+            .addr.uinteger = &index
+        },
+        [3] = {
+            .attribute = NULL
+        }
+    };
+
+    rc = cbor_read_object(&cb->it, attr);
+    if (rc) {
+        return rc;
+    }
+
+
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "logs");
+
+    g_err |= cbor_encoder_create_array(&rsp, &logs, CborIndefiniteLength);
+
+    name_len = strlen(name);
+    log = NULL;
+    while (1) {
+        log = log_list_get_next(log);
+        if (!log) {
+            break;
+        }
+
+        if (log->l_log->log_type == LOG_TYPE_STREAM) {
+            continue;
+        }
+
+        /* Conditions for returning specific logs */
+        if ((name_len > 0) && strcmp(name, log->l_name)) {
+            continue;
+        }
+
+        rc = log_encode(log, &logs, ts, index);
+        if (rc) {
+            goto err;
+        }
+
+        /* If a log was found, encode and break */
+        if (name_len > 0) {
+            break;
+        }
+    }
+
+
+    /* Running out of logs list and we have a specific log to look for */
+    if (!log && name_len > 0) {
+        rc = OS_EINVAL;
+    }
+
+err:
+    g_err |= cbor_encoder_close_container(&rsp, &logs);
+    g_err |= cbor_encode_text_stringz(&rsp, "rc");
+    g_err |= cbor_encode_int(&rsp, rc);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    rc = 0;
+    return (rc);
+}
+
+/**
+ * Newtmgr Module list handler
+ * @param nmgr json buffer
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_module_list(struct mgmt_cbuf *cb)
+{
+    int module;
+    char *str;
+    CborError g_err = CborNoError;
+    CborEncoder *penc = &cb->encoder;
+    CborEncoder rsp, modules;
+
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "rc");
+    g_err |= cbor_encode_int(&rsp, MGMT_ERR_EOK);
+
+    g_err |= cbor_encode_text_stringz(&rsp, "module_map");
+    g_err |= cbor_encoder_create_map(&rsp, &modules, CborIndefiniteLength);
+
+    module = LOG_MODULE_DEFAULT;
+    while (module < LOG_MODULE_MAX) {
+        str = LOG_MODULE_STR(module);
+        if (!strcmp(str, "UNKNOWN")) {
+            module++;
+            continue;
+        }
+
+        g_err |= cbor_encode_text_stringz(&modules, str);
+        g_err |= cbor_encode_uint(&modules, module);
+        module++;
+    }
+
+    g_err |= cbor_encoder_close_container(&rsp, &modules);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return (0);
+}
+
+/**
+ * Newtmgr Log list handler
+ * @param nmgr json buffer
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_logs_list(struct mgmt_cbuf *cb)
+{
+    CborError g_err = CborNoError;
+    CborEncoder *penc = &cb->encoder;
+    CborEncoder rsp, log_list;
+    struct log *log;
+
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "rc");
+    g_err |= cbor_encode_int(&rsp, MGMT_ERR_EOK);
+
+    g_err |= cbor_encode_text_stringz(&rsp, "log_list");
+    g_err |= cbor_encoder_create_array(&rsp, &log_list, CborIndefiniteLength);
+
+    log = NULL;
+    while (1) {
+        log = log_list_get_next(log);
+        if (!log) {
+            break;
+        }
+
+        if (log->l_log->log_type == LOG_TYPE_STREAM) {
+            continue;
+        }
+
+        g_err |= cbor_encode_text_stringz(&log_list, log->l_name);
+    }
+
+    g_err |= cbor_encoder_close_container(&rsp, &log_list);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return (0);
+}
+
+/**
+ * Newtmgr Log Level list handler
+ * @param nmgr json buffer
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_level_list(struct mgmt_cbuf *cb)
+{
+    CborError g_err = CborNoError;
+    CborEncoder *penc = &cb->encoder;
+    CborEncoder rsp, level_map;
+    int level;
+    char *str;
+
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encode_text_stringz(&rsp, "rc");
+    g_err |= cbor_encode_int(&rsp, MGMT_ERR_EOK);
+
+    g_err |= cbor_encode_text_stringz(&rsp, "level_map");
+    g_err |= cbor_encoder_create_map(&rsp, &level_map, CborIndefiniteLength);
+
+    level = LOG_LEVEL_DEBUG;
+    while (level < LOG_LEVEL_MAX) {
+        str = LOG_LEVEL_STR(level);
+        if (!strcmp(str, "UNKNOWN")) {
+            level++;
+            continue;
+        }
+
+        g_err |= cbor_encode_text_stringz(&level_map, str);
+        g_err |= cbor_encode_uint(&level_map, level);
+        level++;
+    }
+
+    g_err |= cbor_encoder_close_container(&rsp, &level_map);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return (0);
+}
+
+/**
+ * Newtmgr log clear handler
+ * @param nmgr json buffer
+ * @return 0 on success; non-zero on failure
+ */
+static int
+log_nmgr_clear(struct mgmt_cbuf *cb)
+{
+    CborError g_err = CborNoError;
+    CborEncoder *penc = &cb->encoder;
+    CborEncoder rsp;
+    struct log *log;
+    int rc;
+
+    log = NULL;
+    while (1) {
+        log = log_list_get_next(log);
+        if (log == NULL) {
+            break;
+        }
+
+        if (log->l_log->log_type == LOG_TYPE_STREAM) {
+            continue;
+        }
+
+        rc = log_flush(log);
+        if (rc) {
+            goto err;
+        }
+    }
+    g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength);
+    g_err |= cbor_encoder_close_container(penc, &rsp);
+
+    if (g_err) {
+        return MGMT_ERR_ENOMEM;
+    }
+    return 0;
+err:
+    mgmt_cbuf_setoerr(cb, rc);
+    return (rc);
+}
+
+/**
+ * Register nmgr group handlers.
+ * @return 0 on success; non-zero on failure
+ */
+int
+log_nmgr_register_group(void)
+{
+    int rc;
+
+    MGMT_GROUP_SET_HANDLERS(&log_nmgr_group, log_nmgr_group_handlers);
+    log_nmgr_group.mg_group_id = MGMT_GROUP_ID_LOGS;
+
+    rc = mgmt_group_register(&log_nmgr_group);
+    if (rc) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/src/log_shell.c
----------------------------------------------------------------------
diff --git a/sys/log/full/src/log_shell.c b/sys/log/full/src/log_shell.c
new file mode 100644
index 0000000..c56e53c
--- /dev/null
+++ b/sys/log/full/src/log_shell.c
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "syscfg/syscfg.h"
+
+/* This whole file is conditionally compiled based on whether the
+ * log package is configured to use the shell (MYNEWT_VAL(LOG_CLI)).
+ */
+
+#if MYNEWT_VAL(LOG_CLI)
+
+#include <stdio.h>
+#include <string.h>
+
+#include "os/os.h"
+#include "cbmem/cbmem.h"
+#include "log/log.h"
+#include "shell/shell.h"
+#include "console/console.h"
+
+static int
+shell_log_dump_entry(struct log *log, void *arg, void *dptr, uint16_t len)
+{
+    struct log_entry_hdr ueh;
+    char data[128];
+    int dlen;
+    int rc;
+
+    rc = log_read(log, dptr, &ueh, 0, sizeof(ueh));
+    if (rc != sizeof(ueh)) {
+        goto err;
+    }
+
+    dlen = min(len-sizeof(ueh), 128);
+
+    rc = log_read(log, dptr, data, sizeof(ueh), dlen);
+    if (rc < 0) {
+        goto err;
+    }
+    data[rc] = 0;
+
+    /* XXX: This is evil.  newlib printf does not like 64-bit
+     * values, and this causes memory to be overwritten.  Cast to a
+     * unsigned 32-bit value for now.
+     */
+    console_printf("[%lu] %s\n", (unsigned long) ueh.ue_ts, data);
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+shell_log_dump_all_cmd(int argc, char **argv)
+{
+    struct log *log;
+    int rc;
+
+    log = NULL;
+    while (1) {
+        log = log_list_get_next(log);
+        if (log == NULL) {
+            break;
+        }
+
+        if (log->l_log->log_type == LOG_TYPE_STREAM) {
+            continue;
+        }
+
+        console_printf("Dumping log %s\n", log->l_name);
+
+        rc = log_walk(log, shell_log_dump_entry, NULL);
+        if (rc != 0) {
+            goto err;
+        }
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+#endif
+
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/syscfg.yml
----------------------------------------------------------------------
diff --git a/sys/log/full/syscfg.yml b/sys/log/full/syscfg.yml
new file mode 100644
index 0000000..7ce1baf
--- /dev/null
+++ b/sys/log/full/syscfg.yml
@@ -0,0 +1,37 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    LOG_LEVEL:
+        description: 'TBD'
+        value: 0
+
+    LOG_FCB:
+        description: 'TBD'
+        value: 0
+
+    LOG_CLI:
+        description: 'TBD'
+        value: 0
+        restrictions:
+            - SHELL_TASK
+
+    LOG_NEWTMGR:
+        description: 'TBD'
+        value: 0

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/pkg.yml
----------------------------------------------------------------------
diff --git a/sys/log/full/test/pkg.yml b/sys/log/full/test/pkg.yml
new file mode 100644
index 0000000..d408275
--- /dev/null
+++ b/sys/log/full/test/pkg.yml
@@ -0,0 +1,30 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+pkg.name: sys/log/full/test
+pkg.type: unittest
+pkg.description: "Log unit tests."
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+
+pkg.deps: 
+    - test/testutil
+    - sys/log/full
+
+pkg.deps.SELFTEST:
+    - sys/console/stub

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/log_test.c
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/log_test.c b/sys/log/full/test/src/log_test.c
new file mode 100644
index 0000000..63fa032
--- /dev/null
+++ b/sys/log/full/test/src/log_test.c
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include <string.h>
+
+#include "syscfg/syscfg.h"
+#include "os/os.h"
+#include "testutil/testutil.h"
+#include "fcb/fcb.h"
+#include "log/log.h"
+
+struct flash_area fcb_areas[] = {
+    [0] = {
+        .fa_off = 0x00000000,
+        .fa_size = 16 * 1024
+    },
+    [1] = {
+        .fa_off = 0x00004000,
+        .fa_size = 16 * 1024
+    }
+};
+struct fcb log_fcb;
+struct log my_log;
+
+char *str_logs[] = {
+    "testdata",
+    "1testdata2",
+    NULL
+};
+int str_idx = 0;
+int str_max_idx = 0;
+
+int
+log_test_walk1(struct log *log, void *arg, void *dptr, uint16_t len)
+{
+    int rc;
+    struct log_entry_hdr ueh;
+    char data[128];
+    int dlen;
+
+    TEST_ASSERT(str_idx < str_max_idx);
+
+    rc = log_read(log, dptr, &ueh, 0, sizeof(ueh));
+    TEST_ASSERT(rc == sizeof(ueh));
+
+    dlen = len - sizeof(ueh);
+    TEST_ASSERT(dlen < sizeof(data));
+
+    rc = log_read(log, dptr, data, sizeof(ueh), dlen);
+    TEST_ASSERT(rc == dlen);
+
+    data[rc] = '\0';
+
+    TEST_ASSERT(strlen(str_logs[str_idx]) == dlen);
+    TEST_ASSERT(!memcmp(str_logs[str_idx], data, dlen));
+    str_idx++;
+
+    return 0;
+}
+
+int
+log_test_walk2(struct log *log, void *arg, void *dptr, uint16_t len)
+{
+    TEST_ASSERT(0);
+    return 0;
+}
+
+TEST_CASE_DECL(log_setup_fcb)
+TEST_CASE_DECL(log_append_fcb)
+TEST_CASE_DECL(log_walk_fcb)
+TEST_CASE_DECL(log_flush_fcb)
+
+TEST_SUITE(log_test_all)
+{
+    log_setup_fcb();
+    log_append_fcb();
+    log_walk_fcb();
+    log_flush_fcb();
+}
+
+#if MYNEWT_VAL(SELFTEST)
+
+int
+main(int argc, char **argv)
+{
+    ts_config.ts_print_results = 1;
+    tu_init();
+
+    log_test_all();
+
+    return tu_any_failed;
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/log_test.h
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/log_test.h b/sys/log/full/test/src/log_test.h
new file mode 100644
index 0000000..c4e37a6
--- /dev/null
+++ b/sys/log/full/test/src/log_test.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#ifndef _LOG_TEST_H
+#define _LOG_TEST_H
+#include <string.h>
+
+#include "syscfg/syscfg.h"
+#include "os/os.h"
+#include "testutil/testutil.h"
+#include "fcb/fcb.h"
+#include "log/log.h"
+
+#ifdef __cplusplus
+#extern "C" {
+#endif
+
+#define FCB_FLASH_AREAS 2
+
+extern struct flash_area fcb_areas[FCB_FLASH_AREAS];
+
+extern struct fcb log_fcb;
+extern struct log my_log;
+
+#define FCB_STR_LOGS_CNT 3
+
+extern char *str_logs[FCB_STR_LOGS_CNT];
+
+extern int str_idx;
+extern int str_max_idx;
+
+int log_test_walk1(struct log *log, void *arg, void *dptr, uint16_t len);
+int log_test_walk2(struct log *log, void *arg, void *dptr, uint16_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOG_TEST_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/testcases/log_append_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/testcases/log_append_fcb.c 
b/sys/log/full/test/src/testcases/log_append_fcb.c
new file mode 100644
index 0000000..3f45eae
--- /dev/null
+++ b/sys/log/full/test/src/testcases/log_append_fcb.c
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "log_test.h"
+
+TEST_CASE(log_append_fcb)
+{
+    char *str;
+
+    while (1) {
+        str = str_logs[str_max_idx];
+        if (!str) {
+            break;
+        }
+        log_printf(&my_log, 0, 0, str, strlen(str));
+        str_max_idx++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/testcases/log_flush_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/testcases/log_flush_fcb.c 
b/sys/log/full/test/src/testcases/log_flush_fcb.c
new file mode 100644
index 0000000..e799fd2
--- /dev/null
+++ b/sys/log/full/test/src/testcases/log_flush_fcb.c
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "log_test.h"
+
+TEST_CASE(log_flush_fcb)
+{
+    struct encode_off encode_off = { 0 };
+    int rc;
+
+    rc = log_flush(&my_log);
+    TEST_ASSERT(rc == 0);
+
+    rc = log_walk(&my_log, log_test_walk2, &encode_off);
+    TEST_ASSERT(rc == 0);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/testcases/log_setup_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/testcases/log_setup_fcb.c 
b/sys/log/full/test/src/testcases/log_setup_fcb.c
new file mode 100644
index 0000000..b54682a
--- /dev/null
+++ b/sys/log/full/test/src/testcases/log_setup_fcb.c
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "log_test.h"
+
+TEST_CASE(log_setup_fcb)
+{
+    int rc;
+    int i;
+
+    log_fcb.f_sectors = fcb_areas;
+    log_fcb.f_sector_cnt = sizeof(fcb_areas) / sizeof(fcb_areas[0]);
+    log_fcb.f_magic = 0x7EADBADF;
+    log_fcb.f_version = 0;
+
+    for (i = 0; i < log_fcb.f_sector_cnt; i++) {
+        rc = flash_area_erase(&fcb_areas[i], 0, fcb_areas[i].fa_size);
+        TEST_ASSERT(rc == 0);
+    }
+    rc = fcb_init(&log_fcb);
+    TEST_ASSERT(rc == 0);
+
+    log_register("log", &my_log, &log_fcb_handler, &log_fcb, LOG_SYSLEVEL);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/src/testcases/log_walk_fcb.c
----------------------------------------------------------------------
diff --git a/sys/log/full/test/src/testcases/log_walk_fcb.c 
b/sys/log/full/test/src/testcases/log_walk_fcb.c
new file mode 100644
index 0000000..e8a732c
--- /dev/null
+++ b/sys/log/full/test/src/testcases/log_walk_fcb.c
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "log_test.h"
+
+TEST_CASE(log_walk_fcb)
+{
+    struct encode_off encode_off = { 0 };
+    int rc;
+
+    str_idx = 0;
+
+    rc = log_walk(&my_log, log_test_walk1, &encode_off);
+    TEST_ASSERT(rc == 0);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/full/test/syscfg.yml
----------------------------------------------------------------------
diff --git a/sys/log/full/test/syscfg.yml b/sys/log/full/test/syscfg.yml
new file mode 100644
index 0000000..22487f5
--- /dev/null
+++ b/sys/log/full/test/syscfg.yml
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Package: sys/log/test
+
+syscfg.vals:
+    LOG_FCB: 1

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/00896291/sys/log/include/log/ignore.h
----------------------------------------------------------------------
diff --git a/sys/log/include/log/ignore.h b/sys/log/include/log/ignore.h
deleted file mode 100644
index 46282a0..0000000
--- a/sys/log/include/log/ignore.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef H_IGNORE_
-#define H_IGNORE_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * These macros prevent the "set but not used" warnings for log writes below
- * the log level.
- */
-
-#define IGN_1(X) ((void)(X))
-#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__)
-#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__)
-#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__)
-#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__)
-#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__)
-#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__)
-#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__)
-#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__)
-#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__)
-#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__)
-#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__)
-#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__)
-#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__)
-#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__)
-#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__)
-#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__)
-#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__)
-#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__)
-#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__)
-
-#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
-                  _13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME
-#define IGNORE(...) \
-    GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \
-              IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \
-              IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

Reply via email to