You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by pa...@apache.org on 2016/09/14 20:32:47 UTC

[01/10] incubator-mynewt-core git commit: some changes to support printing with different size intergers.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 0b82d070c -> 1693f95a3


some changes to support printing with different size intergers.


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/1693f95a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/1693f95a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/1693f95a

Branch: refs/heads/develop
Commit: 1693f95a3c4698792798ac4c2612e9fe90cc5723
Parents: ece29bb
Author: Paul Dietrich <pa...@yahoo.com>
Authored: Wed Sep 14 13:30:42 2016 -0700
Committer: Paul Dietrich <pa...@yahoo.com>
Committed: Wed Sep 14 13:32:32 2016 -0700

----------------------------------------------------------------------
 libs/baselibc/include/inttypes.h                | 7 +++++--
 libs/iotivity/src/messaging/coap/coap.c         | 2 +-
 libs/iotivity/src/messaging/coap/engine.c       | 8 ++++----
 libs/iotivity/src/messaging/coap/transactions.c | 2 +-
 4 files changed, 11 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1693f95a/libs/baselibc/include/inttypes.h
----------------------------------------------------------------------
diff --git a/libs/baselibc/include/inttypes.h b/libs/baselibc/include/inttypes.h
index 29311fe..e9ee426 100644
--- a/libs/baselibc/include/inttypes.h
+++ b/libs/baselibc/include/inttypes.h
@@ -23,6 +23,9 @@ __extern uintmax_t strntoumax(const char *, char **, int, size_t);
 
 #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
 
+#define __PRI64_RANK "ll"
+#define __PRI32_RANK "l"
+
 #define PRId8	"d"
 #define PRId16	"d"
 #define PRId32	"d"
@@ -97,7 +100,7 @@ __extern uintmax_t strntoumax(const char *, char **, int, size_t);
 
 #define PRIx8	"x"
 #define PRIx16	"x"
-#define PRIx32	"x"
+#define PRIx32	__PRI32_RANK "x"
 #define PRIx64	__PRI64_RANK "x"
 
 #define PRIxLEAST8	"x"
@@ -115,7 +118,7 @@ __extern uintmax_t strntoumax(const char *, char **, int, size_t);
 
 #define PRIX8	"X"
 #define PRIX16	"X"
-#define PRIX32	"X"
+#define PRIX32	__PRI32_RANK "X"
 #define PRIX64	__PRI64_RANK "X"
 
 #define PRIXLEAST8	"X"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1693f95a/libs/iotivity/src/messaging/coap/coap.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/coap.c b/libs/iotivity/src/messaging/coap/coap.c
index e8d8608..d77fbbb 100644
--- a/libs/iotivity/src/messaging/coap/coap.c
+++ b/libs/iotivity/src/messaging/coap/coap.c
@@ -405,7 +405,7 @@ coap_serialize_message(void *packet, uint8_t *buffer)
 void
 coap_send_message(oc_message_t *message)
 {
-  LOG("-sending OCF message (%lu)-\n", message->length);
+  LOG("-sending OCF message (%u)-\n", (unsigned int) message->length);
 
   oc_send_message(message);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1693f95a/libs/iotivity/src/messaging/coap/engine.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/engine.c b/libs/iotivity/src/messaging/coap/engine.c
index 638541e..0eecabf 100644
--- a/libs/iotivity/src/messaging/coap/engine.c
+++ b/libs/iotivity/src/messaging/coap/engine.c
@@ -61,7 +61,7 @@ coap_receive(oc_message_t *msg)
 {
   erbium_status_code = NO_ERROR;
 
-  LOG("\n\nCoAP Engine: received datalen=%lu \n", msg->length);
+  LOG("\n\nCoAP Engine: received datalen=%u \n", (unsigned int) msg->length);
 
   /* static declaration reduces stack peaks and program code size */
   static coap_packet_t
@@ -141,8 +141,8 @@ coap_receive(oc_message_t *msg)
         }
         if (coap_get_header_block2(message, &block_num, NULL, &block_size,
                                    &block_offset)) {
-          LOG("\tBlockwise: block request %u (%u/%u) @ %u bytes\n", block_num,
-              block_size, COAP_MAX_BLOCK_SIZE, block_offset);
+          LOG("\tBlockwise: block request %u (%u/%u) @ %u bytes\n", (unsigned int) block_num,
+              block_size, COAP_MAX_BLOCK_SIZE, (unsigned int) block_offset);
           block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
           new_offset = block_offset;
         }
@@ -195,7 +195,7 @@ coap_receive(oc_message_t *msg)
                 /* resource provides chunk-wise data */
               } else {
                 LOG("\tBlockwise: blockwise resource, new offset %d\n",
-                    new_offset);
+                    (int) new_offset);
                 coap_set_header_block2(response, block_num,
                                        new_offset != -1 ||
                                          response->payload_len > block_size,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1693f95a/libs/iotivity/src/messaging/coap/transactions.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/transactions.c b/libs/iotivity/src/messaging/coap/transactions.c
index 851cce1..facd95f 100644
--- a/libs/iotivity/src/messaging/coap/transactions.c
+++ b/libs/iotivity/src/messaging/coap/transactions.c
@@ -68,7 +68,7 @@ coap_new_transaction(uint16_t mid, oc_endpoint_t *endpoint)
   if (t) {
     oc_message_t *message = oc_allocate_message();
     if (message) {
-      LOG("Created new transaction %d %ld\n", mid, message->length);
+      LOG("Created new transaction %d %d\n", mid, (int) message->length);
       t->mid = mid;
       t->retrans_counter = 0;
 


[03/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborparser.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborparser.c b/libs/tinycbor/src/cborparser.c
new file mode 100644
index 0000000..1d81091
--- /dev/null
+++ b/libs/tinycbor/src/cborparser.c
@@ -0,0 +1,1293 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborconstants_p.h"
+#include "compilersupport_p.h"
+#include "extract_number_p.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "assert_p.h"       /* Always include last */
+
+#ifndef CBOR_PARSER_MAX_RECURSIONS
+#  define CBOR_PARSER_MAX_RECURSIONS 1024
+#endif
+
+/**
+ * \defgroup CborParsing Parsing CBOR streams
+ * \brief Group of functions used to parse CBOR streams.
+ *
+ * TinyCBOR provides functions for pull-based stream parsing of a CBOR-encoded
+ * payload. The main data type for the parsing is a CborValue, which behaves
+ * like an iterator and can be used to extract the encoded data. It is first
+ * initialized with a call to cbor_parser_init() and is usually used to extract
+ * exactly one item, most often an array or map.
+ *
+ * Nested CborValue objects can be parsed using cbor_value_enter_container().
+ * Each call to cbor_value_enter_container() must be matched by a call to
+ * cbor_value_leave_container(), with the exact same parameters.
+ *
+ * The example below initializes a CborParser object, begins the parsing with a
+ * CborValue and decodes a single integer:
+ *
+ * \code
+ * int extract_int(const uint8_t *buffer, size_t len)
+ * {
+ *     CborParser parser;
+ *     CborValue value;
+ *     int result;
+ *     cbor_parser_init(buffer, len, 0, &buffer, &value);
+ *     cbor_value_get_int(&value, &result);
+ *     return result;
+ * }
+ * \endcode
+ *
+ * The code above does no error checking, which means it assumes the data comes
+ * from a source trusted to send one properly-encoded integer. The following
+ * example does the exact same operation, but includes error parsing and
+ * returns 0 on parsing failure:
+ *
+ * \code
+ * int extract_int(const uint8_t *buffer, size_t len)
+ * {
+ *     CborParser parser;
+ *     CborValue value;
+ *     int result;
+ *     if (cbor_parser_init(buffer, len, 0, &buffer, &value) != CborNoError)
+ *         return 0;
+ *     if (!cbor_value_is_integer(&value) ||
+ *             cbor_value_get_int(&value, &result) != CborNoError)
+ *         return 0;
+ *     return result;
+ * }
+ * \endcode
+ *
+ * Note, in the example above, that one can't distinguish a parsing failure
+ * from an encoded value of zero. Reporting a parsing error is left as an
+ * exercise to the reader.
+ *
+ * The code above does not execute a range-check either: it is possible that
+ * the value decoded from the CBOR stream encodes a number larger than what can
+ * be represented in a variable of type \c{int}. If detecting that case is
+ * important, the code should call cbor_value_get_int_checked() instead.
+ *
+ * <h3 class="groupheader">Memory and parsing constraints</h3>
+ *
+ * TinyCBOR is designed to run with little memory and with minimal overhead.
+ * Except where otherwise noted, the parser functions always run on constant
+ * time (O(1)), do not recurse and never allocate memory (thus, stack usage is
+ * bounded and is O(1)).
+ *
+ * <h3 class="groupheader">Error handling and preconditions</h3>
+ *
+ * All functions operating on a CborValue return a CborError condition, with
+ * CborNoError standing for the normal situation in which no parsing error
+ * occurred. All functions may return parsing errors in case the stream cannot
+ * be decoded properly, be it due to corrupted data or due to reaching the end
+ * of the input buffer.
+ *
+ * Error conditions must not be ignored. All decoder functions have undefined
+ * behavior if called after an error has been reported, and may crash.
+ *
+ * Some functions are also documented to have preconditions, like
+ * cbor_value_get_int() requiring that the input be an integral value.
+ * Violation of preconditions also results in undefined behavior and the
+ * program may crash.
+ */
+
+/**
+ * \addtogroup CborParsing
+ * @{
+ */
+
+/**
+ * \struct CborValue
+ *
+ * This type contains one value parsed from the CBOR stream. Each CborValue
+ * behaves as an iterator in a StAX-style parser.
+ *
+ * \if privatedocs
+ * Implementation details: the CborValue contains these fields:
+ * \list
+ *   \li ptr: pointer to the actual data
+ *   \li flags: flags from the decoder
+ *   \li extra: partially decoded integer value (0, 1 or 2 bytes)
+ *   \li remaining: remaining items in this collection after this item or UINT32_MAX if length is unknown
+ * \endlist
+ * \endif
+ */
+
+static CborError extract_length(const CborParser *parser, const uint8_t **ptr, size_t *len)
+{
+    uint64_t v;
+    CborError err = extract_number(ptr, parser->end, &v);
+    if (err) {
+        *len = 0;
+        return err;
+    }
+
+    *len = v;
+    if (v != *len)
+        return CborErrorDataTooLarge;
+    return CborNoError;
+}
+
+static bool is_fixed_type(uint8_t type)
+{
+    return type != CborTextStringType && type != CborByteStringType && type != CborArrayType &&
+           type != CborMapType;
+}
+
+static CborError preparse_value(CborValue *it)
+{
+    const CborParser *parser = it->parser;
+    it->type = CborInvalidType;
+
+    /* are we at the end? */
+    if (it->ptr == parser->end)
+        return CborErrorUnexpectedEOF;
+
+    uint8_t descriptor = *it->ptr;
+    uint8_t type = descriptor & MajorTypeMask;
+    it->type = type;
+    it->flags = 0;
+    it->extra = (descriptor &= SmallValueMask);
+
+    if (descriptor > Value64Bit) {
+        if (unlikely(descriptor != IndefiniteLength))
+            return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber;
+        if (likely(!is_fixed_type(type))) {
+            /* special case */
+            it->flags |= CborIteratorFlag_UnknownLength;
+            it->type = type;
+            return CborNoError;
+        }
+        return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber;
+    }
+
+    size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit));
+    if (bytesNeeded + 1 > (size_t)(parser->end - it->ptr))
+        return CborErrorUnexpectedEOF;
+
+    uint8_t majortype = type >> MajorTypeShift;
+    if (majortype == NegativeIntegerType) {
+        it->flags |= CborIteratorFlag_NegativeInteger;
+        it->type = CborIntegerType;
+    } else if (majortype == SimpleTypesType) {
+        switch (descriptor) {
+        case FalseValue:
+            it->extra = false;
+            it->type = CborBooleanType;
+            break;
+
+        case SinglePrecisionFloat:
+        case DoublePrecisionFloat:
+            it->flags |= CborIteratorFlag_IntegerValueTooLarge;
+            /* fall through */
+        case TrueValue:
+        case NullValue:
+        case UndefinedValue:
+        case HalfPrecisionFloat:
+            it->type = *it->ptr;
+            break;
+
+        case SimpleTypeInNextByte:
+            it->extra = (uint8_t)it->ptr[1];
+#ifndef CBOR_PARSER_NO_STRICT_CHECKS
+            if (unlikely(it->extra < 32)) {
+                it->type = CborInvalidType;
+                return CborErrorIllegalSimpleType;
+            }
+#endif
+            break;
+
+        case 28:
+        case 29:
+        case 30:
+        case Break:
+            assert(false);  /* these conditions can't be reached */
+            return CborErrorUnexpectedBreak;
+        }
+        return CborNoError;
+    }
+
+    /* try to decode up to 16 bits */
+    if (descriptor < Value8Bit)
+        return CborNoError;
+
+    if (descriptor == Value8Bit)
+        it->extra = (uint8_t)it->ptr[1];
+    else if (descriptor == Value16Bit)
+        it->extra = get16(it->ptr + 1);
+    else
+        it->flags |= CborIteratorFlag_IntegerValueTooLarge;     /* Value32Bit or Value64Bit */
+    return CborNoError;
+}
+
+static CborError preparse_next_value(CborValue *it)
+{
+    if (it->remaining != UINT32_MAX) {
+        /* don't decrement the item count if the current item is tag: they don't count */
+        if (it->type != CborTagType && !--it->remaining) {
+            it->type = CborInvalidType;
+            return CborNoError;
+        }
+    } else if (it->remaining == UINT32_MAX && it->ptr != it->parser->end && *it->ptr == (uint8_t)BreakByte) {
+        /* end of map or array */
+        ++it->ptr;
+        it->type = CborInvalidType;
+        it->remaining = 0;
+        return CborNoError;
+    }
+
+    return preparse_value(it);
+}
+
+static CborError advance_internal(CborValue *it)
+{
+    uint64_t length;
+    CborError err = extract_number(&it->ptr, it->parser->end, &length);
+    assert(err == CborNoError);
+
+    if (it->type == CborByteStringType || it->type == CborTextStringType) {
+        assert(length == (size_t)length);
+        assert((it->flags & CborIteratorFlag_UnknownLength) == 0);
+        it->ptr += length;
+    }
+
+    return preparse_next_value(it);
+}
+
+/** \internal
+ *
+ * Decodes the CBOR integer value when it is larger than the 16 bits available
+ * in value->extra. This function requires that value->flags have the
+ * CborIteratorFlag_IntegerValueTooLarge flag set.
+ *
+ * This function is also used to extract single- and double-precision floating
+ * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat ==
+ * Value64Bit).
+ */
+uint64_t _cbor_value_decode_int64_internal(const CborValue *value)
+{
+    assert(value->flags & CborIteratorFlag_IntegerValueTooLarge ||
+           value->type == CborFloatType || value->type == CborDoubleType);
+
+    /* since the additional information can only be Value32Bit or Value64Bit,
+     * we just need to test for the one bit those two options differ */
+    assert((*value->ptr & SmallValueMask) == Value32Bit || (*value->ptr & SmallValueMask) == Value64Bit);
+    if ((*value->ptr & 1) == (Value32Bit & 1))
+        return get32(value->ptr + 1);
+
+    assert((*value->ptr & SmallValueMask) == Value64Bit);
+    return get64(value->ptr + 1);
+}
+
+/**
+ * Initializes the CBOR parser for parsing \a size bytes beginning at \a
+ * buffer. Parsing will use flags set in \a flags. The iterator to the first
+ * element is returned in \a it.
+ *
+ * The \a parser structure needs to remain valid throughout the decoding
+ * process. It is not thread-safe to share one CborParser among multiple
+ * threads iterating at the same time, but the object can be copied so multiple
+ * threads can iterate.
+ */
+CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it)
+{
+    memset(parser, 0, sizeof(*parser));
+    parser->end = buffer + size;
+    parser->flags = flags;
+    it->parser = parser;
+    it->ptr = buffer;
+    it->remaining = 1;      /* there's one type altogether, usually an array or map */
+    return preparse_value(it);
+}
+
+/**
+ * \fn bool cbor_value_at_end(const CborValue *it)
+ *
+ * Returns true if \a it has reached the end of the iteration, usually when
+ * advancing after the last item in an array or map.
+ *
+ * In the case of the outermost CborValue object, this function returns true
+ * after decoding a single element. A pointer to the first byte of the
+ * remaining data (if any) can be obtained with cbor_value_get_next_byte().
+ *
+ * \sa cbor_value_advance(), cbor_value_is_valid(), cbor_value_get_next_byte()
+ */
+
+/**
+ * \fn const uint8_t *cbor_value_get_next_byte(const CborValue *it)
+ *
+ * Returns a pointer to the next byte that would be decoded if this CborValue
+ * object were advanced.
+ *
+ * This function is useful if cbor_value_at_end() returns true for the
+ * outermost CborValue: the pointer returned is the first byte of the data
+ * remaining in the buffer, if any. Code can decide whether to begin decoding a
+ * new CBOR data stream from this point, or parse some other data appended to
+ * the same buffer.
+ *
+ * This function may be used even after a parsing error. If that occurred,
+ * then this function returns a pointer to where the parsing error occurred.
+ * Note that the error recovery is not precise and the pointer may not indicate
+ * the exact byte containing bad data.
+ *
+ * \sa cbor_value_at_end()
+ */
+
+/**
+ * \fn bool cbor_value_is_valid(const CborValue *it)
+ *
+ * Returns true if the iterator \a it contains a valid value. Invalid iterators
+ * happen when iteration reaches the end of a container (see \ref
+ * cbor_value_at_end()) or when a search function resulted in no matches.
+ *
+ * \sa cbor_value_advance(), cbor_valie_at_end(), cbor_value_get_type()
+ */
+
+/**
+ * Advances the CBOR value \a it by one fixed-size position. Fixed-size types
+ * are: integers, tags, simple types (including boolean, null and undefined
+ * values) and floating point types.
+ *
+ * If the type is not of fixed size, this function has undefined behavior. Code
+ * must be sure that the current type is one of the fixed-size types before
+ * calling this function. This function is provided because it can guarantee
+ * that runs in constant time (O(1)).
+ *
+ * If the caller is not able to determine whether the type is fixed or not, code
+ * can use the cbor_value_advance() function instead.
+ *
+ * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_enter_container(), cbor_value_leave_container()
+ */
+CborError cbor_value_advance_fixed(CborValue *it)
+{
+    assert(it->type != CborInvalidType);
+    assert(is_fixed_type(it->type));
+    if (!it->remaining)
+        return CborErrorAdvancePastEOF;
+    return advance_internal(it);
+}
+
+static CborError advance_recursive(CborValue *it, int nestingLevel)
+{
+    if (is_fixed_type(it->type))
+        return advance_internal(it);
+
+    if (!cbor_value_is_container(it)) {
+        size_t len = SIZE_MAX;
+        return _cbor_value_copy_string(it, NULL, &len, it);
+    }
+
+    /* map or array */
+    if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS)
+        return CborErrorNestingTooDeep;
+
+    CborError err;
+    CborValue recursed;
+    err = cbor_value_enter_container(it, &recursed);
+    if (err)
+        return err;
+    while (!cbor_value_at_end(&recursed)) {
+        err = advance_recursive(&recursed, nestingLevel + 1);
+        if (err)
+            return err;
+    }
+    return cbor_value_leave_container(it, &recursed);
+}
+
+
+/**
+ * Advances the CBOR value \a it by one element, skipping over containers.
+ * Unlike cbor_value_advance_fixed(), this function can be called on a CBOR
+ * value of any type. However, if the type is a container (map or array) or a
+ * string with a chunked payload, this function will not run in constant time
+ * and will recurse into itself (it will run on O(n) time for the number of
+ * elements or chunks and will use O(n) memory for the number of nested
+ * containers).
+ *
+ * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_enter_container(), cbor_value_leave_container()
+ */
+CborError cbor_value_advance(CborValue *it)
+{
+    assert(it->type != CborInvalidType);
+    if (!it->remaining)
+        return CborErrorAdvancePastEOF;
+    return advance_recursive(it, 0);
+}
+
+/**
+ * \fn bool cbor_value_is_tag(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR tag.
+ *
+ * \sa cbor_value_get_tag(), cbor_value_skip_tag()
+ */
+
+/**
+ * \fn CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
+ *
+ * Retrieves the CBOR tag value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to a CBOR tag value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_tag is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_tag()
+ */
+
+/**
+ * Advances the CBOR value \a it until it no longer points to a tag. If \a it is
+ * already not pointing to a tag, then this function returns it unchanged.
+ *
+ * This function does not run in constant time: it will run on O(n) for n being
+ * the number of tags. It does use constant memory (O(1) memory requirements).
+ *
+ * \sa cbor_value_advance_fixed(), cbor_value_advance()
+ */
+CborError cbor_value_skip_tag(CborValue *it)
+{
+    while (cbor_value_is_tag(it)) {
+        CborError err = cbor_value_advance_fixed(it);
+        if (err)
+            return err;
+    }
+    return CborNoError;
+}
+
+/**
+ * \fn bool cbor_value_is_container(const CborValue *it)
+ *
+ * Returns true if the \a it value is a container and requires recursion in
+ * order to decode (maps and arrays), false otherwise.
+ */
+
+/**
+ * Creates a CborValue iterator pointing to the first element of the container
+ * represented by \a it and saves it in \a recursed. The \a it container object
+ * needs to be kept and passed again to cbor_value_leave_container() in order
+ * to continue iterating past this container.
+ *
+ * The \a it CborValue iterator must point to a container.
+ *
+ * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance()
+ */
+CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed)
+{
+    CborError err;
+    assert(cbor_value_is_container(it));
+    *recursed = *it;
+
+    if (it->flags & CborIteratorFlag_UnknownLength) {
+        recursed->remaining = UINT32_MAX;
+        ++recursed->ptr;
+        err = preparse_value(recursed);
+        if (err != CborErrorUnexpectedBreak)
+            return err;
+        /* actually, break was expected here
+         * it's just an empty container */
+        ++recursed->ptr;
+    } else {
+        uint64_t len;
+        err = extract_number(&recursed->ptr, recursed->parser->end, &len);
+        assert(err == CborNoError);
+
+        recursed->remaining = (uint32_t)len;
+        if (recursed->remaining != len || len == UINT32_MAX) {
+            /* back track the pointer to indicate where the error occurred */
+            recursed->ptr = it->ptr;
+            return CborErrorDataTooLarge;
+        }
+        if (recursed->type == CborMapType) {
+            /* maps have keys and values, so we need to multiply by 2 */
+            if (recursed->remaining > UINT32_MAX / 2) {
+                /* back track the pointer to indicate where the error occurred */
+                recursed->ptr = it->ptr;
+                return CborErrorDataTooLarge;
+            }
+            recursed->remaining *= 2;
+        }
+        if (len != 0)
+            return preparse_value(recursed);
+    }
+
+    /* the case of the empty container */
+    recursed->type = CborInvalidType;
+    recursed->remaining = 0;
+    return CborNoError;
+}
+
+/**
+ * Updates \a it to point to the next element after the container. The \a
+ * recursed object needs to point to the element obtained either by advancing
+ * the last element of the container (via cbor_value_advance(),
+ * cbor_value_advance_fixed(), a nested cbor_value_leave_container(), or the \c
+ * next pointer from cbor_value_copy_string() or cbor_value_dup_string()).
+ *
+ * The \a it and \a recursed parameters must be the exact same as passed to
+ * cbor_value_enter_container().
+ *
+ * \sa cbor_value_enter_container(), cbor_value_at_end()
+ */
+CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed)
+{
+    assert(cbor_value_is_container(it));
+    assert(recursed->type == CborInvalidType);
+    it->ptr = recursed->ptr;
+    return preparse_next_value(it);
+}
+
+
+/**
+ * \fn CborType cbor_value_get_type(const CborValue *value)
+ *
+ * Returns the type of the CBOR value that the iterator \a value points to. If
+ * \a value does not point to a valid value, this function returns \ref
+ * CborInvalidType.
+ *
+ * TinyCBOR also provides functions to test directly if a given CborValue object
+ * is of a given type, like cbor_value_is_text_string() and cbor_value_is_null().
+ *
+ * \sa cbor_value_is_valid()
+ */
+
+/**
+ * \fn bool cbor_value_is_null(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR null type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_undefined()
+ */
+
+/**
+ * \fn bool cbor_value_is_undefined(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR undefined type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_null()
+ */
+
+/**
+ * \fn bool cbor_value_is_boolean(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR boolean
+ * type (true or false).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_boolean()
+ */
+
+/**
+ * \fn CborError cbor_value_get_boolean(const CborValue *value, bool *result)
+ *
+ * Retrieves the boolean value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to a boolean value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_boolean is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_boolean()
+ */
+
+/**
+ * \fn bool cbor_value_is_simple_type(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR Simple Type
+ * type (other than true, false, null and undefined).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_simple_type()
+ */
+
+/**
+ * \fn CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
+ *
+ * Retrieves the CBOR Simple Type value that \a value points to and stores it
+ * in \a result. If the iterator \a value does not point to a simple_type
+ * value, the behavior is undefined, so checking with \ref cbor_value_get_type
+ * or with \ref cbor_value_is_simple_type is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_simple_type()
+ */
+
+/**
+ * \fn bool cbor_value_is_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR integer
+ * type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_uint64, cbor_value_get_raw_integer
+ */
+
+/**
+ * \fn bool cbor_value_is_unsigned_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR unsigned
+ * integer type (positive values or zero).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_uint64()
+ */
+
+/**
+ * \fn bool cbor_value_is_negative_integer(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR negative
+ * integer type.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_int, cbor_value_get_int64, cbor_value_get_raw_integer
+ */
+
+/**
+ * \fn CborError cbor_value_get_int(const CborValue *value, int *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Note that this function does not do range-checking: integral values that do
+ * not fit in a variable of type \c{int} are silently truncated to fit. Use
+ * cbor_value_get_int_checked() that is not acceptable.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Note that this function does not do range-checking: integral values that do
+ * not fit in a variable of type \c{int64_t} are silently truncated to fit. Use
+ * cbor_value_get_int64_checked() that is not acceptable.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an unsigned integer
+ * value, the behavior is undefined, so checking with \ref cbor_value_get_type
+ * or with \ref cbor_value_is_unsigned_integer is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_unsigned_integer()
+ */
+
+/**
+ * \fn CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
+ *
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * This function is provided because CBOR negative integers can assume values
+ * that cannot be represented with normal 64-bit integer variables.
+ *
+ * If the integer is unsigned (that is, if cbor_value_is_unsigned_integer()
+ * returns true), then \a result will contain the actual value. If the integer
+ * is negative, then \a result will contain the absolute value of that integer,
+ * minus one. That is, \c {actual = -result - 1}. On architectures using two's
+ * complement for representation of negative integers, it is equivalent to say
+ * that \a result will contain the bitwise negation of the actual value.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer()
+ */
+
+/**
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Unlike cbor_value_get_int64(), this function performs a check to see if the
+ * stored integer fits in \a result without data loss. If the number is outside
+ * the valid range for the data type, this function returns the recoverable
+ * error CborErrorDataTooLarge. In that case, use either
+ * cbor_value_get_uint64() (if the number is positive) or
+ * cbor_value_get_raw_integer().
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64()
+ */
+CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result)
+{
+    assert(cbor_value_is_integer(value));
+    uint64_t v = _cbor_value_extract_int64_helper(value);
+
+    /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3):
+     * "[if] the new type is signed and the value cannot be represented in it; either the
+     *  result is implementation-defined or an implementation-defined signal is raised."
+     *
+     * The range for int64_t is -2^63 to 2^63-1 (int64_t is required to be
+     * two's complement, C11 7.20.1.1 paragraph 3), which in CBOR is
+     * represented the same way, differing only on the "sign bit" (the major
+     * type).
+     */
+
+    if (unlikely(v > (uint64_t)INT64_MAX))
+        return CborErrorDataTooLarge;
+
+    *result = v;
+    if (value->flags & CborIteratorFlag_NegativeInteger)
+        *result = -*result - 1;
+    return CborNoError;
+}
+
+/**
+ * Retrieves the CBOR integer value that \a value points to and stores it in \a
+ * result. If the iterator \a value does not point to an integer value, the
+ * behavior is undefined, so checking with \ref cbor_value_get_type or with
+ * \ref cbor_value_is_integer is recommended.
+ *
+ * Unlike cbor_value_get_int(), this function performs a check to see if the
+ * stored integer fits in \a result without data loss. If the number is outside
+ * the valid range for the data type, this function returns the recoverable
+ * error CborErrorDataTooLarge. In that case, use one of the other integer
+ * functions to obtain the value.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_integer(), cbor_value_get_int64(),
+ *     cbor_value_get_uint64(), cbor_value_get_int64_checked(), cbor_value_get_raw_integer()
+ */
+CborError cbor_value_get_int_checked(const CborValue *value, int *result)
+{
+    assert(cbor_value_is_integer(value));
+    uint64_t v = _cbor_value_extract_int64_helper(value);
+
+    /* Check before converting, as the standard says (C11 6.3.1.3 paragraph 3):
+     * "[if] the new type is signed and the value cannot be represented in it; either the
+     *  result is implementation-defined or an implementation-defined signal is raised."
+     *
+     * But we can convert from signed to unsigned without fault (paragraph 2).
+     *
+     * The range for int is implementation-defined and int is not guaranteed use
+     * two's complement representation (int32_t is).
+     */
+
+    if (value->flags & CborIteratorFlag_NegativeInteger) {
+        if (unlikely(v > (unsigned) -(INT_MIN + 1)))
+            return CborErrorDataTooLarge;
+
+        *result = v;
+        *result = -*result - 1;
+    } else {
+        if (unlikely(v > (uint64_t)INT_MAX))
+            return CborErrorDataTooLarge;
+
+        *result = v;
+    }
+    return CborNoError;
+
+}
+
+/**
+ * \fn bool cbor_value_is_length_known(const CborValue *value)
+ *
+ * Returns true if the length of this type is known without calculation. That
+ * is, if the length of this CBOR string, map or array is encoded in the data
+ * stream, this function returns true. If the length is not encoded, it returns
+ * false.
+ *
+ * If the length is known, code can call cbor_value_get_string_length(),
+ * cbor_value_get_array_length() or cbor_value_get_map_length() to obtain the
+ * length. If the length is not known but is necessary, code can use the
+ * cbor_value_calculate_string_length() function (no equivalent function is
+ * provided for maps and arrays).
+ */
+
+/**
+ * \fn bool cbor_value_is_text_string(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR text
+ * string. CBOR text strings are UTF-8 encoded and usually contain
+ * human-readable text.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(),
+ *     cbor_value_copy_text_string(), cbor_value_dup_text_string()
+ */
+
+/**
+ * \fn bool cbor_value_is_byte_string(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR text
+ * string. CBOR byte strings are binary data with no specified encoding or
+ * format.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_get_string_length(), cbor_value_calculate_string_length(),
+ *     cbor_value_copy_byte_string(), cbor_value_dup_byte_string()
+ */
+
+/**
+ * \fn CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the byte or text string that \a value points to and
+ * stores it in \a result. If the iterator \a value does not point to a text
+ * string or a byte string, the behaviour is undefined, so checking with \ref
+ * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * If the length of this string is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * If the length of the string is required but the length was not encoded, use
+ * cbor_value_calculate_string_length(), but note that that function does not
+ * run in constant time.
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known(), cbor_value_calculate_string_length()
+ */
+
+/**
+ * Calculates the length of the byte or text string that \a value points to and
+ * stores it in \a len. If the iterator \a value does not point to a text
+ * string or a byte string, the behaviour is undefined, so checking with \ref
+ * cbor_value_get_type, with \ref cbor_value_is_text_string or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * This function is different from cbor_value_get_string_length() in that it
+ * calculates the length even for strings sent in chunks. For that reason, this
+ * function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It does use constant memory (O(1)).
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_get_string_length(), cbor_value_copy_string(), cbor_value_is_length_known()
+ */
+CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len)
+{
+    *len = SIZE_MAX;
+    return _cbor_value_copy_string(value, NULL, len, NULL);
+}
+
+/* We return uintptr_t so that we can pass memcpy directly as the iteration
+ * function. The choice is to optimize for memcpy, which is used in the base
+ * parser API (cbor_value_copy_string), while memcmp is used in convenience API
+ * only. */
+typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t);
+
+static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len)
+{
+    (void)dest;
+    (void)src;
+    (void)len;
+    return true;
+}
+
+static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len)
+{
+    return memcmp(s1, (const char *)s2, len) == 0;
+}
+
+static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen,
+                                       bool *result, CborValue *next, IterateFunction func)
+{
+    assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
+
+    size_t total;
+    CborError err;
+    const uint8_t *ptr = value->ptr;
+    if (cbor_value_is_length_known(value)) {
+        /* easy case: fixed length */
+        err = extract_length(value->parser, &ptr, &total);
+        if (err)
+            return err;
+        if (total > (size_t)(value->parser->end - ptr))
+            return CborErrorUnexpectedEOF;
+        if (total <= *buflen)
+            *result = !!func(buffer, ptr, total);
+        else
+            *result = false;
+        ptr += total;
+    } else {
+        /* chunked */
+        ++ptr;
+        total = 0;
+        *result = true;
+        while (true) {
+            size_t chunkLen;
+            size_t newTotal;
+
+            if (ptr == value->parser->end)
+                return CborErrorUnexpectedEOF;
+
+            if (*ptr == (uint8_t)BreakByte) {
+                ++ptr;
+                break;
+            }
+
+            /* is this the right type? */
+            if ((*ptr & MajorTypeMask) != value->type)
+                return CborErrorIllegalType;
+
+            err = extract_length(value->parser, &ptr, &chunkLen);
+            if (err)
+                return err;
+
+            if (unlikely(add_check_overflow(total, chunkLen, &newTotal)))
+                return CborErrorDataTooLarge;
+
+            if (chunkLen > (size_t)(value->parser->end - ptr))
+                return CborErrorUnexpectedEOF;
+
+            if (*result && *buflen >= newTotal)
+                *result = !!func(buffer + total, ptr, chunkLen);
+            else
+                *result = false;
+
+            ptr += chunkLen;
+            total = newTotal;
+        }
+    }
+
+    /* is there enough room for the ending NUL byte? */
+    if (*result && *buflen > total)
+        *result = !!func(buffer + total, (const uint8_t *)"", 1);
+    *buflen = total;
+
+    if (next) {
+        *next = *value;
+        next->ptr = ptr;
+        return preparse_next_value(next);
+    }
+    return CborNoError;
+}
+
+/**
+ * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next)
+ *
+ * Copies the string pointed by \a value into the buffer provided at \a buffer
+ * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
+ * copy anything and will only update the \a next value.
+ *
+ * If the iterator \a value does not point to a text string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_text_string is recommended.
+ *
+ * If the provided buffer length was too small, this function returns an error
+ * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
+ * of the string in order to preallocate a buffer, use
+ * cbor_value_calculate_string_length().
+ *
+ * On success, this function sets the number of bytes copied to \c{*buflen}. If
+ * the buffer is large enough, this function will insert a null byte after the
+ * last copied byte, to facilitate manipulation of text strings. That byte is
+ * not included in the returned value of \c{*buflen}.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \note This function does not perform UTF-8 validation on the incoming text
+ * string.
+ *
+ * \sa cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
+ */
+
+/**
+ * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next)
+ *
+ * Copies the string pointed by \a value into the buffer provided at \a buffer
+ * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not
+ * copy anything and will only update the \a next value.
+ *
+ * If the iterator \a value does not point to a byte string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * If the provided buffer length was too small, this function returns an error
+ * condition of \ref CborErrorOutOfMemory. If you need to calculate the length
+ * of the string in order to preallocate a buffer, use
+ * cbor_value_calculate_string_length().
+ *
+ * On success, this function sets the number of bytes copied to \c{*buflen}. If
+ * the buffer is large enough, this function will insert a null byte after the
+ * last copied byte, to facilitate manipulation of null-terminated strings.
+ * That byte is not included in the returned value of \c{*buflen}.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \sa cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length()
+ */
+
+CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
+                                 size_t *buflen, CborValue *next)
+{
+    bool copied_all;
+    CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next,
+                                          buffer ? (IterateFunction)memcpy : iterate_noop);
+    return err ? err :
+                 copied_all ? CborNoError : CborErrorOutOfMemory;
+}
+
+/**
+ * Compares the entry \a value with the string \a string and store the result
+ * in \a result. If the value is different from \a string \a result will
+ * contain \c false.
+ *
+ * The entry at \a value may be a tagged string. If \a is not a string or a
+ * tagged string, the comparison result will be false.
+ *
+ * CBOR requires text strings to be encoded in UTF-8, but this function does
+ * not validate either the strings in the stream or the string \a string to be
+ * matched. Moreover, comparison is done on strict codepoint comparison,
+ * without any Unicode normalization.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)).
+ *
+ * \sa cbor_value_skip_tag(), cbor_value_copy_text_string()
+ */
+CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result)
+{
+    CborValue copy = *value;
+    CborError err = cbor_value_skip_tag(&copy);
+    if (err)
+        return err;
+    if (!cbor_value_is_text_string(&copy)) {
+        *result = false;
+        return CborNoError;
+    }
+
+    size_t len = strlen(string);
+    return iterate_string_chunks(&copy, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp);
+}
+
+/**
+ * \fn bool cbor_value_is_array(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR array.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_map()
+ */
+
+/**
+ * \fn CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the CBOR array that \a value points to and stores it
+ * in \a result. If the iterator \a value does not point to a CBOR array, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_array is recommended.
+ *
+ * If the length of this array is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known()
+ */
+
+/**
+ * \fn bool cbor_value_is_map(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR map.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_array()
+ */
+
+/**
+ * \fn CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
+ *
+ * Extracts the length of the CBOR map that \a value points to and stores it in
+ * \a result. If the iterator \a value does not point to a CBOR map, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_map is recommended.
+ *
+ * If the length of this map is not encoded in the CBOR data stream, this
+ * function will return the recoverable error CborErrorUnknownLength. You may
+ * also check whether that is the case by using cbor_value_is_length_known().
+ *
+ * \note On 32-bit platforms, this function will return error condition of \ref
+ * CborErrorDataTooLarge if the stream indicates a length that is too big to
+ * fit in 32-bit.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_length_known()
+ */
+
+/**
+ * Attempts to find the value in map \a map that corresponds to the text string
+ * entry \a string. If the iterator \a value does not point to a CBOR map, the
+ * behaviour is undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_map is recommended.
+ *
+ * If the item is found, it is stored in \a result. If no item is found
+ * matching the key, then \a result will contain an element of type \ref
+ * CborInvalidType. Matching is performed using
+ * cbor_value_text_string_equals(), so tagged strings will also match.
+ *
+ * This function has a time complexity of O(n) where n is the number of
+ * elements in the map to be searched. In addition, this function is has O(n)
+ * memory requirement based on the number of nested containers (maps or arrays)
+ * found as elements of this map.
+ *
+ * \sa cbor_value_is_valid(), cbor_value_text_string_equals(), cbor_value_advance()
+ */
+CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element)
+{
+    assert(cbor_value_is_map(map));
+    size_t len = strlen(string);
+    CborError err = cbor_value_enter_container(map, element);
+    if (err)
+        goto error;
+
+    while (!cbor_value_at_end(element)) {
+        /* find the non-tag so we can compare */
+        err = cbor_value_skip_tag(element);
+        if (err)
+            goto error;
+        if (cbor_value_is_text_string(element)) {
+            bool equals;
+            size_t dummyLen = len;
+            err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen,
+                                        &equals, element, iterate_memcmp);
+            if (err)
+                goto error;
+            if (equals)
+                return preparse_value(element);
+        } else {
+            /* skip this key */
+            err = cbor_value_advance(element);
+            if (err)
+                goto error;
+        }
+
+        /* skip this value */
+        err = cbor_value_skip_tag(element);
+        if (err)
+            goto error;
+        err = cbor_value_advance(element);
+        if (err)
+            goto error;
+    }
+
+    /* not found */
+    element->type = CborInvalidType;
+    return CborNoError;
+
+error:
+    element->type = CborInvalidType;
+    return err;
+}
+
+/**
+ * \fn bool cbor_value_is_float(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * single-precision floating point (32-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_half_float()
+ */
+
+/**
+ * \fn CborError cbor_value_get_float(const CborValue *value, float *result)
+ *
+ * Retrieves the CBOR single-precision floating point (32-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a single-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_float is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_float(), cbor_value_get_double()
+ */
+
+/**
+ * \fn bool cbor_value_is_double(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * double-precision floating point (64-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_float(), cbor_value_is_half_float()
+ */
+
+/**
+ * \fn CborError cbor_value_get_double(const CborValue *value, float *result)
+ *
+ * Retrieves the CBOR double-precision floating point (64-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a double-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_double is recommended.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_double(), cbor_value_get_float()
+ */
+
+/**
+ * \fn bool cbor_value_is_half_float(const CborValue *value)
+ *
+ * Returns true if the iterator \a value is valid and points to a CBOR
+ * single-precision floating point (16-bit).
+ *
+ * \sa cbor_value_is_valid(), cbor_value_is_double(), cbor_value_is_float()
+ */
+
+/**
+ * Retrieves the CBOR half-precision floating point (16-bit) value that \a
+ * value points to and stores it in \a result. If the iterator \a value does
+ * not point to a half-precision floating point value, the behavior is
+ * undefined, so checking with \ref cbor_value_get_type or with \ref
+ * cbor_value_is_half_float is recommended.
+ *
+ * Note: since the C language does not have a standard type for half-precision
+ * floating point, this function takes a \c{void *} as a parameter for the
+ * storage area, which must be at least 16 bits wide.
+ *
+ * \sa cbor_value_get_type(), cbor_value_is_valid(), cbor_value_is_half_float(), cbor_value_get_float()
+ */
+CborError cbor_value_get_half_float(const CborValue *value, void *result)
+{
+    assert(cbor_value_is_half_float(value));
+
+    /* size has been computed already */
+    uint16_t v = get16(value->ptr + 1);
+    memcpy(result, &v, sizeof(v));
+    return CborNoError;
+}
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborparser_dup_string.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborparser_dup_string.c b/libs/tinycbor/src/cborparser_dup_string.c
new file mode 100644
index 0000000..60dbdbe
--- /dev/null
+++ b/libs/tinycbor/src/cborparser_dup_string.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include <stdlib.h>
+
+/**
+ * \fn CborError cbor_value_dup_text_string(const CborValue *value, char **buffer, size_t *buflen, CborValue *next)
+ *
+ * Allocates memory for the string pointed by \a value and copies it into this
+ * buffer. The pointer to the buffer is stored in \a buffer and the number of
+ * bytes copied is stored in \a len (those variables must not be NULL).
+ *
+ * If the iterator \a value does not point to a text string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_text_string is recommended.
+ *
+ * If \c malloc returns a NULL pointer, this function will return error
+ * condition \ref CborErrorOutOfMemory.
+ *
+ * On success, \c{*buffer} will contain a valid pointer that must be freed by
+ * calling \c{free()}. This is the case even for zero-length strings.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)) in addition to the
+ * malloc'ed block.
+ *
+ * \note This function does not perform UTF-8 validation on the incoming text
+ * string.
+ *
+ * \sa cbor_value_copy_text_string(), cbor_value_dup_byte_string()
+ */
+
+/**
+ * \fn CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer, size_t *buflen, CborValue *next)
+ *
+ * Allocates memory for the string pointed by \a value and copies it into this
+ * buffer. The pointer to the buffer is stored in \a buffer and the number of
+ * bytes copied is stored in \a len (those variables must not be NULL).
+ *
+ * If the iterator \a value does not point to a byte string, the behaviour is
+ * undefined, so checking with \ref cbor_value_get_type or \ref
+ * cbor_value_is_byte_string is recommended.
+ *
+ * If \c malloc returns a NULL pointer, this function will return error
+ * condition \ref CborErrorOutOfMemory.
+ *
+ * On success, \c{*buffer} will contain a valid pointer that must be freed by
+ * calling \c{free()}. This is the case even for zero-length strings.
+ *
+ * The \a next pointer, if not null, will be updated to point to the next item
+ * after this string. If \a value points to the last item, then \a next will be
+ * invalid.
+ *
+ * This function may not run in constant time (it will run in O(n) time on the
+ * number of chunks). It requires constant memory (O(1)) in addition to the
+ * malloc'ed block.
+ *
+ * \sa cbor_value_copy_byte_string(), cbor_value_dup_text_string()
+ */
+CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next)
+{
+    assert(buffer);
+    assert(buflen);
+    *buflen = SIZE_MAX;
+    CborError err = _cbor_value_copy_string(value, NULL, buflen, NULL);
+    if (err)
+        return err;
+
+    ++*buflen;
+    *buffer = malloc(*buflen);
+    if (!*buffer) {
+        /* out of memory */
+        return CborErrorOutOfMemory;
+    }
+    err = _cbor_value_copy_string(value, *buffer, buflen, next);
+    if (err) {
+        free(*buffer);
+        return err;
+    }
+    return CborNoError;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborpretty.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborpretty.c b/libs/tinycbor/src/cborpretty.c
new file mode 100644
index 0000000..e8e7316
--- /dev/null
+++ b/libs/tinycbor/src/cborpretty.c
@@ -0,0 +1,470 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "compilersupport_p.h"
+#include "math_support_p.h"
+
+#include <float.h>
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * \defgroup CborPretty Converting CBOR to text
+ * \brief Group of functions used to convert CBOR to text form.
+ *
+ * This group contains two functions that are can be used to convert one
+ * CborValue object to a text representation. This module attempts to follow
+ * the recommendations from RFC 7049 section 6 "Diagnostic Notation", though it
+ * has a few differences. They are noted below.
+ *
+ * TinyCBOR does not provide a way to convert from the text representation back
+ * to encoded form. To produce a text form meant to be parsed, CborToJson is
+ * recommended instead.
+ *
+ * Either of the functions in this section will attempt to convert exactly one
+ * CborValue object to text. Those functions may return any error documented
+ * for the functions for CborParsing. In addition, if the C standard library
+ * stream functions return with error, the text conversion will return with
+ * error CborErrorIO.
+ *
+ * These functions also perform UTF-8 validation in CBOR text strings. If they
+ * encounter a sequence of bytes that not permitted in UTF-8, they will return
+ * CborErrorInvalidUtf8TextString. That includes encoding of surrogate points
+ * in UTF-8.
+ *
+ * \warning The output type produced by these functions is not guaranteed to
+ * remain stable. A future update of TinyCBOR may produce different output for
+ * the same input and parsers may be unable to handle them.
+ *
+ * \sa CborParsing, CborToJson, cbor_parser_init()
+ */
+
+/**
+ * \addtogroup CborPretty
+ * @{
+ * <h2 class="groupheader">Text format</h2>
+ *
+ * As described in RFC 7049 section 6 "Diagnostic Notation", the format is
+ * largely borrowed from JSON, but modified to suit CBOR's different data
+ * types. TinyCBOR makes further modifications to distinguish different, but
+ * similar values.
+ *
+ * CBOR values are currently encoded as follows:
+ * \par Integrals (unsigned and negative)
+ *      Base-10 (decimal) text representation of the value
+ * \par Byte strings:
+ *      <tt>"h'"</tt> followed by the Base16 (hex) representation of the binary data, followed by an ending quote (')
+ * \par Text strings:
+ *      C-style escaped string in quotes, with C11/C++11 escaping of Unicode codepoints above U+007F.
+ * \par Tags:
+ *      Tag value, with the tagged value in parentheses. No special encoding of the tagged value is performed.
+ * \par Simple types:
+ *      <tt>"simple(nn)"</tt> where \c nn is the simple value
+ * \par Null:
+ *      \c null
+ * \par Undefined:
+ *      \c undefined
+ * \par Booleans:
+ *      \c true or \c false
+ * \par Floating point:
+ *      If NaN or infinite, the actual words \c NaN or \c infinite.
+ *      Otherwise, the decimal representation with as many digits as necessary to ensure no loss of information,
+ *      with float values suffixed by "f" and half-float values suffixed by "f16" (doubles have no suffix). A dot is always present.
+ * \par Arrays:
+ *      Comma-separated list of elements, enclosed in square brackets ("[" and "]").
+ *     If the array length is indeterminate, an underscore ("_") appears immediately after the opening bracket.
+ * \par Maps:
+ *      Comma-separated list of key-value pairs, with the key and value separated
+ *      by a colon (":"), enclosed in curly braces ("{" and "}").
+ *      If the map length is indeterminate, an underscore ("_") appears immediately after the opening brace.
+ */
+
+static int hexDump(FILE *out, const uint8_t *buffer, size_t n)
+{
+    while (n--) {
+        int r = fprintf(out, "%02" PRIx8, *buffer++);
+        if (r < 0)
+            return r;
+    }
+    return 0;   /* should be n * 2, but we don't have the original n anymore */
+}
+
+/* This function decodes buffer as UTF-8 and prints as escaped UTF-16.
+ * On UTF-8 decoding error, it returns CborErrorInvalidUtf8TextString */
+static int utf8EscapedDump(FILE *out, const char *buffer, size_t n)
+{
+    uint32_t uc;
+    while (n--) {
+        uc = (uint8_t)*buffer++;
+        if (uc < 0x80) {
+            /* single-byte UTF-8 */
+            if (uc < 0x7f && uc >= 0x20 && uc != '\\' && uc != '"') {
+                if (fprintf(out, "%c", (char)uc) < 0)
+                    return CborErrorIO;
+                continue;
+            }
+
+            /* print as an escape sequence */
+            char escaped = (char)uc;
+            switch (uc) {
+            case '"':
+            case '\\':
+                break;
+            case '\b':
+                escaped = 'b';
+                break;
+            case '\f':
+                escaped = 'f';
+                break;
+            case '\n':
+                escaped = 'n';
+                break;
+            case '\r':
+                escaped = 'r';
+                break;
+            case '\t':
+                escaped = 't';
+                break;
+            default:
+                goto print_utf16;
+            }
+            if (fprintf(out, "\\%c", escaped) < 0)
+                return CborErrorIO;
+            continue;
+        }
+
+        /* multi-byte UTF-8, decode it */
+        unsigned charsNeeded;
+        uint32_t min_uc;
+        if (unlikely(uc <= 0xC1))
+            return CborErrorInvalidUtf8TextString;
+        if (uc < 0xE0) {
+            /* two-byte UTF-8 */
+            charsNeeded = 2;
+            min_uc = 0x80;
+            uc &= 0x1f;
+        } else if (uc < 0xF0) {
+            /* three-byte UTF-8 */
+            charsNeeded = 3;
+            min_uc = 0x800;
+            uc &= 0x0f;
+        } else if (uc < 0xF5) {
+            /* four-byte UTF-8 */
+            charsNeeded = 4;
+            min_uc = 0x10000;
+            uc &= 0x07;
+        } else {
+            return CborErrorInvalidUtf8TextString;
+        }
+
+        if (n < charsNeeded - 1)
+            return CborErrorInvalidUtf8TextString;
+
+        /* first continuation character */
+        uint8_t b = (uint8_t)*buffer++;
+        if ((b & 0xc0) != 0x80)
+            return CborErrorInvalidUtf8TextString;
+        uc <<= 6;
+        uc |= b & 0x3f;
+
+        if (charsNeeded > 2) {
+            /* second continuation character */
+            b = (uint8_t)*buffer++;
+            if ((b & 0xc0) != 0x80)
+                return CborErrorInvalidUtf8TextString;
+            uc <<= 6;
+            uc |= b & 0x3f;
+
+            if (charsNeeded > 3) {
+                /* third continuation character */
+                b = (uint8_t)*buffer++;
+                if ((b & 0xc0) != 0x80)
+                    return CborErrorInvalidUtf8TextString;
+                uc <<= 6;
+                uc |= b & 0x3f;
+            }
+        }
+
+        /* overlong sequence? surrogate pair? out or range? */
+        if (uc < min_uc || uc - 0xd800U < 2048U || uc > 0x10ffff)
+            return CborErrorInvalidUtf8TextString;
+
+        /* now print the sequence */
+        if (charsNeeded > 3) {
+            /* needs surrogate pairs */
+            if (fprintf(out, "\\u%04" PRIX32 "\\u%04" PRIX32,
+                        (uc >> 10) + 0xd7c0,    /* high surrogate */
+                        (uc % 0x0400) + 0xdc00) < 0)
+                return CborErrorIO;
+        } else {
+print_utf16:
+            /* no surrogate pair needed */
+            if (fprintf(out, "\\u%04" PRIX32, uc) < 0)
+                return CborErrorIO;
+        }
+    }
+    return CborNoError;
+}
+
+static CborError value_to_pretty(FILE *out, CborValue *it);
+static CborError container_to_pretty(FILE *out, CborValue *it, CborType containerType)
+{
+    const char *comma = "";
+    while (!cbor_value_at_end(it)) {
+        if (fprintf(out, "%s", comma) < 0)
+            return CborErrorIO;
+        comma = ", ";
+
+        CborError err = value_to_pretty(out, it);
+        if (err)
+            return err;
+
+        if (containerType == CborArrayType)
+            continue;
+
+        /* map: that was the key, so get the value */
+        if (fprintf(out, ": ") < 0)
+            return CborErrorIO;
+        err = value_to_pretty(out, it);
+        if (err)
+            return err;
+    }
+    return CborNoError;
+}
+
+static CborError value_to_pretty(FILE *out, CborValue *it)
+{
+    CborError err;
+    CborType type = cbor_value_get_type(it);
+    switch (type) {
+    case CborArrayType:
+    case CborMapType: {
+        /* recursive type */
+        CborValue recursed;
+
+        if (fprintf(out, type == CborArrayType ? "[" : "{") < 0)
+            return CborErrorIO;
+        if (!cbor_value_is_length_known(it)) {
+            if (fprintf(out, "_ ") < 0)
+                return CborErrorIO;
+        }
+
+        err = cbor_value_enter_container(it, &recursed);
+        if (err) {
+            it->ptr = recursed.ptr;
+            return err;       /* parse error */
+        }
+        err = container_to_pretty(out, &recursed, type);
+        if (err) {
+            it->ptr = recursed.ptr;
+            return err;       /* parse error */
+        }
+        err = cbor_value_leave_container(it, &recursed);
+        if (err)
+            return err;       /* parse error */
+
+        if (fprintf(out, type == CborArrayType ? "]" : "}") < 0)
+            return CborErrorIO;
+        return CborNoError;
+    }
+
+    case CborIntegerType: {
+        uint64_t val;
+        cbor_value_get_raw_integer(it, &val);    /* can't fail */
+
+        if (cbor_value_is_unsigned_integer(it)) {
+            if (fprintf(out, "%" PRIu64, val) < 0)
+                return CborErrorIO;
+        } else {
+            /* CBOR stores the negative number X as -1 - X
+             * (that is, -1 is stored as 0, -2 as 1 and so forth) */
+            if (++val) {                /* unsigned overflow may happen */
+                if (fprintf(out, "-%" PRIu64, val) < 0)
+                    return CborErrorIO;
+            } else {
+                /* overflown
+                 *   0xffff`ffff`ffff`ffff + 1 =
+                 * 0x1`0000`0000`0000`0000 = 18446744073709551616 (2^64) */
+                if (fprintf(out, "-18446744073709551616") < 0)
+                    return CborErrorIO;
+            }
+        }
+        break;
+    }
+
+    case CborByteStringType:{
+        size_t n = 0;
+        uint8_t *buffer;
+        err = cbor_value_dup_byte_string(it, &buffer, &n, it);
+        if (err)
+            return err;
+
+        bool failed = fprintf(out, "h'") < 0 || hexDump(out, buffer, n) < 0 || fprintf(out, "'") < 0;
+        free(buffer);
+        return failed ? CborErrorIO : CborNoError;
+    }
+
+    case CborTextStringType: {
+        size_t n = 0;
+        char *buffer;
+        err = cbor_value_dup_text_string(it, &buffer, &n, it);
+        if (err)
+            return err;
+
+        err = CborNoError;
+        bool failed = fprintf(out, "\"") < 0
+                      || (err = utf8EscapedDump(out, buffer, n)) != CborNoError
+                      || fprintf(out, "\"") < 0;
+        free(buffer);
+        return err != CborNoError ? err :
+                                    failed ? CborErrorIO : CborNoError;
+    }
+
+    case CborTagType: {
+        CborTag tag;
+        cbor_value_get_tag(it, &tag);       /* can't fail */
+        if (fprintf(out, "%" PRIu64 "(", tag) < 0)
+            return CborErrorIO;
+        err = cbor_value_advance_fixed(it);
+        if (err)
+            return err;
+        err = value_to_pretty(out, it);
+        if (err)
+            return err;
+        if (fprintf(out, ")") < 0)
+            return CborErrorIO;
+        return CborNoError;
+    }
+
+    case CborSimpleType: {
+        uint8_t simple_type;
+        cbor_value_get_simple_type(it, &simple_type);  /* can't fail */
+        if (fprintf(out, "simple(%" PRIu8 ")", simple_type) < 0)
+            return CborErrorIO;
+        break;
+    }
+
+    case CborNullType:
+        if (fprintf(out, "null") < 0)
+            return CborErrorIO;
+        break;
+
+    case CborUndefinedType:
+        if (fprintf(out, "undefined") < 0)
+            return CborErrorIO;
+        break;
+
+    case CborBooleanType: {
+        bool val;
+        cbor_value_get_boolean(it, &val);       /* can't fail */
+        if (fprintf(out, val ? "true" : "false") < 0)
+            return CborErrorIO;
+        break;
+    }
+
+    case CborDoubleType: {
+        const char *suffix;
+        double val;
+        if (false) {
+            float f;
+    case CborFloatType:
+            cbor_value_get_float(it, &f);
+            val = f;
+            suffix = "f";
+        } else if (false) {
+            uint16_t f16;
+    case CborHalfFloatType:
+            cbor_value_get_half_float(it, &f16);
+            val = decode_half(f16);
+            suffix = "f16";
+        } else {
+            cbor_value_get_double(it, &val);
+            suffix = "";
+        }
+
+        int r = fpclassify(val);
+        if (r == FP_NAN || r == FP_INFINITE)
+            suffix = "";
+
+        uint64_t ival = (uint64_t)fabs(val);
+        if (ival == fabs(val)) {
+            /* this double value fits in a 64-bit integer, so show it as such
+             * (followed by a floating point suffix, to disambiguate) */
+            r = fprintf(out, "%s%" PRIu64 ".%s", val < 0 ? "-" : "", ival, suffix);
+        } else {
+            /* this number is definitely not a 64-bit integer */
+            r = fprintf(out, "%." DBL_DECIMAL_DIG_STR "g%s", val, suffix);
+        }
+        if (r < 0)
+            return CborErrorIO;
+        break;
+    }
+
+    case CborInvalidType:
+        if (fprintf(out, "invalid") < 0)
+            return CborErrorIO;
+        return CborErrorUnknownType;
+    }
+
+    err = cbor_value_advance_fixed(it);
+    return err;
+}
+
+/**
+ * \fn CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
+ *
+ * Converts the current CBOR type pointed by \a value to its textual
+ * representation and writes it to the \a out stream. If an error occurs, this
+ * function returns an error code similar to CborParsing.
+ *
+ * \sa cbor_value_to_pretty_advance(), cbor_value_to_json_advance()
+ */
+
+/**
+ * Converts the current CBOR type pointed by \a value to its textual
+ * representation and writes it to the \a out stream. If an error occurs, this
+ * function returns an error code similar to CborParsing.
+ *
+ * If no error ocurred, this function advances \a value to the next element.
+ * Often, concatenating the text representation of multiple elements can be
+ * done by appending a comma to the output stream.
+ *
+ * \sa cbor_value_to_pretty(), cbor_value_to_json_advance()
+ */
+CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value)
+{
+    return value_to_pretty(out, value);
+}
+
+/** @} */


[06/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_dtls.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_dtls.c b/libs/iotivity/src/security/oc_dtls.c
new file mode 100644
index 0000000..fdd0249
--- /dev/null
+++ b/libs/iotivity/src/security/oc_dtls.c
@@ -0,0 +1,372 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_dtls.h"
+#include "api/oc_events.h"
+#include "config.h"
+#include "oc_acl.h"
+#include "oc_buffer.h"
+#include "oc_core_res.h"
+#include "oc_cred.h"
+#include "oc_pstat.h"
+#include "oc_svr.h"
+
+OC_PROCESS(oc_dtls_handler, "DTLS Process");
+OC_MEMB(dtls_peers_s, oc_sec_dtls_peer_t, MAX_DTLS_PEERS);
+OC_LIST(dtls_peers);
+
+static dtls_context_t *ocf_dtls_context;
+
+oc_sec_dtls_peer_t *
+oc_sec_dtls_get_peer(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *peer = oc_list_head(dtls_peers);
+  while (peer != NULL) {
+    if (memcmp(&peer->session.addr, endpoint, sizeof(oc_endpoint_t)) == 0)
+      break;
+    peer = oc_list_item_next(peer);
+  }
+  return peer;
+}
+
+void
+oc_sec_dtls_remove_peer(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(endpoint);
+  if (peer) {
+    LOG("\n\noc_sec_dtls: removed peer\n\n");
+    oc_list_remove(dtls_peers, peer);
+    oc_memb_free(&dtls_peers_s, peer);
+  }
+}
+
+oc_event_callback_retval_t
+oc_sec_dtls_inactive(void *data)
+{
+  LOG("\n\noc_sec_dtls: DTLS inactivity callback\n\n");
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(data);
+  if (peer) {
+    oc_clock_time_t time = oc_clock_time();
+    time -= peer->timestamp;
+    if (time < DTLS_INACTIVITY_TIMEOUT * OC_CLOCK_SECOND) {
+      LOG("\n\noc_sec_dtls: Resetting DTLS inactivity callback\n\n");
+      return CONTINUE;
+    } else if (time < 2 * DTLS_INACTIVITY_TIMEOUT * OC_CLOCK_SECOND) {
+      LOG("\n\noc_sec_dtls: Initiating connection close\n\n");
+      oc_sec_dtls_close_init(data);
+      return CONTINUE;
+    } else {
+      LOG("\n\noc_sec_dtls: Completing connection close\n\n");
+      oc_sec_dtls_close_finish(data);
+    }
+  } else {
+    LOG("\n\noc_sec_dtls: Could not find peer\n\n");
+    LOG("oc_sec_dtls: Num active peers %d\n", oc_list_length(dtls_peers));
+  }
+  LOG("\n\noc_sec_dtls: Terminating DTLS inactivity callback\n\n");
+  return DONE;
+}
+
+oc_sec_dtls_peer_t *
+oc_sec_dtls_add_peer(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(endpoint);
+  if (!peer) {
+    peer = oc_memb_alloc(&dtls_peers_s);
+    if (peer) {
+      LOG("\n\noc_sec_dtls: Allocating new DTLS peer\n\n");
+      memcpy(&peer->session.addr, endpoint, sizeof(oc_endpoint_t));
+      peer->session.size = sizeof(oc_endpoint_t);
+      OC_LIST_STRUCT_INIT(peer, send_queue);
+      peer->connected = false;
+      oc_list_add(dtls_peers, peer);
+
+      oc_ri_add_timed_event_callback_seconds(
+        &peer->session.addr, oc_sec_dtls_inactive, DTLS_INACTIVITY_TIMEOUT);
+    }
+  }
+  return peer;
+}
+
+bool
+oc_sec_dtls_connected(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(endpoint);
+  if (peer)
+    return peer->connected;
+  return false;
+}
+
+oc_uuid_t *
+oc_sec_dtls_get_peer_uuid(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(endpoint);
+  if (peer) {
+    return &peer->uuid;
+  }
+  return NULL;
+}
+
+/*
+  Called back from DTLS state machine following decryption so
+  application can read incoming message.
+  Following function packages up incoming data into a messaage
+  to forward up to CoAP
+*/
+static int
+oc_sec_dtls_get_decrypted_message(struct dtls_context_t *ctx,
+                                  session_t *session, uint8_t *buf, size_t len)
+{
+  oc_message_t *message = oc_allocate_message();
+  if (message) {
+    memcpy(&message->endpoint, &session->addr, sizeof(oc_endpoint_t));
+    memcpy(message->data, buf, len);
+    message->length = len;
+    oc_recv_message(message);
+  }
+  return 0;
+}
+
+void
+oc_sec_dtls_init_connection(oc_message_t *message)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_add_peer(&message->endpoint);
+  if (peer) {
+    LOG("\n\noc_dtls: Initializing DTLS connection\n\n");
+    dtls_connect(ocf_dtls_context, &peer->session);
+    oc_list_add(peer->send_queue, message);
+  } else
+    oc_message_unref(message);
+}
+
+/*
+  Called from app layer via buffer.c to post OCF responses...
+  Message routed to this function on spoting SECURE flag in
+  endpoint structure. This would've already been set on receipt
+  of the request (to which this the current message is the response)
+  We call dtls_write(...) to feed response data through the
+  DTLS state machine leading up to the encrypted send callback below.
+
+  Message sent here may have been flagged to get freed OR
+  may have been stored for retransmissions.
+*/
+int
+oc_sec_dtls_send_message(oc_message_t *message)
+{
+  int ret = 0;
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(&message->endpoint);
+  if (peer) {
+    ret = dtls_write(ocf_dtls_context, &peer->session, message->data,
+                     message->length);
+  }
+  oc_message_unref(message);
+  return ret;
+}
+
+/*
+  Called back from DTLS state machine when it is ready to send
+  an encrypted response to the remote endpoint.
+  Construct a new oc_message for this purpose and call oc_send_buffer
+  to send this message over the wire.
+*/
+static int
+oc_sec_dtls_send_encrypted_message(struct dtls_context_t *ctx,
+                                   session_t *session, uint8_t *buf, size_t len)
+{
+  oc_message_t message;
+  memcpy(&message.endpoint, &session->addr, sizeof(oc_endpoint_t));
+  memcpy(message.data, buf, len);
+  message.length = len;
+  oc_send_buffer(&message);
+  return len;
+}
+
+/*
+  This is called once during the handshake process over normal
+  operation.
+  OwnerPSK woud've been generated previously during provisioning.
+*/
+static int
+oc_sec_dtls_get_owner_psk(struct dtls_context_t *ctx, const session_t *session,
+                          dtls_credentials_type_t type,
+                          const unsigned char *desc, size_t desc_len,
+                          unsigned char *result, size_t result_length)
+{
+  switch (type) {
+  case DTLS_PSK_IDENTITY:
+  case DTLS_PSK_HINT: {
+    LOG("Identity\n");
+    oc_uuid_t *uuid = oc_core_get_device_id(0);
+    memcpy(result, uuid->id, 16);
+    return 16;
+  } break;
+  case DTLS_PSK_KEY: {
+    LOG("key\n");
+    oc_sec_cred_t *cred = oc_sec_find_cred((oc_uuid_t *)desc);
+    oc_sec_dtls_peer_t *peer =
+      oc_sec_dtls_get_peer((oc_endpoint_t *)&session->addr);
+    if (cred != NULL && peer != NULL) {
+      memcpy(&peer->uuid, (oc_uuid_t *)desc, 16);
+      memcpy(result, cred->key, 16);
+      return 16;
+    }
+    return 0;
+  } break;
+  default:
+    break;
+  }
+  return 0;
+}
+
+int
+oc_sec_dtls_events(struct dtls_context_t *ctx, session_t *session,
+                   dtls_alert_level_t level, unsigned short code)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(&session->addr);
+  if (peer && level == 0 && code == DTLS_EVENT_CONNECTED) {
+    peer->connected = true;
+    oc_message_t *m = oc_list_pop(peer->send_queue);
+    while (m != NULL) {
+      oc_sec_dtls_send_message(m);
+      m = oc_list_pop(peer->send_queue);
+    }
+  } else if (level == 2) {
+    oc_sec_dtls_close_finish(&session->addr);
+  }
+  return 0;
+}
+
+static dtls_handler_t dtls_cb = {.write = oc_sec_dtls_send_encrypted_message,
+                                 .read = oc_sec_dtls_get_decrypted_message,
+                                 .event = oc_sec_dtls_events,
+                                 .get_psk_info = oc_sec_dtls_get_owner_psk };
+
+void
+oc_sec_derive_owner_psk(oc_endpoint_t *endpoint, const char *oxm,
+                        const size_t oxm_len, const char *server_uuid,
+                        const size_t server_uuid_len, const char *obt_uuid,
+                        const size_t obt_uuid_len, uint8_t *key,
+                        const size_t key_len)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_get_peer(endpoint);
+  if (peer) {
+    dtls_prf_with_current_keyblock(
+      ocf_dtls_context, &peer->session, oxm, oxm_len, server_uuid,
+      server_uuid_len, obt_uuid, obt_uuid_len, (uint8_t *)key, key_len);
+  }
+}
+
+/*
+  Message received from the wire, routed here via buffer.c
+  based on examination of the 1st byte proving it is DTLS.
+  Data sent to dtls_handle_message(...) for decryption.
+*/
+static void
+oc_sec_dtls_recv_message(oc_message_t *message)
+{
+  oc_sec_dtls_peer_t *peer = oc_sec_dtls_add_peer(&message->endpoint);
+  if (peer) {
+    int ret = dtls_handle_message(ocf_dtls_context, &peer->session,
+                                  message->data, message->length);
+    if (ret != 0) {
+      oc_sec_dtls_close_finish(&message->endpoint);
+    } else {
+      peer->timestamp = oc_clock_time();
+    }
+  }
+  oc_message_unref(message);
+}
+
+/* If not owned, select anon_ECDH cipher and enter ready for OTM state */
+/* If owned, enter ready for normal operation state */
+/* Fetch persisted SVR from app by this time */
+
+void
+oc_sec_dtls_init_context(void)
+{
+  dtls_init();
+  ocf_dtls_context = dtls_new_context(NULL);
+
+  if (oc_sec_provisioned()) {
+    LOG("\n\noc_sec_dtls: Device in normal operation state\n\n");
+    dtls_select_cipher(ocf_dtls_context, TLS_PSK_WITH_AES_128_CCM_8);
+  } else {
+    LOG("\n\noc_sec_dtls: Device in ready for OTM state\n\n");
+    dtls_enables_anon_ecdh(ocf_dtls_context, DTLS_CIPHER_ENABLE);
+  }
+  dtls_set_handler(ocf_dtls_context, &dtls_cb);
+}
+
+void
+oc_sec_dtls_close_init(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *p = oc_sec_dtls_get_peer(endpoint);
+  if (p) {
+    dtls_peer_t *peer = dtls_get_peer(ocf_dtls_context, &p->session);
+    if (peer) {
+      dtls_close(ocf_dtls_context, &p->session);
+      oc_message_t *m = oc_list_pop(p->send_queue);
+      while (m != NULL) {
+        LOG("\n\noc_sec_dtls: Freeing DTLS Peer send queue\n\n");
+        oc_message_unref(m);
+        m = oc_list_pop(p->send_queue);
+      }
+    }
+  }
+}
+
+void
+oc_sec_dtls_close_finish(oc_endpoint_t *endpoint)
+{
+  oc_sec_dtls_peer_t *p = oc_sec_dtls_get_peer(endpoint);
+  if (p) {
+    dtls_peer_t *peer = dtls_get_peer(ocf_dtls_context, &p->session);
+    if (peer) {
+      oc_list_remove(ocf_dtls_context->peers, peer);
+      dtls_free_peer(peer);
+    }
+    oc_message_t *m = oc_list_pop(p->send_queue);
+    while (m != NULL) {
+      LOG("\n\noc_sec_dtls: Freeing DTLS Peer send queue\n\n");
+      oc_message_unref(m);
+      m = oc_list_pop(p->send_queue);
+    }
+    oc_sec_dtls_remove_peer(endpoint);
+  }
+}
+
+OC_PROCESS_THREAD(oc_dtls_handler, ev, data)
+{
+  OC_PROCESS_BEGIN();
+
+  while (1) {
+    OC_PROCESS_YIELD();
+
+    if (ev == oc_events[UDP_TO_DTLS_EVENT]) {
+      oc_sec_dtls_recv_message(data);
+    } else if (ev == oc_events[INIT_DTLS_CONN_EVENT]) {
+      oc_sec_dtls_init_connection(data);
+    } else if (ev == oc_events[RI_TO_DTLS_EVENT]) {
+      oc_sec_dtls_send_message(data);
+    }
+  }
+
+  OC_PROCESS_END();
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_dtls.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_dtls.h b/libs/iotivity/src/security/oc_dtls.h
new file mode 100644
index 0000000..5cb0aa0
--- /dev/null
+++ b/libs/iotivity/src/security/oc_dtls.h
@@ -0,0 +1,50 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_DTLS_H_
+#define OC_DTLS_H_
+
+#include "deps/tinydtls/dtls.h"
+#include "oc_uuid.h"
+#include "port/oc_connectivity.h"
+#include "util/oc_process.h"
+#include <stdbool.h>
+
+OC_PROCESS_NAME(oc_dtls_handler);
+
+void oc_sec_dtls_close_init(oc_endpoint_t *endpoint);
+void oc_sec_dtls_close_finish(oc_endpoint_t *endpoint);
+void oc_sec_derive_owner_psk(oc_endpoint_t *endpoint, const char *oxm,
+                             const size_t oxm_len, const char *server_uuid,
+                             const size_t server_uuid_len, const char *obt_uuid,
+                             const size_t obt_uuid_len, uint8_t *key,
+                             const size_t key_len);
+void oc_sec_dtls_init_context(void);
+int oc_sec_dtls_send_message(oc_message_t *message);
+oc_uuid_t *oc_sec_dtls_get_peer_uuid(oc_endpoint_t *endpoint);
+bool oc_sec_dtls_connected(oc_endpoint_t *endpoint);
+
+typedef struct oc_sec_dtls_peer_s
+{
+  struct oc_sec_dtls_peer_s *next;
+  OC_LIST_STRUCT(send_queue);
+  session_t session;
+  oc_uuid_t uuid;
+  bool connected;
+  oc_clock_time_t timestamp;
+} oc_sec_dtls_peer_t;
+
+#endif /* OC_DTLS_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_pstat.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_pstat.c b/libs/iotivity/src/security/oc_pstat.c
new file mode 100644
index 0000000..7e8a86d
--- /dev/null
+++ b/libs/iotivity/src/security/oc_pstat.c
@@ -0,0 +1,119 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_pstat.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+#include "oc_doxm.h"
+
+static oc_sec_pstat_t pstat;
+
+oc_sec_pstat_t *
+oc_sec_get_pstat(void)
+{
+  return &pstat;
+}
+
+bool
+oc_sec_provisioned(void)
+{
+  return pstat.isop;
+}
+
+void
+oc_sec_pstat_default(void)
+{
+  pstat.isop = false;
+  pstat.cm = 2;
+  pstat.tm = 0;
+  pstat.om = 3;
+  pstat.sm = 3;
+}
+
+void
+oc_sec_encode_pstat(void)
+{
+  char uuid[37];
+  oc_sec_doxm_t *doxm = oc_sec_get_doxm();
+  oc_rep_start_root_object();
+  oc_process_baseline_interface(oc_core_get_resource_by_index(OCF_SEC_PSTAT));
+  oc_rep_set_uint(root, cm, pstat.cm);
+  oc_rep_set_uint(root, tm, pstat.tm);
+  oc_rep_set_int(root, om, pstat.om);
+  oc_rep_set_int(root, sm, pstat.sm);
+  oc_rep_set_boolean(root, isop, pstat.isop);
+  oc_uuid_to_str(&doxm->deviceuuid, uuid, 37);
+  oc_rep_set_text_string(root, deviceuuid, uuid);
+  oc_uuid_to_str(&doxm->rowneruuid, uuid, 37);
+  oc_rep_set_text_string(root, rowneruuid, uuid);
+  oc_rep_end_root_object();
+}
+
+void
+oc_sec_decode_pstat(oc_rep_t *rep)
+{
+  oc_sec_doxm_t *doxm = oc_sec_get_doxm();
+  while (rep != NULL) {
+    switch (rep->type) {
+    case BOOL:
+      pstat.isop = rep->value_boolean;
+      break;
+    case INT:
+      if (strncmp(oc_string(rep->name), "cm", 2) == 0)
+        pstat.cm = rep->value_int;
+      else if (strncmp(oc_string(rep->name), "tm", 2) == 0)
+        pstat.tm = rep->value_int;
+      else if (strncmp(oc_string(rep->name), "om", 2) == 0)
+        pstat.om = rep->value_int;
+      else if (strncmp(oc_string(rep->name), "sm", 2) == 0)
+        pstat.sm = rep->value_int;
+      break;
+    case STRING:
+      if (strncmp(oc_string(rep->name), "deviceuuid", 10) == 0)
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm->deviceuuid);
+      else if (strncmp(oc_string(rep->name), "rowneruuid", 10) == 0)
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm->rowneruuid);
+      break;
+    default:
+      break;
+    }
+    rep = rep->next;
+  }
+}
+
+void
+get_pstat(oc_request_t *request, oc_interface_mask_t interface)
+{
+  switch (interface) {
+  case OC_IF_BASELINE: {
+    oc_sec_encode_pstat();
+    oc_send_response(request, OC_STATUS_OK);
+  } break;
+  default:
+    break;
+  }
+}
+
+void
+post_pstat(oc_request_t *request, oc_interface_mask_t interface)
+{
+  oc_sec_decode_pstat(request->request_payload);
+  oc_send_response(request, OC_STATUS_CHANGED);
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_pstat.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_pstat.h b/libs/iotivity/src/security/oc_pstat.h
new file mode 100644
index 0000000..77daa52
--- /dev/null
+++ b/libs/iotivity/src/security/oc_pstat.h
@@ -0,0 +1,39 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_PSTAT_H_
+#define OC_PSTAT_H_
+
+#include "oc_ri.h"
+
+typedef struct
+{
+  bool isop;
+  int cm;
+  int tm;
+  int om;
+  int sm;
+} oc_sec_pstat_t;
+
+bool oc_sec_provisioned(void);
+void oc_sec_decode_pstat(oc_rep_t *rep);
+void oc_sec_encode_pstat(void);
+oc_sec_pstat_t *oc_sec_get_pstat(void);
+void oc_sec_pstat_default(void);
+void get_pstat(oc_request_t *request, oc_interface_mask_t interface);
+void post_pstat(oc_request_t *request, oc_interface_mask_t interface);
+
+#endif /* OC_PSTAT_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_store.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_store.c b/libs/iotivity/src/security/oc_store.c
new file mode 100644
index 0000000..15f8cca
--- /dev/null
+++ b/libs/iotivity/src/security/oc_store.c
@@ -0,0 +1,158 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+#include "oc_store.h"
+#include "oc_acl.h"
+#include "oc_core_res.h"
+#include "oc_cred.h"
+#include "oc_doxm.h"
+#include "oc_pstat.h"
+#include "port/oc_storage.h"
+
+void
+oc_sec_load_doxm(void)
+{
+  long ret = 0;
+  size_t size = 512;
+  uint8_t buf[size];
+  oc_rep_t *rep;
+
+  if (oc_sec_provisioned()) {
+    ret = oc_storage_read("/doxm", buf, size);
+    if (ret > 0) {
+      oc_parse_rep(buf, ret, &rep);
+      oc_sec_decode_doxm(rep);
+      oc_free_rep(rep);
+    }
+  }
+
+  if (ret <= 0) {
+    oc_sec_doxm_default();
+  }
+
+  oc_uuid_t *deviceuuid = oc_core_get_device_id(0);
+  oc_sec_doxm_t *doxm = oc_sec_get_doxm();
+  memcpy(deviceuuid, &doxm->deviceuuid, sizeof(oc_uuid_t));
+}
+
+void
+oc_sec_load_pstat(void)
+{
+  long ret = 0;
+  size_t size = 512;
+  uint8_t buf[size];
+  oc_rep_t *rep;
+
+  ret = oc_storage_read("/pstat", buf, size);
+  if (ret > 0) {
+    oc_parse_rep(buf, ret, &rep);
+    oc_sec_decode_pstat(rep);
+    oc_free_rep(rep);
+  }
+
+  if (ret <= 0) {
+    oc_sec_pstat_default();
+  }
+}
+
+void
+oc_sec_load_cred(void)
+{
+  long ret = 0;
+  size_t size = 1024;
+  uint8_t buf[size];
+  oc_rep_t *rep;
+
+  if (oc_sec_provisioned()) {
+    ret = oc_storage_read("/cred", buf, size);
+
+    if (ret <= 0)
+      return;
+
+    oc_parse_rep(buf, ret, &rep);
+    oc_sec_decode_cred(rep, NULL);
+    oc_free_rep(rep);
+  }
+}
+
+void
+oc_sec_load_acl(void)
+{
+  size_t size = 1024;
+  long ret = 0;
+  uint8_t buf[size];
+  oc_rep_t *rep;
+
+  oc_sec_acl_init();
+
+  if (oc_sec_provisioned()) {
+    ret = oc_storage_read("/acl", buf, size);
+    if (ret > 0) {
+      oc_parse_rep(buf, ret, &rep);
+      oc_sec_decode_acl(rep);
+      oc_free_rep(rep);
+    }
+  }
+
+  if (ret <= 0) {
+    oc_sec_acl_default();
+  }
+}
+
+void
+oc_sec_dump_state(void)
+{
+  uint8_t buf[1024];
+
+  /* pstat */
+  oc_rep_new(buf, 1024);
+  oc_sec_encode_pstat();
+  int size = oc_rep_finalize();
+  if (size > 0) {
+    LOG("oc_store: encoded pstat size %d\n", size);
+    oc_storage_write("/pstat", buf, size);
+  }
+
+  /* cred */
+  oc_rep_new(buf, 1024);
+  oc_sec_encode_cred();
+  size = oc_rep_finalize();
+  if (size > 0) {
+    LOG("oc_store: encoded cred size %d\n", size);
+    oc_storage_write("/cred", buf, size);
+  }
+
+  /* doxm */
+  oc_rep_new(buf, 1024);
+  oc_sec_encode_doxm();
+  size = oc_rep_finalize();
+  if (size > 0) {
+    LOG("oc_store: encoded doxm size %d\n", size);
+    oc_storage_write("/doxm", buf, size);
+  }
+
+  /* acl */
+  oc_rep_new(buf, 1024);
+  oc_sec_encode_acl();
+  size = oc_rep_finalize();
+  if (size > 0) {
+    LOG("oc_store: encoded ACL size %d\n", size);
+    oc_storage_write("/acl", buf, size);
+  }
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_store.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_store.h b/libs/iotivity/src/security/oc_store.h
new file mode 100644
index 0000000..bf684e3
--- /dev/null
+++ b/libs/iotivity/src/security/oc_store.h
@@ -0,0 +1,26 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_STORE_H_
+#define OC_STORE_H_
+
+void oc_sec_load_pstat(void);
+void oc_sec_load_doxm(void);
+void oc_sec_load_cred(void);
+void oc_sec_load_acl(void);
+void oc_sec_dump_state(void);
+
+#endif /* OC_STORE_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_svr.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_svr.c b/libs/iotivity/src/security/oc_svr.c
new file mode 100644
index 0000000..8e44425
--- /dev/null
+++ b/libs/iotivity/src/security/oc_svr.c
@@ -0,0 +1,51 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_svr.h"
+#include "oc_acl.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+#include "oc_cred.h"
+#include "oc_doxm.h"
+#include "oc_pstat.h"
+#include "oc_ri.h"
+#include "port/oc_log.h"
+
+// Multiple devices?
+// What methods do sec resources support
+
+/* check resource properties */
+void
+oc_sec_create_svr(void)
+{
+  oc_core_populate_resource(OCF_SEC_DOXM, "/oic/sec/doxm", "oic.sec.doxm",
+                            OC_IF_BASELINE, OC_IF_BASELINE,
+                            OC_ACTIVE | OC_SECURE | OC_DISCOVERABLE, get_doxm,
+                            0, post_doxm, 0, 0);
+  oc_core_populate_resource(
+    OCF_SEC_PSTAT, "/oic/sec/pstat", "oic.sec.pstat", OC_IF_BASELINE,
+    OC_IF_BASELINE, OC_ACTIVE | OC_SECURE, get_pstat, 0, post_pstat, 0, 0);
+  oc_core_populate_resource(OCF_SEC_ACL, "/oic/sec/acl", "oic.sec.acl",
+                            OC_IF_BASELINE, OC_IF_BASELINE,
+                            OC_ACTIVE | OC_SECURE, 0, 0, post_acl, 0, 0);
+  oc_core_populate_resource(OCF_SEC_CRED, "/oic/sec/cred", "oic.sec.cred",
+                            OC_IF_BASELINE, OC_IF_BASELINE,
+                            OC_ACTIVE | OC_SECURE, 0, 0, post_cred, 0, 0);
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_svr.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_svr.h b/libs/iotivity/src/security/oc_svr.h
new file mode 100644
index 0000000..51b4106
--- /dev/null
+++ b/libs/iotivity/src/security/oc_svr.h
@@ -0,0 +1,22 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_SVR_H
+#define OC_SVR_H
+
+void oc_sec_create_svr(void);
+
+#endif /* OC_SVR_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_etimer.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_etimer.c b/libs/iotivity/src/util/oc_etimer.c
new file mode 100644
index 0000000..bf56f49
--- /dev/null
+++ b/libs/iotivity/src/util/oc_etimer.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#include "oc_etimer.h"
+#include "oc_process.h"
+
+static struct oc_etimer *timerlist;
+static oc_clock_time_t next_expiration;
+
+OC_PROCESS(oc_etimer_process, "Event timer");
+/*---------------------------------------------------------------------------*/
+static void
+update_time(void)
+{
+  oc_clock_time_t tdist;
+  oc_clock_time_t now;
+  struct oc_etimer *t;
+
+  if (timerlist == NULL) {
+    next_expiration = 0;
+  } else {
+    now = oc_clock_time();
+    t = timerlist;
+    /* Must calculate distance to next time into account due to wraps */
+    tdist = t->timer.start + t->timer.interval - now;
+    for (t = t->next; t != NULL; t = t->next) {
+      if (t->timer.start + t->timer.interval - now < tdist) {
+        tdist = t->timer.start + t->timer.interval - now;
+      }
+    }
+    next_expiration = now + tdist;
+  }
+}
+/*---------------------------------------------------------------------------*/
+OC_PROCESS_THREAD(oc_etimer_process, ev, data)
+{
+  struct oc_etimer *t, *u;
+
+  OC_PROCESS_BEGIN();
+
+  timerlist = NULL;
+
+  while (1) {
+    OC_PROCESS_YIELD();
+
+    if (ev == OC_PROCESS_EVENT_EXITED) {
+      struct oc_process *p = data;
+
+      while (timerlist != NULL && timerlist->p == p) {
+        timerlist = timerlist->next;
+      }
+
+      if (timerlist != NULL) {
+        t = timerlist;
+        while (t->next != NULL) {
+          if (t->next->p == p) {
+            t->next = t->next->next;
+          } else
+            t = t->next;
+        }
+      }
+      continue;
+    } else if (ev != OC_PROCESS_EVENT_POLL) {
+      continue;
+    }
+
+  again:
+
+    u = NULL;
+
+    for (t = timerlist; t != NULL; t = t->next) {
+      if (oc_timer_expired(&t->timer)) {
+        if (oc_process_post(t->p, OC_PROCESS_EVENT_TIMER, t) ==
+            OC_PROCESS_ERR_OK) {
+
+          /* Reset the process ID of the event timer, to signal that the
+             etimer has expired. This is later checked in the
+             oc_etimer_expired() function. */
+          t->p = OC_PROCESS_NONE;
+          if (u != NULL) {
+            u->next = t->next;
+          } else {
+            timerlist = t->next;
+          }
+          t->next = NULL;
+          update_time();
+          goto again;
+        } else {
+          oc_etimer_request_poll();
+        }
+      }
+      u = t;
+    }
+  }
+
+  OC_PROCESS_END();
+}
+/*---------------------------------------------------------------------------*/
+oc_clock_time_t
+oc_etimer_request_poll(void)
+{
+  oc_process_poll(&oc_etimer_process);
+  return oc_etimer_next_expiration_time();
+}
+/*---------------------------------------------------------------------------*/
+static void
+add_timer(struct oc_etimer *timer)
+{
+  struct oc_etimer *t;
+
+  oc_etimer_request_poll();
+
+  if (timer->p != OC_PROCESS_NONE) {
+    for (t = timerlist; t != NULL; t = t->next) {
+      if (t == timer) {
+        /* Timer already on list, bail out. */
+        timer->p = OC_PROCESS_CURRENT();
+        update_time();
+        return;
+      }
+    }
+  }
+
+  /* Timer not on list. */
+  timer->p = OC_PROCESS_CURRENT();
+  timer->next = timerlist;
+  timerlist = timer;
+
+  update_time();
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_set(struct oc_etimer *et, oc_clock_time_t interval)
+{
+  oc_timer_set(&et->timer, interval);
+  add_timer(et);
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_reset_with_new_interval(struct oc_etimer *et,
+                                  oc_clock_time_t interval)
+{
+  oc_timer_reset(&et->timer);
+  et->timer.interval = interval;
+  add_timer(et);
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_reset(struct oc_etimer *et)
+{
+  oc_timer_reset(&et->timer);
+  add_timer(et);
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_restart(struct oc_etimer *et)
+{
+  oc_timer_restart(&et->timer);
+  add_timer(et);
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_adjust(struct oc_etimer *et, int timediff)
+{
+  et->timer.start += timediff;
+  update_time();
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_etimer_expired(struct oc_etimer *et)
+{
+  return et->p == OC_PROCESS_NONE;
+}
+/*---------------------------------------------------------------------------*/
+oc_clock_time_t
+oc_etimer_expiration_time(struct oc_etimer *et)
+{
+  return et->timer.start + et->timer.interval;
+}
+/*---------------------------------------------------------------------------*/
+oc_clock_time_t
+oc_etimer_start_time(struct oc_etimer *et)
+{
+  return et->timer.start;
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_etimer_pending(void)
+{
+  return timerlist != NULL;
+}
+/*---------------------------------------------------------------------------*/
+oc_clock_time_t
+oc_etimer_next_expiration_time(void)
+{
+  return oc_etimer_pending() ? next_expiration : 0;
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_etimer_stop(struct oc_etimer *et)
+{
+  struct oc_etimer *t;
+
+  /* First check if et is the first event timer on the list. */
+  if (et == timerlist) {
+    timerlist = timerlist->next;
+    update_time();
+  } else {
+    /* Else walk through the list and try to find the item before the
+       et timer. */
+    for (t = timerlist; t != NULL && t->next != et; t = t->next)
+      ;
+
+    if (t != NULL) {
+      /* We've found the item before the event timer that we are about
+   to remove. We point the items next pointer to the event after
+   the removed item. */
+      t->next = et->next;
+
+      update_time();
+    }
+  }
+
+  /* Remove the next pointer from the item to be removed. */
+  et->next = NULL;
+  /* Set the timer as expired */
+  et->p = OC_PROCESS_NONE;
+}
+/*---------------------------------------------------------------------------*/
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_etimer.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_etimer.h b/libs/iotivity/src/util/oc_etimer.h
new file mode 100644
index 0000000..edce777
--- /dev/null
+++ b/libs/iotivity/src/util/oc_etimer.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \defgroup etimer Event timers
+ *
+ * Event timers provides a way to generate timed events. An event
+ * timer will post an event to the process that set the timer when the
+ * event timer expires.
+ *
+ * An event timer is declared as a \c struct \c etimer and all access
+ * to the event timer is made by a pointer to the declared event
+ * timer.
+ *
+ * \sa \ref timer "Simple timer library"
+ * \sa \ref clock "Clock library" (used by the timer library)
+ *
+ * @{
+ */
+
+#ifndef OC_ETIMER_H
+#define OC_ETIMER_H
+
+#include "oc_process.h"
+#include "oc_timer.h"
+
+/**
+ * A timer.
+ *
+ * This structure is used for declaring a timer. The timer must be set
+ * with oc_etimer_set() before it can be used.
+ *
+ * \hideinitializer
+ */
+struct oc_etimer
+{
+  struct oc_timer timer;
+  struct oc_etimer *next;
+  struct oc_process *p;
+};
+
+/**
+ * \name Functions called from application programs
+ * @{
+ */
+
+/**
+ * \brief      Set an event timer.
+ * \param et   A pointer to the event timer
+ * \param interval The interval before the timer expires.
+ *
+ *             This function is used to set an event timer for a time
+ *             sometime in the future. When the event timer expires,
+ *             the event PROCESS_EVENT_TIMER will be posted to the
+ *             process that called the oc_etimer_set() function.
+ *
+ */
+void oc_etimer_set(struct oc_etimer *et, oc_clock_time_t interval);
+
+/**
+ * \brief      Reset an event timer with the same interval as was
+ *             previously set.
+ * \param et   A pointer to the event timer.
+ *
+ *             This function resets the event timer with the same
+ *             interval that was given to the event timer with the
+ *             oc_etimer_set() function. The start point of the interval
+ *             is the exact time that the event timer last
+ *             expired. Therefore, this function will cause the timer
+ *             to be stable over time, unlike the oc_etimer_restart()
+ *             function.
+ *
+ * \sa oc_etimer_restart()
+ */
+void oc_etimer_reset(struct oc_etimer *et);
+
+/**
+ * \brief      Reset an event timer with a new interval.
+ * \param et   A pointer to the event timer.
+ * \param interval The interval before the timer expires.
+ *
+ *             This function very similar to oc_etimer_reset. Opposed to
+ *             oc_etimer_reset it is possible to change the timout.
+ *             This allows accurate, non-periodic timers without drift.
+ *
+ * \sa oc_etimer_reset()
+ */
+void oc_etimer_reset_with_new_interval(struct oc_etimer *et,
+                                       oc_clock_time_t interval);
+
+/**
+ * \brief      Restart an event timer from the current point in time
+ * \param et   A pointer to the event timer.
+ *
+ *             This function restarts the event timer with the same
+ *             interval that was given to the oc_etimer_set()
+ *             function. The event timer will start at the current
+ *             time.
+ *
+ *             \note A periodic timer will drift if this function is
+ *             used to reset it. For periodic timers, use the
+ *             oc_etimer_reset() function instead.
+ *
+ * \sa oc_etimer_reset()
+ */
+void oc_etimer_restart(struct oc_etimer *et);
+
+/**
+ * \brief      Adjust the expiration time for an event timer
+ * \param et   A pointer to the event timer.
+ * \param td   The time difference to adjust the expiration time with.
+ *
+ *             This function is used to adjust the time the event
+ *             timer will expire. It can be used to synchronize
+ *             periodic timers without the need to restart the timer
+ *             or change the timer interval.
+ *
+ *             \note This function should only be used for small
+ *             adjustments. For large adjustments use oc_etimer_set()
+ *             instead.
+ *
+ *             \note A periodic timer will drift unless the
+ *             oc_etimer_reset() function is used.
+ *
+ * \sa oc_etimer_set()
+ * \sa oc_etimer_reset()
+ */
+void oc_etimer_adjust(struct oc_etimer *et, int td);
+
+/**
+ * \brief      Get the expiration time for the event timer.
+ * \param et   A pointer to the event timer
+ * \return     The expiration time for the event timer.
+ *
+ *             This function returns the expiration time for an event timer.
+ */
+oc_clock_time_t oc_etimer_expiration_time(struct oc_etimer *et);
+
+/**
+ * \brief      Get the start time for the event timer.
+ * \param et   A pointer to the event timer
+ * \return     The start time for the event timer.
+ *
+ *             This function returns the start time (when the timer
+ *             was last set) for an event timer.
+ */
+oc_clock_time_t oc_etimer_start_time(struct oc_etimer *et);
+
+/**
+ * \brief      Check if an event timer has expired.
+ * \param et   A pointer to the event timer
+ * \return     Non-zero if the timer has expired, zero otherwise.
+ *
+ *             This function tests if an event timer has expired and
+ *             returns true or false depending on its status.
+ */
+int oc_etimer_expired(struct oc_etimer *et);
+
+/**
+ * \brief      Stop a pending event timer.
+ * \param et   A pointer to the pending event timer.
+ *
+ *             This function stops an event timer that has previously
+ *             been set with oc_etimer_set() or oc_etimer_reset(). After
+ *             this function has been called, the event timer will not
+ *             emit any event when it expires.
+ *
+ */
+void oc_etimer_stop(struct oc_etimer *et);
+
+/** @} */
+
+/**
+ * \name Functions called from timer interrupts, by the system
+ * @{
+ */
+
+/**
+ * \brief      Make the event timer aware that the clock has changed
+ *
+ *             This function is used to inform the event timer module
+ *             that the system clock has been updated. Typically, this
+ *             function would be called from the timer interrupt
+ *             handler when the clock has ticked.
+ */
+oc_clock_time_t oc_etimer_request_poll(void);
+
+/**
+ * \brief      Check if there are any non-expired event timers.
+ * \return     True if there are active event timers, false if there are
+ *             no active timers.
+ *
+ *             This function checks if there are any active event
+ *             timers that have not expired.
+ */
+int oc_etimer_pending(void);
+
+/**
+ * \brief      Get next event timer expiration time.
+ * \return     Next expiration time of all pending event timers.
+ *             If there are no pending event timers this function
+ *	       returns 0.
+ *
+ *             This functions returns next expiration time of all
+ *             pending event timers.
+ */
+oc_clock_time_t oc_etimer_next_expiration_time(void);
+
+/** @} */
+
+OC_PROCESS_NAME(oc_etimer_process);
+#endif /* OC_ETIMER_H */
+/** @} */
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_list.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_list.c b/libs/iotivity/src/util/oc_list.c
new file mode 100644
index 0000000..429f411
--- /dev/null
+++ b/libs/iotivity/src/util/oc_list.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#include "oc_list.h"
+
+#define NULL 0
+
+struct list
+{
+  struct list *next;
+};
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Initialize a list.
+ *
+ * This function initalizes a list. The list will be empty after this
+ * function has been called.
+ *
+ * \param list The list to be initialized.
+ */
+void
+oc_list_init(oc_list_t list)
+{
+  *list = NULL;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Get a pointer to the first element of a list.
+ *
+ * This function returns a pointer to the first element of the
+ * list. The element will \b not be removed from the list.
+ *
+ * \param list The list.
+ * \return A pointer to the first element on the list.
+ *
+ * \sa oc_list_tail()
+ */
+void *
+oc_list_head(oc_list_t list)
+{
+  return *list;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Duplicate a list.
+ *
+ * This function duplicates a list by copying the list reference, but
+ * not the elements.
+ *
+ * \note This function does \b not copy the elements of the list, but
+ * merely duplicates the pointer to the first element of the list.
+ *
+ * \param dest The destination list.
+ * \param src The source list.
+ */
+void
+oc_list_copy(oc_list_t dest, oc_list_t src)
+{
+  *dest = *src;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Get the tail of a list.
+ *
+ * This function returns a pointer to the elements following the first
+ * element of a list. No elements are removed by this function.
+ *
+ * \param list The list
+ * \return A pointer to the element after the first element on the list.
+ *
+ * \sa oc_list_head()
+ */
+void *
+oc_list_tail(oc_list_t list)
+{
+  struct list *l;
+
+  if (*list == NULL) {
+    return NULL;
+  }
+
+  for (l = *list; l->next != NULL; l = l->next)
+    ;
+
+  return l;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Add an item at the end of a list.
+ *
+ * This function adds an item to the end of the list.
+ *
+ * \param list The list.
+ * \param item A pointer to the item to be added.
+ *
+ * \sa oc_list_push()
+ *
+ */
+void
+oc_list_add(oc_list_t list, void *item)
+{
+  struct list *l;
+
+  /* Make sure not to add the same element twice */
+  oc_list_remove(list, item);
+
+  ((struct list *)item)->next = NULL;
+
+  l = oc_list_tail(list);
+
+  if (l == NULL) {
+    *list = item;
+  } else {
+    l->next = item;
+  }
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Add an item to the start of the list.
+ */
+void
+oc_list_push(oc_list_t list, void *item)
+{
+  /* Make sure not to add the same element twice */
+  oc_list_remove(list, item);
+
+  ((struct list *)item)->next = *list;
+  *list = item;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Remove the last object on the list.
+ *
+ * This function removes the last object on the list and returns it.
+ *
+ * \param list The list
+ * \return The removed object
+ *
+ */
+void *
+oc_list_chop(oc_list_t list)
+{
+  struct list *l, *r;
+
+  if (*list == NULL) {
+    return NULL;
+  }
+  if (((struct list *)*list)->next == NULL) {
+    l = *list;
+    *list = NULL;
+    return l;
+  }
+
+  for (l = *list; l->next->next != NULL; l = l->next)
+    ;
+
+  r = l->next;
+  l->next = NULL;
+
+  return r;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Remove the first object on a list.
+ *
+ * This function removes the first object on the list and returns a
+ * pointer to it.
+ *
+ * \param list The list.
+ * \return Pointer to the removed element of list.
+ */
+/*---------------------------------------------------------------------------*/
+void *
+oc_list_pop(oc_list_t list)
+{
+  struct list *l;
+  l = *list;
+  if (*list != NULL) {
+    *list = ((struct list *)*list)->next;
+  }
+
+  return l;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Remove a specific element from a list.
+ *
+ * This function removes a specified element from the list.
+ *
+ * \param list The list.
+ * \param item The item that is to be removed from the list.
+ *
+ */
+/*---------------------------------------------------------------------------*/
+void
+oc_list_remove(oc_list_t list, void *item)
+{
+  struct list *l, *r;
+
+  if (*list == NULL) {
+    return;
+  }
+
+  r = NULL;
+  for (l = *list; l != NULL; l = l->next) {
+    if (l == item) {
+      if (r == NULL) {
+        /* First on list */
+        *list = l->next;
+      } else {
+        /* Not first on list */
+        r->next = l->next;
+      }
+      l->next = NULL;
+      return;
+    }
+    r = l;
+  }
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Get the length of a list.
+ *
+ * This function counts the number of elements on a specified list.
+ *
+ * \param list The list.
+ * \return The length of the list.
+ */
+/*---------------------------------------------------------------------------*/
+int
+oc_list_length(oc_list_t list)
+{
+  struct list *l;
+  int n = 0;
+
+  for (l = *list; l != NULL; l = l->next) {
+    ++n;
+  }
+
+  return n;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * \brief      Insert an item after a specified item on the list
+ * \param list The list
+ * \param previtem The item after which the new item should be inserted
+ * \param newitem  The new item that is to be inserted
+ * \author     Adam Dunkels
+ *
+ *             This function inserts an item right after a specified
+ *             item on the list. This function is useful when using
+ *             the list module to ordered lists.
+ *
+ *             If previtem is NULL, the new item is placed at the
+ *             start of the list.
+ *
+ */
+void
+oc_list_insert(oc_list_t list, void *previtem, void *newitem)
+{
+  if (previtem == NULL) {
+    oc_list_push(list, newitem);
+  } else {
+
+    ((struct list *)newitem)->next = ((struct list *)previtem)->next;
+    ((struct list *)previtem)->next = newitem;
+  }
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * \brief      Get the next item following this item
+ * \param item A list item
+ * \returns    A next item on the list
+ *
+ *             This function takes a list item and returns the next
+ *             item on the list, or NULL if there are no more items on
+ *             the list. This function is used when iterating through
+ *             lists.
+ */
+void *
+oc_list_item_next(void *item)
+{
+  return item == NULL ? NULL : ((struct list *)item)->next;
+}
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_list.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_list.h b/libs/iotivity/src/util/oc_list.h
new file mode 100644
index 0000000..1ff9e15
--- /dev/null
+++ b/libs/iotivity/src/util/oc_list.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \defgroup list Linked list library
+ *
+ * The linked list library provides a set of functions for
+ * manipulating linked lists.
+ *
+ * A linked list is made up of elements where the first element \b
+ * must be a pointer. This pointer is used by the linked list library
+ * to form lists of the elements.
+ *
+ * Lists are declared with the LIST() macro. The declaration specifies
+ * the name of the list that later is used with all list functions.
+ *
+ * Lists can be manipulated by inserting or removing elements from
+ * either sides of the list (list_push(), list_add(), list_pop(),
+ * list_chop()). A specified element can also be removed from inside a
+ * list with list_remove(). The head and tail of a list can be
+ * extracted using list_head() and list_tail(), respectively.
+ *
+ */
+
+#ifndef OC_LIST_H
+#define OC_LIST_H
+
+#define OC_LIST_CONCAT2(s1, s2) s1##s2
+#define OC_LIST_CONCAT(s1, s2) OC_LIST_CONCAT2(s1, s2)
+
+/**
+ * Declare a linked list.
+ *
+ * This macro declares a linked list with the specified \c type. The
+ * type \b must be a structure (\c struct) with its first element
+ * being a pointer. This pointer is used by the linked list library to
+ * form the linked lists.
+ *
+ * The list variable is declared as static to make it easy to use in a
+ * single C module without unnecessarily exporting the name to other
+ * modules.
+ *
+ * \param name The name of the list.
+ */
+#define OC_LIST(name)                                                          \
+  static void *OC_LIST_CONCAT(name, _list) = NULL;                             \
+  static oc_list_t name = (oc_list_t)&OC_LIST_CONCAT(name, _list)
+
+/**
+ * Declare a linked list inside a structure declaraction.
+ *
+ * This macro declares a linked list with the specified \c type. The
+ * type \b must be a structure (\c struct) with its first element
+ * being a pointer. This pointer is used by the linked list library to
+ * form the linked lists.
+ *
+ * Internally, the list is defined as two items: the list itself and a
+ * pointer to the list. The pointer has the name of the parameter to
+ * the macro and the name of the list is a concatenation of the name
+ * and the suffix "_list". The pointer must point to the list for the
+ * list to work. Thus the list must be initialized before using.
+ *
+ * The list is initialized with the LIST_STRUCT_INIT() macro.
+ *
+ * \param name The name of the list.
+ */
+#define OC_LIST_STRUCT(name)                                                   \
+  void *OC_LIST_CONCAT(name, _list);                                           \
+  oc_list_t name
+
+/**
+ * Initialize a linked list that is part of a structure.
+ *
+ * This macro sets up the internal pointers in a list that has been
+ * defined as part of a struct. This macro must be called before using
+ * the list.
+ *
+ * \param struct_ptr A pointer to the struct
+ * \param name The name of the list.
+ */
+#define OC_LIST_STRUCT_INIT(struct_ptr, name)                                  \
+  do {                                                                         \
+    (struct_ptr)->name = &((struct_ptr)->OC_LIST_CONCAT(name, _list));         \
+    (struct_ptr)->OC_LIST_CONCAT(name, _list) = NULL;                          \
+    oc_list_init((struct_ptr)->name);                                          \
+  } while (0)
+
+/**
+ * The linked list type.
+ *
+ */
+typedef void **oc_list_t;
+
+void oc_list_init(oc_list_t list);
+void *oc_list_head(oc_list_t list);
+void *oc_list_tail(oc_list_t list);
+void *oc_list_pop(oc_list_t list);
+void oc_list_push(oc_list_t list, void *item);
+
+void *oc_list_chop(oc_list_t list);
+
+void oc_list_add(oc_list_t list, void *item);
+void oc_list_remove(oc_list_t list, void *item);
+
+int oc_list_length(oc_list_t list);
+
+void oc_list_copy(oc_list_t dest, oc_list_t src);
+
+void oc_list_insert(oc_list_t list, void *previtem, void *newitem);
+
+void *oc_list_item_next(void *item);
+
+#endif /* OC_LIST_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_memb.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_memb.c b/libs/iotivity/src/util/oc_memb.c
new file mode 100644
index 0000000..31909a9
--- /dev/null
+++ b/libs/iotivity/src/util/oc_memb.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#include "oc_memb.h"
+#include <string.h>
+
+/*---------------------------------------------------------------------------*/
+void
+oc_memb_init(struct oc_memb *m)
+{
+  memset(m->count, 0, m->num);
+  memset(m->mem, 0, (unsigned)m->size * (unsigned)m->num);
+}
+/*---------------------------------------------------------------------------*/
+void *
+oc_memb_alloc(struct oc_memb *m)
+{
+  int i;
+
+  for (i = 0; i < m->num; ++i) {
+    if (m->count[i] == 0) {
+      /* If this block was unused, we increase the reference count to
+   indicate that it now is used and return a pointer to the
+   memory block. */
+      ++(m->count[i]);
+      return (void *)((char *)m->mem + (i * m->size));
+    }
+  }
+
+  /* No free block was found, so we return NULL to indicate failure to
+     allocate block. */
+  return NULL;
+}
+/*---------------------------------------------------------------------------*/
+char
+oc_memb_free(struct oc_memb *m, void *ptr)
+{
+  int i;
+  char *ptr2;
+
+  /* Walk through the list of blocks and try to find the block to
+     which the pointer "ptr" points to. */
+  ptr2 = (char *)m->mem;
+  for (i = 0; i < m->num; ++i) {
+
+    if (ptr2 == (char *)ptr) {
+      /* We've found to block to which "ptr" points so we decrease the
+   reference count and return the new value of it. */
+      if (m->count[i] > 0) {
+        /* Make sure that we don't deallocate free memory. */
+        --(m->count[i]);
+      }
+      return m->count[i];
+    }
+    ptr2 += m->size;
+  }
+  return -1;
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_memb_inmemb(struct oc_memb *m, void *ptr)
+{
+  return (char *)ptr >= (char *)m->mem &&
+         (char *)ptr < (char *)m->mem + (m->num * m->size);
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_memb_numfree(struct oc_memb *m)
+{
+  int i;
+  int num_free = 0;
+
+  for (i = 0; i < m->num; ++i) {
+    if (m->count[i] == 0) {
+      ++num_free;
+    }
+  }
+
+  return num_free;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_memb.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_memb.h b/libs/iotivity/src/util/oc_memb.h
new file mode 100644
index 0000000..f329dfe
--- /dev/null
+++ b/libs/iotivity/src/util/oc_memb.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \defgroup memb Memory block management functions
+ *
+ * The memory block allocation routines provide a simple yet powerful
+ * set of functions for managing a set of memory blocks of fixed
+ * size. A set of memory blocks is statically declared with the
+ * OC_MEMB() macro. Memory blocks are allocated from the declared
+ * memory by the oc_memb_alloc() function, and are deallocated with the
+ * oc_memb_free() function.
+ *
+ */
+
+#ifndef OC_MEMB_H
+#define OC_MEMB_H
+
+#define CC_CONCAT2(s1, s2) s1##s2
+/**
+ * A C preprocessing macro for concatenating two preprocessor tokens.
+ *
+ * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow
+ * concatenation of two \#defined macros.
+ */
+#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2)
+
+/**
+ * Declare a memory block.
+ *
+ * This macro is used to statically declare a block of memory that can
+ * be used by the block allocation functions. The macro statically
+ * declares a C array with a size that matches the specified number of
+ * blocks and their individual sizes.
+ *
+ * Example:
+ \code
+ MEMB(connections, struct connection, 16);
+ \endcode
+ *
+ * \param name The name of the memory block (later used with
+ * oc_memb_init(), oc_memb_alloc() and oc_memb_free()).
+ *
+ * \param structure The name of the struct that the memory block holds
+ *
+ * \param num The total number of memory chunks in the block.
+ *
+ */
+#define OC_MEMB(name, structure, num)                                          \
+  static char CC_CONCAT(name, _memb_count)[num];                               \
+  static structure CC_CONCAT(name, _memb_mem)[num];                            \
+  static struct oc_memb name = { sizeof(structure), num,                       \
+                                 CC_CONCAT(name, _memb_count),                 \
+                                 (void *)CC_CONCAT(name, _memb_mem) }
+
+struct oc_memb
+{
+  unsigned short size;
+  unsigned short num;
+  char *count;
+  void *mem;
+};
+
+/**
+ * Initialize a memory block that was declared with MEMB().
+ *
+ * \param m A memory block previously declared with MEMB().
+ */
+void oc_memb_init(struct oc_memb *m);
+
+/**
+ * Allocate a memory block from a block of memory declared with MEMB().
+ *
+ * \param m A memory block previously declared with MEMB().
+ */
+void *oc_memb_alloc(struct oc_memb *m);
+
+/**
+ * Deallocate a memory block from a memory block previously declared
+ * with MEMB().
+ *
+ * \param m m A memory block previously declared with MEMB().
+ *
+ * \param ptr A pointer to the memory block that is to be deallocated.
+ *
+ * \return The new reference count for the memory block (should be 0
+ * if successfully deallocated) or -1 if the pointer "ptr" did not
+ * point to a legal memory block.
+ */
+char oc_memb_free(struct oc_memb *m, void *ptr);
+
+int oc_memb_inmemb(struct oc_memb *m, void *ptr);
+
+int oc_memb_numfree(struct oc_memb *m);
+
+#endif /* OC_MEMB_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_mmem.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_mmem.c b/libs/iotivity/src/util/oc_mmem.c
new file mode 100644
index 0000000..8a129c6
--- /dev/null
+++ b/libs/iotivity/src/util/oc_mmem.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+#include "oc_mmem.h"
+#include "config.h"
+#include "oc_list.h"
+#include "port/oc_log.h"
+#include <stdint.h>
+#include <string.h>
+
+#if !defined(OC_BYTES_POOL_SIZE) || !defined(OC_INTS_POOL_SIZE) ||             \
+  !defined(OC_DOUBLES_POOL_SIZE)
+#error "Please define byte, int, double pool sizes in config.h"
+#endif /* ...POOL_SIZE */
+
+static double doubles[OC_DOUBLES_POOL_SIZE];
+static int64_t ints[OC_INTS_POOL_SIZE];
+static unsigned char bytes[OC_BYTES_POOL_SIZE];
+static unsigned int avail_bytes, avail_ints, avail_doubles;
+
+OC_LIST(bytes_list);
+OC_LIST(ints_list);
+OC_LIST(doubles_list);
+
+/*---------------------------------------------------------------------------*/
+int
+oc_mmem_alloc(struct oc_mmem *m, unsigned int size, pool pool_type)
+{
+  switch (pool_type) {
+  case BYTE_POOL:
+    if (avail_bytes < size) {
+      return 0;
+    }
+    oc_list_add(bytes_list, m);
+    m->ptr = &bytes[OC_BYTES_POOL_SIZE - avail_bytes];
+    m->size = size;
+    avail_bytes -= size;
+    break;
+  case INT_POOL:
+    if (avail_ints < size) {
+      return 0;
+    }
+    oc_list_add(ints_list, m);
+    m->ptr = &ints[OC_INTS_POOL_SIZE - avail_ints];
+    m->size = size;
+    avail_ints -= size;
+    break;
+  case DOUBLE_POOL:
+    if (avail_doubles < size) {
+      return 0;
+    }
+    oc_list_add(doubles_list, m);
+    m->ptr = &doubles[OC_DOUBLES_POOL_SIZE - avail_doubles];
+    m->size = size;
+    avail_doubles -= size;
+    break;
+  default:
+    break;
+  }
+  return 1;
+}
+
+void
+oc_mmem_free(struct oc_mmem *m, pool pool_type)
+{
+  struct oc_mmem *n;
+
+  if (m->next != NULL) {
+    switch (pool_type) {
+    case BYTE_POOL:
+      memmove(m->ptr, m->next->ptr, &bytes[OC_BYTES_POOL_SIZE - avail_bytes] -
+                                      (unsigned char *)m->next->ptr);
+      break;
+    case INT_POOL:
+      memmove(m->ptr, m->next->ptr,
+              &ints[OC_INTS_POOL_SIZE - avail_ints] - (int64_t *)m->next->ptr);
+      break;
+    case DOUBLE_POOL:
+      memmove(m->ptr, m->next->ptr,
+              &doubles[OC_DOUBLES_POOL_SIZE - avail_doubles] -
+                (double *)m->next->ptr);
+      break;
+    default:
+      return;
+      break;
+    }
+    for (n = m->next; n != NULL; n = n->next) {
+      n->ptr = (void *)((char *)n->ptr - m->size);
+    }
+  }
+
+  switch (pool_type) {
+  case BYTE_POOL:
+    avail_bytes += m->size;
+    oc_list_remove(bytes_list, m);
+    break;
+  case INT_POOL:
+    avail_ints += m->size;
+    oc_list_remove(ints_list, m);
+    break;
+  case DOUBLE_POOL:
+    avail_doubles += m->size;
+    oc_list_remove(doubles_list, m);
+    break;
+  }
+}
+
+void
+oc_mmem_init(void)
+{
+  static int inited = 0;
+  if (inited) {
+    return;
+  }
+  oc_list_init(bytes_list);
+  oc_list_init(ints_list);
+  oc_list_init(doubles_list);
+  avail_bytes = OC_BYTES_POOL_SIZE;
+  avail_ints = OC_INTS_POOL_SIZE;
+  avail_doubles = OC_DOUBLES_POOL_SIZE;
+  inited = 1;
+}
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_mmem.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_mmem.h b/libs/iotivity/src/util/oc_mmem.h
new file mode 100644
index 0000000..fdabfa4
--- /dev/null
+++ b/libs/iotivity/src/util/oc_mmem.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+#ifndef OC_MMEM_H
+#define OC_MMEM_H
+
+#define OC_MMEM_PTR(m) (struct oc_mmem *)(m)->ptr
+
+struct oc_mmem
+{
+  struct oc_mmem *next;
+  unsigned int size;
+  void *ptr;
+};
+
+typedef enum { BYTE_POOL, INT_POOL, DOUBLE_POOL } pool;
+
+int oc_mmem_alloc(struct oc_mmem *m, unsigned int size, pool pool_type);
+void oc_mmem_free(struct oc_mmem *, pool pool_type);
+void oc_mmem_init(void);
+
+#endif /* OC_MMEM_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_process.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_process.c b/libs/iotivity/src/util/oc_process.c
new file mode 100644
index 0000000..47c3282
--- /dev/null
+++ b/libs/iotivity/src/util/oc_process.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+#include "oc_process.h"
+#include "oc_buffer.h"
+#include <stdio.h>
+
+/*
+ * Pointer to the currently running process structure.
+ */
+struct oc_process *oc_process_list = NULL;
+struct oc_process *oc_process_current = NULL;
+
+static oc_process_event_t lastevent;
+
+/*
+ * Structure used for keeping the queue of active events.
+ */
+struct event_data
+{
+  oc_process_event_t ev;
+  oc_process_data_t data;
+  struct oc_process *p;
+};
+
+static oc_process_num_events_t nevents, fevent;
+static struct event_data events[OC_PROCESS_CONF_NUMEVENTS];
+
+#if OC_PROCESS_CONF_STATS
+oc_process_num_events_t process_maxevents;
+#endif
+
+static volatile unsigned char poll_requested;
+
+#define OC_PROCESS_STATE_NONE 0
+#define OC_PROCESS_STATE_RUNNING 1
+#define OC_PROCESS_STATE_CALLED 2
+
+static void call_process(struct oc_process *p, oc_process_event_t ev,
+                         oc_process_data_t data);
+
+/*---------------------------------------------------------------------------*/
+oc_process_event_t
+oc_process_alloc_event(void)
+{
+  return lastevent++;
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_process_start(struct oc_process *p, oc_process_data_t data)
+{
+  struct oc_process *q;
+
+  /* First make sure that we don't try to start a process that is
+     already running. */
+  for (q = oc_process_list; q != p && q != NULL; q = q->next)
+    ;
+
+  /* If we found the process on the process list, we bail out. */
+  if (q == p) {
+    return;
+  }
+  /* Put on the procs list.*/
+  p->next = oc_process_list;
+  oc_process_list = p;
+  p->state = OC_PROCESS_STATE_RUNNING;
+  PT_INIT(&p->pt);
+
+  /* Post a synchronous initialization event to the process. */
+  oc_process_post_synch(p, OC_PROCESS_EVENT_INIT, data);
+}
+/*---------------------------------------------------------------------------*/
+static void
+exit_process(struct oc_process *p, struct oc_process *fromprocess)
+{
+  register struct oc_process *q;
+  struct oc_process *old_current = oc_process_current;
+
+  /* Make sure the process is in the process list before we try to
+     exit it. */
+  for (q = oc_process_list; q != p && q != NULL; q = q->next)
+    ;
+  if (q == NULL) {
+    return;
+  }
+
+  if (oc_process_is_running(p)) {
+    /* Process was running */
+    p->state = OC_PROCESS_STATE_NONE;
+
+    /*
+     * Post a synchronous event to all processes to inform them that
+     * this process is about to exit. This will allow services to
+     * deallocate state associated with this process.
+     */
+    for (q = oc_process_list; q != NULL; q = q->next) {
+      if (p != q) {
+        call_process(q, OC_PROCESS_EVENT_EXITED, (oc_process_data_t)p);
+      }
+    }
+
+    if (p->thread != NULL && p != fromprocess) {
+      /* Post the exit event to the process that is about to exit. */
+      oc_process_current = p;
+      p->thread(&p->pt, OC_PROCESS_EVENT_EXIT, NULL);
+    }
+  }
+
+  if (p == oc_process_list) {
+    oc_process_list = oc_process_list->next;
+  } else {
+    for (q = oc_process_list; q != NULL; q = q->next) {
+      if (q->next == p) {
+        q->next = p->next;
+        break;
+      }
+    }
+  }
+
+  oc_process_current = old_current;
+}
+/*---------------------------------------------------------------------------*/
+static void
+call_process(struct oc_process *p, oc_process_event_t ev,
+             oc_process_data_t data)
+{
+  int ret;
+
+  if ((p->state & OC_PROCESS_STATE_RUNNING) && p->thread != NULL) {
+    oc_process_current = p;
+    p->state = OC_PROCESS_STATE_CALLED;
+    ret = p->thread(&p->pt, ev, data);
+    if (ret == PT_EXITED || ret == PT_ENDED || ev == OC_PROCESS_EVENT_EXIT) {
+      exit_process(p, p);
+    } else {
+      p->state = OC_PROCESS_STATE_RUNNING;
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_process_exit(struct oc_process *p)
+{
+  exit_process(p, OC_PROCESS_CURRENT());
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_process_init(void)
+{
+  lastevent = OC_PROCESS_EVENT_MAX;
+
+  nevents = fevent = 0;
+#if OC_PROCESS_CONF_STATS
+  process_maxevents = 0;
+#endif /* OC_PROCESS_CONF_STATS */
+
+  oc_process_current = oc_process_list = NULL;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * Call each process' poll handler.
+ */
+/*---------------------------------------------------------------------------*/
+static void
+do_poll(void)
+{
+  struct oc_process *p;
+
+  poll_requested = 0;
+  /* Call the processes that needs to be polled. */
+  for (p = oc_process_list; p != NULL; p = p->next) {
+    if (p->needspoll) {
+      p->state = OC_PROCESS_STATE_RUNNING;
+      p->needspoll = 0;
+      call_process(p, OC_PROCESS_EVENT_POLL, NULL);
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * Process the next event in the event queue and deliver it to
+ * listening processes.
+ */
+/*---------------------------------------------------------------------------*/
+static void
+do_event(void)
+{
+  static oc_process_event_t ev;
+  static oc_process_data_t data;
+  static struct oc_process *receiver;
+  static struct oc_process *p;
+
+  /*
+   * If there are any events in the queue, take the first one and walk
+   * through the list of processes to see if the event should be
+   * delivered to any of them. If so, we call the event handler
+   * function for the process. We only process one event at a time and
+   * call the poll handlers inbetween.
+   */
+
+  if (nevents > 0) {
+
+    /* There are events that we should deliver. */
+    ev = events[fevent].ev;
+
+    data = events[fevent].data;
+    receiver = events[fevent].p;
+
+    /* Since we have seen the new event, we move pointer upwards
+       and decrease the number of events. */
+    fevent = (fevent + 1) % OC_PROCESS_CONF_NUMEVENTS;
+    --nevents;
+
+    /* If this is a broadcast event, we deliver it to all events, in
+       order of their priority. */
+    if (receiver == OC_PROCESS_BROADCAST) {
+      for (p = oc_process_list; p != NULL; p = p->next) {
+
+        /* If we have been requested to poll a process, we do this in
+           between processing the broadcast event. */
+        if (poll_requested) {
+          do_poll();
+        }
+        call_process(p, ev, data);
+      }
+    } else {
+      /* This is not a broadcast event, so we deliver it to the
+   specified process. */
+      /* If the event was an INIT event, we should also update the
+   state of the process. */
+      if (ev == OC_PROCESS_EVENT_INIT) {
+        receiver->state = OC_PROCESS_STATE_RUNNING;
+      }
+
+      /* Make sure that the process actually is running. */
+      call_process(receiver, ev, data);
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_process_run(void)
+{
+  /* Process poll events. */
+  if (poll_requested) {
+    do_poll();
+  }
+
+  /* Process one event from the queue */
+  do_event();
+
+  return nevents + poll_requested;
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_process_nevents(void)
+{
+  return nevents + poll_requested;
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_process_post(struct oc_process *p, oc_process_event_t ev,
+                oc_process_data_t data)
+{
+  static oc_process_num_events_t snum;
+
+  if (nevents == OC_PROCESS_CONF_NUMEVENTS) {
+    oc_message_unref(data);
+    return OC_PROCESS_ERR_FULL;
+  }
+
+  snum =
+    (oc_process_num_events_t)(fevent + nevents) % OC_PROCESS_CONF_NUMEVENTS;
+  events[snum].ev = ev;
+  events[snum].data = data;
+  events[snum].p = p;
+  ++nevents;
+
+#if OC_PROCESS_CONF_STATS
+  if (nevents > process_maxevents) {
+    process_maxevents = nevents;
+  }
+#endif /* OC_PROCESS_CONF_STATS */
+
+  return OC_PROCESS_ERR_OK;
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_process_post_synch(struct oc_process *p, oc_process_event_t ev,
+                      oc_process_data_t data)
+{
+  struct oc_process *caller = oc_process_current;
+
+  call_process(p, ev, data);
+  oc_process_current = caller;
+}
+/*---------------------------------------------------------------------------*/
+void
+oc_process_poll(struct oc_process *p)
+{
+  if (p != NULL) {
+    if (p->state == OC_PROCESS_STATE_RUNNING ||
+        p->state == OC_PROCESS_STATE_CALLED) {
+      p->needspoll = 1;
+      poll_requested = 1;
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/
+int
+oc_process_is_running(struct oc_process *p)
+{
+  return p->state != OC_PROCESS_STATE_NONE;
+}
+/*---------------------------------------------------------------------------*/


[09/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_network_events.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_network_events.c b/libs/iotivity/src/api/oc_network_events.c
new file mode 100644
index 0000000..2149bd3
--- /dev/null
+++ b/libs/iotivity/src/api/oc_network_events.c
@@ -0,0 +1,57 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "oc_network_events.h"
+#include "oc_buffer.h"
+#include "port/oc_connectivity.h"
+#include "port/oc_signal_main_loop.h"
+#include "util/oc_list.h"
+
+OC_LIST(network_events);
+
+static void
+oc_process_network_event(void)
+{
+  oc_network_event_handler_mutex_lock();
+  oc_message_t *head = (oc_message_t *)oc_list_pop(network_events);
+  while (head != NULL) {
+    oc_recv_message(head);
+    head = oc_list_pop(network_events);
+  }
+  oc_network_event_handler_mutex_unlock();
+}
+
+OC_PROCESS(oc_network_events, "");
+OC_PROCESS_THREAD(oc_network_events, ev, data)
+{
+  OC_PROCESS_POLLHANDLER(oc_process_network_event());
+  OC_PROCESS_BEGIN();
+  while (oc_process_is_running(&(oc_network_events))) {
+    OC_PROCESS_YIELD();
+  }
+  OC_PROCESS_END();
+}
+
+void
+oc_network_event(oc_message_t *message)
+{
+  oc_network_event_handler_mutex_lock();
+  oc_list_add(network_events, message);
+  oc_network_event_handler_mutex_unlock();
+
+  oc_process_poll(&(oc_network_events));
+  oc_signal_main_loop();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_rep.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_rep.c b/libs/iotivity/src/api/oc_rep.c
new file mode 100644
index 0000000..b922e1e
--- /dev/null
+++ b/libs/iotivity/src/api/oc_rep.c
@@ -0,0 +1,301 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "oc_rep.h"
+#include "config.h"
+#include "port/oc_assert.h"
+#include "port/oc_log.h"
+#include "util/oc_memb.h"
+
+OC_MEMB(rep_objects, oc_rep_t, EST_NUM_REP_OBJECTS);
+static const CborEncoder g_empty;
+static uint8_t *g_buf;
+CborEncoder g_encoder, root_map, links_array;
+CborError g_err;
+
+void
+oc_rep_new(uint8_t *out_payload, int size)
+{
+  g_err = CborNoError;
+  g_buf = out_payload;
+  cbor_encoder_init(&g_encoder, out_payload, size, 0);
+}
+
+int
+oc_rep_finalize(void)
+{
+  int size = cbor_encoder_get_buffer_size(&g_encoder, g_buf);
+  oc_rep_reset();
+  if (g_err != CborNoError)
+    return -1;
+  return size;
+}
+
+void
+oc_rep_reset(void)
+{
+  g_encoder = g_empty;
+}
+
+static oc_rep_t *
+_alloc_rep(void)
+{
+  oc_rep_t *rep = oc_memb_alloc(&rep_objects);
+#ifdef DEBUG
+  oc_assert(rep != NULL);
+#endif
+  return rep;
+}
+
+static void
+_free_rep(oc_rep_t *rep_value)
+{
+  oc_memb_free(&rep_objects, rep_value);
+}
+
+void
+oc_free_rep(oc_rep_t *rep)
+{
+  if (rep == 0)
+    return;
+  oc_free_rep(rep->next);
+  switch (rep->type) {
+  case BYTE_STRING_ARRAY:
+  case STRING_ARRAY:
+    oc_free_string_array(&rep->value_array);
+    break;
+  case BOOL_ARRAY:
+    oc_free_bool_array(&rep->value_array);
+    break;
+  case DOUBLE_ARRAY:
+    oc_free_double_array(&rep->value_array);
+    break;
+  case INT_ARRAY:
+    oc_free_int_array(&rep->value_array);
+    break;
+  case BYTE_STRING:
+  case STRING:
+    oc_free_string(&rep->value_string);
+    break;
+  case OBJECT:
+    oc_free_rep(rep->value_object);
+    break;
+  case OBJECT_ARRAY:
+    oc_free_rep(rep->value_object_array);
+    break;
+  default:
+    break;
+  }
+  oc_free_string(&rep->name);
+  _free_rep(rep);
+}
+
+/*
+  An Object is a collection of key-value pairs.
+  A value_object value points to the first key-value pair,
+  and subsequent items are accessed via the next pointer.
+
+  An Object Array is a collection of objects, where each object
+  is a collection of key-value pairs.
+  A value_object_array value points to the first object in the
+  array. This object is then traversed via its value_object pointer.
+  Subsequent objects in the object array are then accessed through
+  the next pointer of the first object.
+*/
+
+/* Parse single property */
+static void
+oc_parse_rep_value(CborValue *value, oc_rep_t **rep, CborError *err)
+{
+  size_t k, len;
+  CborValue map, array;
+  *rep = _alloc_rep();
+  oc_rep_t *cur = *rep, **prev = 0;
+  cur->next = 0;
+  cur->value_object_array = 0;
+  /* key */
+  *err |= cbor_value_calculate_string_length(value, &len);
+  len++;
+  oc_alloc_string(&cur->name, len);
+  *err |= cbor_value_copy_text_string(value, (char *)oc_string(cur->name), &len,
+                                      NULL);
+  *err |= cbor_value_advance(value);
+  /* value */
+  switch (value->type) {
+  case CborIntegerType:
+    *err |= cbor_value_get_int64(value, &cur->value_int);
+    cur->type = INT;
+    break;
+  case CborBooleanType:
+    *err |= cbor_value_get_boolean(value, &cur->value_boolean);
+    cur->type = BOOL;
+    break;
+  case CborDoubleType:
+    *err |= cbor_value_get_double(value, &cur->value_double);
+    cur->type = DOUBLE;
+    break;
+  case CborByteStringType:
+    *err |= cbor_value_calculate_string_length(value, &len);
+    len++;
+    oc_alloc_string(&cur->value_string, len);
+    *err |= cbor_value_copy_byte_string(
+      value, oc_cast(cur->value_string, uint8_t), &len, NULL);
+    cur->type = BYTE_STRING;
+    break;
+  case CborTextStringType:
+    *err |= cbor_value_calculate_string_length(value, &len);
+    len++;
+    oc_alloc_string(&cur->value_string, len);
+    *err |= cbor_value_copy_text_string(value, oc_string(cur->value_string),
+                                        &len, NULL);
+    cur->type = STRING;
+    break;
+  case CborMapType: /* when value is a map/object */ {
+    oc_rep_t **obj = &cur->value_object; // object points to list of properties
+    *err |= cbor_value_enter_container(value, &map);
+    while (!cbor_value_at_end(&map)) {
+      oc_parse_rep_value(&map, obj, err);
+      (*obj)->next = 0;
+      obj = &(*obj)->next;
+      *err |= cbor_value_advance(&map);
+    }
+    cur->type = OBJECT;
+  } break;
+  case CborArrayType:
+    *err |= cbor_value_enter_container(value, &array);
+    len = 0;
+    cbor_value_get_array_length(value, &len);
+    if (len == 0) {
+      CborValue t = array;
+      while (!cbor_value_at_end(&t)) {
+        len++;
+        cbor_value_advance(&t);
+      }
+    }
+    k = 0;
+    while (!cbor_value_at_end(&array)) {
+      switch (array.type) {
+      case CborIntegerType:
+        if (k == 0) {
+          oc_new_int_array(&cur->value_array, len);
+          cur->type = INT | ARRAY;
+        }
+        *err |=
+          cbor_value_get_int64(&array, oc_int_array(cur->value_array) + k);
+        break;
+      case CborDoubleType:
+        if (k == 0) {
+          oc_new_double_array(&cur->value_array, len);
+          cur->type = DOUBLE | ARRAY;
+        }
+        *err |=
+          cbor_value_get_double(&array, oc_double_array(cur->value_array) + k);
+        break;
+      case CborBooleanType:
+        if (k == 0) {
+          oc_new_bool_array(&cur->value_array, len);
+          cur->type = BOOL | ARRAY;
+        }
+        *err |=
+          cbor_value_get_boolean(&array, oc_bool_array(cur->value_array) + k);
+        break;
+      case CborByteStringType:
+        if (k == 0) {
+          oc_new_string_array(&cur->value_array, len);
+          cur->type = BYTE_STRING | ARRAY;
+        }
+        *err |= cbor_value_calculate_string_length(&array, &len);
+        len++;
+        *err |= cbor_value_copy_byte_string(
+          &array, (uint8_t *)oc_string_array_get_item(cur->value_array, k),
+          &len, NULL);
+        break;
+      case CborTextStringType:
+        if (k == 0) {
+          oc_new_string_array(&cur->value_array, len);
+          cur->type = STRING | ARRAY;
+        }
+        *err |= cbor_value_calculate_string_length(&array, &len);
+        len++;
+        *err |= cbor_value_copy_text_string(
+          &array, (char *)oc_string_array_get_item(cur->value_array, k), &len,
+          NULL);
+        break;
+      case CborMapType:
+        if (k == 0) {
+          cur->type = OBJECT | ARRAY;
+          cur->value_object_array = _alloc_rep();
+          prev = &cur->value_object_array;
+        } else {
+          (*prev)->next = _alloc_rep();
+          prev = &(*prev)->next;
+        }
+        (*prev)->type = OBJECT;
+        (*prev)->next = 0;
+        oc_rep_t **obj = &(*prev)->value_object;
+        /* Process a series of properties that make up an object of the array */
+        *err |= cbor_value_enter_container(&array, &map);
+        while (!cbor_value_at_end(&map)) {
+          oc_parse_rep_value(&map, obj, err);
+          obj = &(*obj)->next;
+          *err |= cbor_value_advance(&map);
+        }
+        break;
+      default:
+        break;
+      }
+      k++;
+      *err |= cbor_value_advance(&array);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+uint16_t
+oc_parse_rep(const uint8_t *in_payload, uint16_t payload_size,
+             oc_rep_t **out_rep)
+{
+  CborParser parser;
+  CborValue root_value, cur_value, map;
+  CborError err = CborNoError;
+  err |= cbor_parser_init(in_payload, payload_size, 0, &parser, &root_value);
+  if (cbor_value_is_map(&root_value)) {
+    err |= cbor_value_enter_container(&root_value, &cur_value);
+    *out_rep = 0;
+    oc_rep_t **cur = out_rep;
+    while (cbor_value_is_valid(&cur_value)) {
+      oc_parse_rep_value(&cur_value, cur, &err);
+      err |= cbor_value_advance(&cur_value);
+      cur = &(*cur)->next;
+    }
+  } else if (cbor_value_is_array(&root_value)) {
+    err |= cbor_value_enter_container(&root_value, &map);
+    err |= cbor_value_enter_container(&map, &cur_value);
+    *out_rep = 0;
+    oc_rep_t **cur = out_rep;
+    while (cbor_value_is_valid(&cur_value)) {
+      *cur = _alloc_rep();
+      (*cur)->type = OBJECT;
+      oc_parse_rep_value(&cur_value, &(*cur)->value_object, &err);
+      err |= cbor_value_advance(&cur_value);
+      (*cur)->next = 0;
+      cur = &(*cur)->next;
+    }
+  }
+  return (uint16_t)err;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_ri.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_ri.c b/libs/iotivity/src/api/oc_ri.c
new file mode 100644
index 0000000..7af353e
--- /dev/null
+++ b/libs/iotivity/src/api/oc_ri.c
@@ -0,0 +1,1016 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 <stdbool.h>
+#include <stddef.h>
+#include <strings.h>
+
+#include "util/oc_etimer.h"
+#include "util/oc_list.h"
+#include "util/oc_memb.h"
+#include "util/oc_process.h"
+
+#include "messaging/coap/constants.h"
+#include "messaging/coap/engine.h"
+#include "messaging/coap/oc_coap.h"
+
+#include "port/oc_random.h"
+
+#include "oc_buffer.h"
+#include "oc_core_res.h"
+#include "oc_discovery.h"
+#include "oc_events.h"
+#include "oc_network_events.h"
+#include "oc_ri.h"
+#include "oc_uuid.h"
+
+#ifdef OC_SECURITY
+#include "security/oc_acl.h"
+#include "security/oc_dtls.h"
+#endif /* OC_SECURITY */
+
+#ifdef OC_SERVER
+OC_LIST(app_resources);
+OC_LIST(observe_callbacks);
+OC_MEMB(app_resources_s, oc_resource_t, MAX_APP_RESOURCES);
+#endif /* OC_SERVER */
+
+#ifdef OC_CLIENT
+#include "oc_client_state.h"
+OC_LIST(client_cbs);
+OC_MEMB(client_cbs_s, oc_client_cb_t, MAX_NUM_CONCURRENT_REQUESTS);
+#endif /* OC_CLIENT */
+
+OC_LIST(timed_callbacks);
+OC_MEMB(event_callbacks_s, oc_event_callback_t, NUM_OC_CORE_RESOURCES +
+                                                  MAX_APP_RESOURCES +
+                                                  MAX_NUM_CONCURRENT_REQUESTS);
+
+OC_PROCESS(timed_callback_events, "OC timed callbacks");
+
+// TODO: Define and use a  complete set of error codes.
+int oc_stack_errno;
+
+static unsigned int oc_coap_status_codes[__NUM_OC_STATUS_CODES__];
+
+static void
+set_mpro_status_codes(void)
+{
+  /* OK_200 */
+  oc_coap_status_codes[OC_STATUS_OK] = CONTENT_2_05;
+  /* CREATED_201 */
+  oc_coap_status_codes[OC_STATUS_CREATED] = CREATED_2_01;
+  /* NO_CONTENT_204 */
+  oc_coap_status_codes[OC_STATUS_CHANGED] = CHANGED_2_04;
+  /* NO_CONTENT_204 */
+  oc_coap_status_codes[OC_STATUS_DELETED] = DELETED_2_02;
+  /* NOT_MODIFIED_304 */
+  oc_coap_status_codes[OC_STATUS_NOT_MODIFIED] = VALID_2_03;
+  /* BAD_REQUEST_400 */
+  oc_coap_status_codes[OC_STATUS_BAD_REQUEST] = BAD_REQUEST_4_00;
+  /* UNAUTHORIZED_401 */
+  oc_coap_status_codes[OC_STATUS_UNAUTHORIZED] = UNAUTHORIZED_4_01;
+  /* BAD_REQUEST_400 */
+  oc_coap_status_codes[OC_STATUS_BAD_OPTION] = BAD_OPTION_4_02;
+  /* FORBIDDEN_403 */
+  oc_coap_status_codes[OC_STATUS_FORBIDDEN] = FORBIDDEN_4_03;
+  /* NOT_FOUND_404 */
+  oc_coap_status_codes[OC_STATUS_NOT_FOUND] = NOT_FOUND_4_04;
+  /* METHOD_NOT_ALLOWED_405 */
+  oc_coap_status_codes[OC_STATUS_METHOD_NOT_ALLOWED] = METHOD_NOT_ALLOWED_4_05;
+  /* NOT_ACCEPTABLE_406 */
+  oc_coap_status_codes[OC_STATUS_NOT_ACCEPTABLE] = NOT_ACCEPTABLE_4_06;
+  /* REQUEST_ENTITY_TOO_LARGE_413 */
+  oc_coap_status_codes[OC_STATUS_REQUEST_ENTITY_TOO_LARGE] =
+    REQUEST_ENTITY_TOO_LARGE_4_13;
+  /* UNSUPPORTED_MEDIA_TYPE_415 */
+  oc_coap_status_codes[OC_STATUS_UNSUPPORTED_MEDIA_TYPE] =
+    UNSUPPORTED_MEDIA_TYPE_4_15;
+  /* INTERNAL_SERVER_ERROR_500 */
+  oc_coap_status_codes[OC_STATUS_INTERNAL_SERVER_ERROR] =
+    INTERNAL_SERVER_ERROR_5_00;
+  /* NOT_IMPLEMENTED_501 */
+  oc_coap_status_codes[OC_STATUS_NOT_IMPLEMENTED] = NOT_IMPLEMENTED_5_01;
+  /* BAD_GATEWAY_502 */
+  oc_coap_status_codes[OC_STATUS_BAD_GATEWAY] = BAD_GATEWAY_5_02;
+  /* SERVICE_UNAVAILABLE_503 */
+  oc_coap_status_codes[OC_STATUS_SERVICE_UNAVAILABLE] =
+    SERVICE_UNAVAILABLE_5_03;
+  /* GATEWAY_TIMEOUT_504 */
+  oc_coap_status_codes[OC_STATUS_GATEWAY_TIMEOUT] = GATEWAY_TIMEOUT_5_04;
+  /* INTERNAL_SERVER_ERROR_500 */
+  oc_coap_status_codes[OC_STATUS_PROXYING_NOT_SUPPORTED] =
+    PROXYING_NOT_SUPPORTED_5_05;
+}
+
+#ifdef OC_SERVER
+oc_resource_t *
+oc_ri_get_app_resources(void)
+{
+  return oc_list_head(app_resources);
+}
+#endif
+
+int
+oc_status_code(oc_status_t key)
+{
+  return oc_coap_status_codes[key];
+}
+
+int
+oc_ri_get_query_nth_key_value(const char *query, int query_len, char **key,
+                              int *key_len, char **value, int *value_len, int n)
+{
+  int next_pos = -1;
+  int i = 0;
+  char *start = (char *)query, *current, *end = (char *)query + query_len;
+  current = start;
+
+  while (i < (n - 1) && current != NULL) {
+    current = memchr(start, '&', end - start);
+    i++;
+    start = current + 1;
+  }
+
+  current = memchr(start, '=', end - start);
+  if (current != NULL) {
+    *key_len = current - start;
+    *key = start;
+    *value = current + 1;
+    current = memchr(*value, '&', end - *value);
+    if (current == NULL) {
+      *value_len = end - *value;
+    } else {
+      *value_len = current - *value;
+    }
+    next_pos = *value + *value_len - query + 1;
+  }
+  return next_pos;
+}
+
+int
+oc_ri_get_query_value(const char *query, int query_len, const char *key,
+                      char **value)
+{
+  int next_pos = 0, found = -1, kl, vl;
+  char *k;
+  while (next_pos < query_len) {
+    next_pos = oc_ri_get_query_nth_key_value(
+      query + next_pos, query_len - next_pos, &k, &kl, value, &vl, 1);
+    if (next_pos == -1)
+      return -1;
+
+    if (kl == strlen(key) && strncasecmp(key, k, kl) == 0) {
+      found = vl;
+      break;
+    }
+  }
+  return found;
+}
+
+static void
+allocate_events(void)
+{
+  int i = 0;
+  for (i = 0; i < __NUM_OC_EVENT_TYPES__; i++) {
+    oc_events[i] = oc_process_alloc_event();
+  }
+}
+
+static void
+start_processes(void)
+{
+  allocate_events();
+  oc_process_start(&oc_etimer_process, NULL);
+  oc_process_start(&timed_callback_events, NULL);
+  oc_process_start(&coap_engine, NULL);
+  oc_process_start(&message_buffer_handler, NULL);
+
+#ifdef OC_SECURITY
+  oc_process_start(&oc_dtls_handler, NULL);
+#endif
+
+  oc_process_start(&oc_network_events, NULL);
+}
+
+static void
+stop_processes(void)
+{
+  oc_process_exit(&oc_etimer_process);
+  oc_process_exit(&timed_callback_events);
+  oc_process_exit(&coap_engine);
+
+#ifdef OC_SECURITY
+  oc_process_exit(&oc_dtls_handler);
+#endif
+
+  oc_process_exit(&message_buffer_handler);
+}
+
+#ifdef OC_SERVER
+oc_resource_t *
+oc_ri_get_app_resource_by_uri(const char *uri)
+{
+  oc_resource_t *res = oc_ri_get_app_resources();
+  while (res != NULL) {
+    if (oc_string_len(res->uri) == strlen(uri) &&
+        strncmp(uri, oc_string(res->uri), strlen(uri)) == 0)
+      return res;
+    res = res->next;
+  }
+  return res;
+}
+#endif
+
+void
+oc_ri_init(void)
+{
+  oc_random_init(0); // Fix: allow user to seed RNG.
+  oc_clock_init();
+  set_mpro_status_codes();
+
+#ifdef OC_SERVER
+  oc_list_init(app_resources);
+  oc_list_init(observe_callbacks);
+#endif
+
+#ifdef OC_CLIENT
+  oc_list_init(client_cbs);
+#endif
+
+  oc_list_init(timed_callbacks);
+  start_processes();
+  oc_create_discovery_resource();
+}
+
+void
+oc_ri_shutdown(void)
+{
+  oc_random_destroy();
+  stop_processes();
+}
+
+#ifdef OC_SERVER
+oc_resource_t *
+oc_ri_alloc_resource(void)
+{
+  return oc_memb_alloc(&app_resources_s);
+}
+
+void
+oc_ri_delete_resource(oc_resource_t *resource)
+{
+  oc_memb_free(&app_resources_s, resource);
+}
+
+bool
+oc_ri_add_resource(oc_resource_t *resource)
+{
+  bool valid = true;
+
+  if (!resource->get_handler && !resource->put_handler &&
+      !resource->post_handler && !resource->delete_handler)
+    valid = false;
+
+  if (resource->properties & OC_PERIODIC &&
+      resource->observe_period_seconds == 0)
+    valid = false;
+
+  if (valid) {
+    oc_list_add(app_resources, resource);
+  }
+
+  return valid;
+}
+#endif /* OC_SERVER */
+
+void
+oc_ri_remove_timed_event_callback(void *cb_data, oc_trigger_t event_callback)
+{
+  oc_event_callback_t *event_cb =
+    (oc_event_callback_t *)oc_list_head(timed_callbacks);
+
+  while (event_cb != NULL) {
+    if (event_cb->data == cb_data && event_cb->callback == event_callback) {
+      oc_list_remove(timed_callbacks, event_cb);
+      oc_memb_free(&event_callbacks_s, event_cb);
+      break;
+    }
+    event_cb = event_cb->next;
+  }
+}
+
+void
+oc_ri_add_timed_event_callback_ticks(void *cb_data, oc_trigger_t event_callback,
+                                     oc_clock_time_t ticks)
+{
+  oc_event_callback_t *event_cb =
+    (oc_event_callback_t *)oc_memb_alloc(&event_callbacks_s);
+
+  if (event_cb) {
+    event_cb->data = cb_data;
+    event_cb->callback = event_callback;
+    OC_PROCESS_CONTEXT_BEGIN(&timed_callback_events);
+    oc_etimer_set(&event_cb->timer, ticks);
+    OC_PROCESS_CONTEXT_END(&timed_callback_events);
+    oc_list_add(timed_callbacks, event_cb);
+  }
+}
+
+static void
+poll_event_callback_timers(oc_list_t list, struct oc_memb *cb_pool)
+{
+  oc_event_callback_t *event_cb = (oc_event_callback_t *)oc_list_head(list),
+                      *next;
+
+  while (event_cb != NULL) {
+    next = event_cb->next;
+
+    if (oc_etimer_expired(&event_cb->timer)) {
+      if (event_cb->callback(event_cb->data) == DONE) {
+        oc_list_remove(list, event_cb);
+        oc_memb_free(cb_pool, event_cb);
+      } else {
+        OC_PROCESS_CONTEXT_BEGIN(&timed_callback_events);
+        oc_etimer_restart(&event_cb->timer);
+        OC_PROCESS_CONTEXT_END(&timed_callback_events);
+      }
+    }
+
+    event_cb = next;
+  }
+}
+
+static void
+check_event_callbacks(void)
+{
+#ifdef OC_SERVER
+  poll_event_callback_timers(observe_callbacks, &event_callbacks_s);
+#endif /* OC_SERVER */
+  poll_event_callback_timers(timed_callbacks, &event_callbacks_s);
+}
+
+#ifdef OC_SERVER
+static oc_event_callback_retval_t
+periodic_observe_handler(void *data)
+{
+  oc_resource_t *resource = (oc_resource_t *)data;
+
+  if (coap_notify_observers(resource, NULL, NULL)) {
+    return CONTINUE;
+  }
+
+  return DONE;
+}
+
+static oc_event_callback_t *
+get_periodic_observe_callback(oc_resource_t *resource)
+{
+  oc_event_callback_t *event_cb;
+  bool found = false;
+
+  for (event_cb = (oc_event_callback_t *)oc_list_head(observe_callbacks);
+       event_cb; event_cb = event_cb->next) {
+    if (resource == event_cb->data) {
+      found = true;
+      break;
+    }
+  }
+
+  if (found) {
+    return event_cb;
+  }
+
+  return NULL;
+}
+
+static void
+remove_periodic_observe_callback(oc_resource_t *resource)
+{
+  oc_event_callback_t *event_cb = get_periodic_observe_callback(resource);
+
+  if (event_cb) {
+    oc_etimer_stop(&event_cb->timer);
+    oc_list_remove(observe_callbacks, event_cb);
+    oc_memb_free(&event_callbacks_s, event_cb);
+  }
+}
+
+static bool
+add_periodic_observe_callback(oc_resource_t *resource)
+{
+  oc_event_callback_t *event_cb = get_periodic_observe_callback(resource);
+
+  if (!event_cb) {
+    event_cb = (oc_event_callback_t *)oc_memb_alloc(&event_callbacks_s);
+
+    if (!event_cb)
+      return false;
+
+    event_cb->data = resource;
+    event_cb->callback = periodic_observe_handler;
+    OC_PROCESS_CONTEXT_BEGIN(&timed_callback_events);
+    oc_etimer_set(&event_cb->timer,
+                  resource->observe_period_seconds * OC_CLOCK_SECOND);
+    OC_PROCESS_CONTEXT_END(&timed_callback_events);
+    oc_list_add(observe_callbacks, event_cb);
+  }
+
+  return true;
+}
+#endif
+
+oc_interface_mask_t
+oc_ri_get_interface_mask(char *iface, int if_len)
+{
+  oc_interface_mask_t interface = 0;
+  if (OC_BASELINE_IF_LEN == if_len &&
+      strncmp(iface, OC_RSRVD_IF_BASELINE, if_len) == 0)
+    interface |= OC_IF_BASELINE;
+  if (OC_LL_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_LL, if_len) == 0)
+    interface |= OC_IF_LL;
+  if (OC_B_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_B, if_len) == 0)
+    interface |= OC_IF_B;
+  if (OC_R_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_R, if_len) == 0)
+    interface |= OC_IF_R;
+  if (OC_RW_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_RW, if_len) == 0)
+    interface |= OC_IF_RW;
+  if (OC_A_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_A, if_len) == 0)
+    interface |= OC_IF_A;
+  if (OC_S_IF_LEN == if_len && strncmp(iface, OC_RSRVD_IF_S, if_len) == 0)
+    interface |= OC_IF_S;
+  return interface;
+}
+
+static bool
+does_interface_support_method(oc_resource_t *resource,
+                              oc_interface_mask_t interface, oc_method_t method)
+{
+  bool supported = true;
+  switch (interface) {
+  /* Per section 7.5.3 of the OCF Core spec, the following three interfaces
+   * are RETRIEVE-only.
+   */
+  case OC_IF_LL:
+  case OC_IF_S:
+  case OC_IF_R:
+    if (method != OC_GET)
+      supported = false;
+    break;
+  /* Per section 7.5.3 of the OCF Core spec, the following three interfaces
+   * support RETRIEVE, UPDATE.
+   * TODO: Refine logic below after adding logic that identifies
+   * and handles CREATE requests using PUT/POST.
+   */
+  case OC_IF_RW:
+  case OC_IF_B:
+  case OC_IF_BASELINE:
+  /* Per section 7.5.3 of the OCF Core spec, the following interface
+   * supports CREATE, RETRIEVE and UPDATE.
+   */
+  case OC_IF_A:
+    break;
+  }
+  return supported;
+}
+
+bool
+oc_ri_invoke_coap_entity_handler(void *request, void *response, uint8_t *buffer,
+                                 uint16_t buffer_size, int32_t *offset,
+                                 oc_endpoint_t *endpoint)
+{
+  /* Flags that capture status along various stages of processing
+   *  the request.
+   */
+  bool method_impl = true, bad_request = false, success = true;
+
+#ifdef OC_SECURITY
+  bool authorized = true;
+#endif
+
+  /* Parsed CoAP PDU structure. */
+  coap_packet_t *const packet = (coap_packet_t *)request;
+
+  /* This function is a server-side entry point solely for requests.
+   *  Hence, "code" contains the CoAP method code.
+   */
+  oc_method_t method = packet->code;
+
+  /* Initialize request/response objects to be sent up to the app layer. */
+  oc_request_t request_obj;
+  oc_response_buffer_t response_buffer;
+  oc_response_t response_obj;
+
+  response_buffer.buffer = buffer;
+  response_buffer.buffer_size = buffer_size;
+  response_buffer.block_offset = offset;
+  response_buffer.code = 0;
+  response_buffer.response_length = 0;
+
+  response_obj.separate_response = 0;
+  response_obj.response_buffer = &response_buffer;
+
+  request_obj.response = &response_obj;
+  request_obj.request_payload = 0;
+  request_obj.query_len = 0;
+  request_obj.resource = 0;
+  request_obj.origin = endpoint;
+
+  /* Initialize OCF interface selector. */
+  oc_interface_mask_t interface = 0;
+
+  /* Obtain request uri from the CoAP packet. */
+  const char *uri_path;
+  int uri_path_len = coap_get_header_uri_path(request, &uri_path);
+
+  /* Obtain query string from CoAP packet. */
+  const char *uri_query;
+  int uri_query_len = coap_get_header_uri_query(request, &uri_query);
+
+  if (uri_query_len) {
+    request_obj.query = uri_query;
+    request_obj.query_len = uri_query_len;
+
+    /* Check if query string includes interface selection. */
+    char *iface;
+    int if_len = oc_ri_get_query_value(uri_query, uri_query_len, "if", &iface);
+    if (if_len != -1) {
+      interface |= oc_ri_get_interface_mask(iface, if_len);
+    }
+  }
+
+  /* Obtain handle to buffer containing the serialized payload */
+  const uint8_t *payload;
+  int payload_len = coap_get_payload(request, &payload);
+  if (payload_len) {
+    /* Attempt to parse request payload using tinyCBOR via oc_rep helper
+     * functions. The result of this parse is a tree of oc_rep_t structures
+     * which will reflect the schema of the payload.
+     * Any failures while parsing the payload is viewed as an erroneous
+     * request and results in a 4.00 response being sent.
+     */
+    if (oc_parse_rep(payload, payload_len, &request_obj.request_payload) != 0) {
+      LOG("ocri: error parsing request payload\n");
+      bad_request = true;
+    }
+  }
+
+  oc_resource_t *resource, *cur_resource = NULL;
+
+  /* If there were no errors thus far, attempt to locate the specific
+   * resource object that will handle the request using the request uri.
+   */
+  /* Check against list of declared core resources.
+   */
+  if (!bad_request) {
+    int i;
+    for (i = 0; i < NUM_OC_CORE_RESOURCES; i++) {
+      resource = oc_core_get_resource_by_index(i);
+      if (oc_string_len(resource->uri) == (uri_path_len + 1) &&
+          strncmp((const char *)oc_string(resource->uri) + 1, uri_path,
+                  uri_path_len) == 0) {
+        request_obj.resource = cur_resource = resource;
+        break;
+      }
+    }
+  }
+
+#ifdef OC_SERVER
+  /* Check against list of declared application resources.
+   */
+  if (!cur_resource && !bad_request) {
+    for (resource = oc_ri_get_app_resources(); resource;
+         resource = resource->next) {
+      if (oc_string_len(resource->uri) == (uri_path_len + 1) &&
+          strncmp((const char *)oc_string(resource->uri) + 1, uri_path,
+                  uri_path_len) == 0) {
+        request_obj.resource = cur_resource = resource;
+        break;
+      }
+    }
+  }
+#endif
+
+  if (cur_resource) {
+    /* If there was no interface selection, pick the "default interface". */
+    if (interface == 0)
+      interface = cur_resource->default_interface;
+
+    /* Found the matching resource object. Now verify that:
+     * 1) the selected interface is one that is supported by
+     *    the resource, and,
+     * 2) the selected interface supports the request method.
+     *
+     * If not, return a 4.00 response.
+     */
+    if (((interface & ~cur_resource->interfaces) != 0) ||
+        !does_interface_support_method(cur_resource, interface, method))
+      bad_request = true;
+  }
+
+  if (cur_resource && !bad_request) {
+    /* Process a request against a valid resource, request payload, and
+     * interface.
+     */
+
+    /* Initialize oc_rep with a buffer to hold the response payload. "buffer"
+     * points to memory allocated in the messaging layer for the "CoAP
+     * Transaction" to service this request.
+     */
+    oc_rep_new(buffer, buffer_size);
+
+#ifdef OC_SECURITY
+    /* If cur_resource is a coaps:// resource, then query ACL to check if
+     * the requestor (the subject) is authorized to issue this request to
+     * the resource.
+     */
+    if ((cur_resource->properties & OC_SECURE) &&
+        !oc_sec_check_acl(method, cur_resource, endpoint)) {
+      authorized = false;
+    } else
+#endif
+    {
+      /* Invoke a specific request handler for the resource
+             * based on the request method. If the resource has not
+             * implemented that method, then return a 4.05 response.
+             */
+      if (method == OC_GET && cur_resource->get_handler) {
+        cur_resource->get_handler(&request_obj, interface);
+      } else if (method == OC_POST && cur_resource->post_handler) {
+        cur_resource->post_handler(&request_obj, interface);
+      } else if (method == OC_PUT && cur_resource->put_handler) {
+        cur_resource->put_handler(&request_obj, interface);
+      } else if (method == OC_DELETE && cur_resource->delete_handler) {
+        cur_resource->delete_handler(&request_obj, interface);
+      } else {
+        method_impl = false;
+      }
+    }
+  }
+
+  if (payload_len) {
+    /* To the extent that the request payload was parsed, free the
+     * payload structure (and return its memory to the pool).
+     */
+    oc_free_rep(request_obj.request_payload);
+  }
+
+  if (bad_request) {
+    LOG("ocri: Bad request\n");
+    /* Return a 4.00 response */
+    response_buffer.code = oc_status_code(OC_STATUS_BAD_REQUEST);
+    success = false;
+  } else if (!cur_resource) {
+    LOG("ocri: Could not find resource\n");
+    /* Return a 4.04 response if the requested resource was not found */
+    response_buffer.response_length = 0;
+    response_buffer.code = oc_status_code(OC_STATUS_NOT_FOUND);
+    success = false;
+  } else if (!method_impl) {
+    LOG("ocri: Could not find method\n");
+    /* Return a 4.05 response if the resource does not implement the
+     * request method.
+     */
+    response_buffer.response_length = 0;
+    response_buffer.code = oc_status_code(OC_STATUS_METHOD_NOT_ALLOWED);
+    success = false;
+  }
+#ifdef OC_SECURITY
+  else if (!authorized) {
+    LOG("ocri: Subject not authorized\n");
+    /* If the requestor (subject) does not have access granted via an
+     * access control entry in the ACL, then it is not authorized to
+     * access the resource. A 4.03 response is sent.
+     */
+    response_buffer.response_length = 0;
+    response_buffer.code = oc_status_code(OC_STATUS_FORBIDDEN);
+    success = false;
+  }
+#endif
+
+#ifdef OC_SERVER
+  /* If a GET request was successfully processed, then check its
+   *  observe option.
+   */
+  uint32_t observe = 2;
+  if (success && coap_get_header_observe(request, &observe)) {
+    /* Check if the resource is OBSERVABLE */
+    if (cur_resource->properties & OC_OBSERVABLE) {
+      /* If the observe option is set to 0, make an attempt to add the
+       * requesting client as an observer.
+       */
+      if (observe == 0) {
+        if (coap_observe_handler(request, response, cur_resource, endpoint) ==
+            0) {
+          /* If the resource is marked as periodic observable it means
+           * it must be polled internally for updates (which would lead to
+           * notifications being sent). If so, add the resource to a list of
+           * periodic GET callbacks to utilize the framework's internal
+           * polling mechanism.
+           */
+          bool set_observe_option = true;
+          if (cur_resource->properties & OC_PERIODIC) {
+            if (!add_periodic_observe_callback(cur_resource)) {
+              set_observe_option = false;
+              coap_remove_observer_by_token(endpoint, packet->token,
+                                            packet->token_len);
+            }
+          }
+
+          if (set_observe_option) {
+            coap_set_header_observe(response, 0);
+          }
+        }
+      }
+      /* If the observe option is set to 1, make an attempt to remove
+       * the requesting client from the list of observers. In addition,
+       * remove the resource from the list periodic GET callbacks if it
+       * is periodic observable.
+       */
+      else if (observe == 1) {
+        if (coap_observe_handler(request, response, cur_resource, endpoint) >
+            0) {
+          if (cur_resource->properties & OC_PERIODIC) {
+            remove_periodic_observe_callback(cur_resource);
+          }
+        }
+      }
+    }
+  }
+#endif
+
+#ifdef OC_SERVER
+  /* The presence of a separate response handle here indicates a
+   * successful handling of the request by a slow resource.
+   */
+  if (response_obj.separate_response != NULL) {
+    /* Attempt to register a client request to the separate response tracker
+     * and pass in the observe option (if present) or the value 2 as
+     * determined by the code block above. Values 0 and 1 result in their
+     * expected behaviors whereas 2 indicates an absence of an observe
+     * option and hence a one-off request.
+     * Following a successful registration, the separate response tracker
+     * is flagged as "active". In this way, the function that later executes
+     * out-of-band upon availability of the resource state knows it must
+     * send out a response with it.
+     */
+    if (coap_separate_accept(request, response_obj.separate_response, endpoint,
+                             observe) == 1)
+      response_obj.separate_response->active = 1;
+  } else
+#endif
+    if (response_buffer.code == OC_IGNORE) {
+    /* If the server-side logic chooses to reject a request, it sends
+     * below a response code of IGNORE, which results in the messaging
+     * layer freeing the CoAP transaction associated with the request.
+     */
+    erbium_status_code = CLEAR_TRANSACTION;
+  } else {
+#ifdef OC_SERVER
+    /* If the recently handled request was a PUT/POST, it conceivably
+     * altered the resource state, so attempt to notify all observers
+     * of that resource with the change.
+     */
+    if ((method == OC_PUT || method == OC_POST) &&
+        response_buffer.code < oc_status_code(OC_STATUS_BAD_REQUEST))
+      coap_notify_observers(cur_resource, NULL, NULL);
+#endif
+    if (response_buffer.response_length) {
+      coap_set_payload(response, response_buffer.buffer,
+                       response_buffer.response_length);
+      coap_set_header_content_format(response, APPLICATION_CBOR);
+    }
+    /* response_buffer.code at this point contains a valid CoAP status
+     *  code.
+     */
+    coap_set_status_code(response, response_buffer.code);
+  }
+  return success;
+}
+
+#ifdef OC_CLIENT
+static void
+free_client_cb(oc_client_cb_t *cb)
+{
+  oc_free_string(&cb->uri);
+  oc_list_remove(client_cbs, cb);
+  oc_memb_free(&client_cbs_s, cb);
+}
+
+void
+oc_ri_remove_client_cb_by_mid(uint16_t mid)
+{
+  oc_client_cb_t *cb = (oc_client_cb_t *)oc_list_head(client_cbs);
+  while (cb != NULL) {
+    if (cb->mid == mid)
+      break;
+    cb = cb->next;
+  }
+  if (cb)
+    free_client_cb(cb);
+}
+
+oc_event_callback_retval_t
+oc_ri_remove_client_cb(void *data)
+{
+  free_client_cb(data);
+  return DONE;
+}
+
+bool
+oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
+               uint16_t mid)
+{
+  coap_packet_t rst[1];
+  coap_init_message(rst, COAP_TYPE_RST, 0, mid);
+  coap_set_header_observe(rst, 1);
+  coap_set_token(rst, token, token_len);
+  oc_message_t *message = oc_allocate_message();
+  if (message) {
+    message->length = coap_serialize_message(rst, message->data);
+    coap_send_message(message);
+    return true;
+  }
+  return false;
+}
+
+bool
+oc_ri_invoke_client_cb(void *response, oc_endpoint_t *endpoint)
+{
+  uint8_t *payload;
+  int payload_len;
+  coap_packet_t *const pkt = (coap_packet_t *)response;
+  oc_client_cb_t *cb = oc_list_head(client_cbs);
+  int i;
+  /*
+    if con then send ack and process as above
+    -empty ack sent from below by engine
+    if ack with piggyback then process as above
+    -processed below
+    if ack and empty then it is a separate response, and keep cb
+    -handled by separate flag
+    if ack is for block then store data and pass to client
+  */
+
+  unsigned int content_format = APPLICATION_CBOR;
+  coap_get_header_content_format(pkt, &content_format);
+
+  while (cb != NULL) {
+    if (cb->token_len == pkt->token_len &&
+        memcmp(cb->token, pkt->token, pkt->token_len) == 0) {
+
+      /* If content format is not CBOR, then reject response
+         and clear callback
+   If incoming response type is RST, then clear callback
+      */
+      if (content_format != APPLICATION_CBOR || pkt->type == COAP_TYPE_RST) {
+        free_client_cb(cb);
+        break;
+      }
+
+      /* Check code, translate to oc_status_code, store
+   Check observe option:
+         if no observe option, set to -1, else store observe seq
+      */
+      oc_client_response_t client_response;
+      client_response.observe_option = -1;
+      client_response.payload = 0;
+
+      for (i = 0; i < __NUM_OC_STATUS_CODES__; i++) {
+        if (oc_coap_status_codes[i] == pkt->code) {
+          client_response.code = i;
+          break;
+        }
+      }
+      coap_get_header_observe(pkt, &client_response.observe_option);
+
+      bool separate = false;
+      /*
+  if payload exists, process payload and save in client response
+  send client response to callback and return
+      */
+      payload_len = coap_get_payload(response, (const uint8_t **)&payload);
+      if (payload_len) {
+        if (cb->discovery) {
+          if (oc_ri_process_discovery_payload(payload, payload_len, cb->handler,
+                                              endpoint) == OC_STOP_DISCOVERY) {
+            oc_ri_remove_client_cb(cb);
+          }
+        } else {
+          uint16_t err =
+            oc_parse_rep(payload, payload_len, &client_response.payload);
+          if (err == 0) {
+            oc_response_handler_t handler = (oc_response_handler_t)cb->handler;
+            handler(&client_response);
+          }
+          oc_free_rep(client_response.payload);
+        }
+      } else { // no payload
+        if (pkt->type == COAP_TYPE_ACK && pkt->code == 0) {
+          separate = true;
+        } else if (!cb->discovery) {
+          oc_response_handler_t handler = (oc_response_handler_t)cb->handler;
+          handler(&client_response);
+        }
+      }
+
+      /* check observe sequence number:
+   if -1 then remove cb, else keep cb
+         if it is an ACK for a separate response, keep cb
+         if it is a discovery response, keep cb so that it will last
+   for the entirety of OC_CLIENT_CB_TIMEOUT_SECS
+      */
+      if (client_response.observe_option == -1 && !separate && !cb->discovery) {
+        oc_ri_remove_timed_event_callback(cb, &oc_ri_remove_client_cb);
+        free_client_cb(cb);
+      } else
+        cb->observe_seq = client_response.observe_option;
+
+      break;
+    }
+    cb = cb->next;
+  }
+
+  return true;
+}
+
+oc_client_cb_t *
+oc_ri_get_client_cb(const char *uri, oc_server_handle_t *server,
+                    oc_method_t method)
+{
+  oc_client_cb_t *cb = (oc_client_cb_t *)oc_list_head(client_cbs);
+
+  while (cb != NULL) {
+    if (oc_string_len(cb->uri) == strlen(uri) &&
+        strncmp(oc_string(cb->uri), uri, strlen(uri)) == 0 &&
+        memcmp(&cb->server.endpoint, &server->endpoint,
+               sizeof(oc_endpoint_t)) == 0 &&
+        cb->method == method)
+      return cb;
+
+    cb = cb->next;
+  }
+
+  return cb;
+}
+
+oc_client_cb_t *
+oc_ri_alloc_client_cb(const char *uri, oc_server_handle_t *server,
+                      oc_method_t method, void *handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb = oc_memb_alloc(&client_cbs_s);
+  if (!cb)
+    return cb;
+
+  cb->mid = coap_get_mid();
+  oc_new_string(&cb->uri, uri);
+  cb->method = method;
+  cb->qos = qos;
+  cb->handler = handler;
+  cb->token_len = 8;
+  int i = 0;
+  uint16_t r;
+  while (i < cb->token_len) {
+    r = oc_random_rand();
+    memcpy(cb->token + i, &r, sizeof(r));
+    i += sizeof(r);
+  }
+  cb->discovery = false;
+  cb->timestamp = oc_clock_time();
+  cb->observe_seq = -1;
+  memcpy(&cb->server, server, sizeof(oc_server_handle_t));
+
+  oc_list_add(client_cbs, cb);
+  return cb;
+}
+#endif /* OC_CLIENT */
+
+OC_PROCESS_THREAD(timed_callback_events, ev, data)
+{
+  OC_PROCESS_BEGIN();
+  while (1) {
+    OC_PROCESS_YIELD();
+    if (ev == OC_PROCESS_EVENT_TIMER) {
+      check_event_callbacks();
+    }
+  }
+  OC_PROCESS_END();
+}
+
+// TODO:
+// resource collections
+// if method accepted by interface selection
+// resources for presence based discovery

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_server_api.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_server_api.c b/libs/iotivity/src/api/oc_server_api.c
new file mode 100644
index 0000000..8650d27
--- /dev/null
+++ b/libs/iotivity/src/api/oc_server_api.c
@@ -0,0 +1,291 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "messaging/coap/engine.h"
+#include "messaging/coap/oc_coap.h"
+#include "messaging/coap/separate.h"
+#include "oc_api.h"
+#include "oc_constants.h"
+#include "oc_core_res.h"
+
+extern int oc_stack_errno;
+// TODO:
+// 0x01: Couldnt add platform
+// 0x02: Couldnt add device
+// 0x03: CBOR error
+
+void
+oc_add_device(const char *uri, const char *rt, const char *name,
+              const char *spec_version, const char *data_model_version,
+              oc_add_device_cb_t add_device_cb, void *data)
+{
+  oc_string_t *payload;
+
+  payload = oc_core_add_new_device(uri, rt, name, spec_version,
+                                   data_model_version, add_device_cb, data);
+  if (!payload)
+    oc_stack_errno |= 0x02;
+}
+
+void
+oc_init_platform(const char *mfg_name, oc_init_platform_cb_t init_platform_cb,
+                 void *data)
+{
+  oc_string_t *payload;
+
+  payload = oc_core_init_platform(mfg_name, init_platform_cb, data);
+  if (!payload)
+    oc_stack_errno |= 0x01;
+}
+
+int
+oc_get_query_value(oc_request_t *request, const char *key, char **value)
+{
+  return oc_ri_get_query_value(request->query, request->query_len, key, value);
+}
+
+static int
+response_length(void)
+{
+  int size = oc_rep_finalize();
+  return (size <= 2) ? 0 : size;
+}
+
+void
+oc_send_response(oc_request_t *request, oc_status_t response_code)
+{
+  // FIX:: set errno if CBOR encoding failed.
+  request->response->response_buffer->response_length = response_length();
+  request->response->response_buffer->code = oc_status_code(response_code);
+}
+
+void
+oc_ignore_request(oc_request_t *request)
+{
+  request->response->response_buffer->code = OC_IGNORE;
+}
+
+void
+oc_set_delayed_callback(void *cb_data, oc_trigger_t callback, uint16_t seconds)
+{
+  oc_ri_add_timed_event_callback_seconds(cb_data, callback, seconds);
+}
+
+void
+oc_remove_delayed_callback(void *cb_data, oc_trigger_t callback)
+{
+  oc_ri_remove_timed_event_callback(cb_data, callback);
+}
+
+void
+oc_process_baseline_interface(oc_resource_t *resource)
+{
+  oc_rep_set_string_array(root, rt, resource->types);
+  oc_core_encode_interfaces_mask(oc_rep_object(root), resource->interfaces);
+  oc_rep_set_uint(root, p, resource->properties & ~OC_PERIODIC);
+}
+
+#ifdef OC_SERVER
+static int query_iterator;
+
+// FIX: validate uri
+oc_resource_t *
+oc_new_resource(const char *uri, uint8_t num_resource_types, int device)
+{
+  oc_resource_t *resource = oc_ri_alloc_resource();
+  const char *start = uri;
+  size_t end = strlen(uri);
+  oc_alloc_string(&resource->uri, end + 1);
+  strncpy((char *)oc_string(resource->uri), start, end);
+  strcpy((char *)oc_string(resource->uri) + end, (const char *)"");
+  oc_new_string_array(&resource->types, num_resource_types);
+  resource->interfaces = OC_IF_BASELINE;
+  resource->default_interface = OC_IF_BASELINE;
+  resource->observe_period_seconds = 0;
+  resource->properties = OC_ACTIVE;
+  resource->num_observers = 0;
+  resource->device = device;
+  return resource;
+}
+
+void
+oc_resource_bind_resource_interface(oc_resource_t *resource, uint8_t interface)
+{
+  resource->interfaces |= interface;
+}
+
+void
+oc_resource_set_default_interface(oc_resource_t *resource,
+                                  oc_interface_mask_t interface)
+{
+  resource->default_interface = interface;
+}
+
+void
+oc_resource_bind_resource_type(oc_resource_t *resource, const char *type)
+{
+  oc_string_array_add_item(resource->types, (char *)type);
+}
+
+#ifdef OC_SECURITY
+void
+oc_resource_make_secure(oc_resource_t *resource)
+{
+  resource->properties |= OC_SECURE;
+}
+#endif /* OC_SECURITY */
+
+void
+oc_resource_set_discoverable(oc_resource_t *resource)
+{
+  resource->properties |= OC_DISCOVERABLE;
+}
+
+void
+oc_resource_set_observable(oc_resource_t *resource)
+{
+  resource->properties |= OC_OBSERVABLE;
+}
+
+void
+oc_resource_set_periodic_observable(oc_resource_t *resource, uint16_t seconds)
+{
+  resource->properties |= OC_OBSERVABLE | OC_PERIODIC;
+  resource->observe_period_seconds = seconds;
+}
+
+void
+oc_deactivate_resource(oc_resource_t *resource)
+{
+  resource->properties ^= OC_ACTIVE;
+}
+
+void
+oc_resource_set_request_handler(oc_resource_t *resource, oc_method_t method,
+                                oc_request_handler_t handler)
+{
+  switch (method) {
+  case OC_GET:
+    resource->get_handler = handler;
+    break;
+  case OC_POST:
+    resource->post_handler = handler;
+    break;
+  case OC_PUT:
+    resource->put_handler = handler;
+    break;
+  case OC_DELETE:
+    resource->delete_handler = handler;
+    break;
+  default:
+    break;
+  }
+}
+
+bool
+oc_add_resource(oc_resource_t *resource)
+{
+  return oc_ri_add_resource(resource);
+}
+
+void
+oc_delete_resource(oc_resource_t *resource)
+{
+  oc_ri_delete_resource(resource);
+}
+
+void
+oc_init_query_iterator(oc_request_t *request)
+{
+  query_iterator = 0;
+}
+
+int
+oc_interate_query(oc_request_t *request, char **key, int *key_len, char **value,
+                  int *value_len)
+{
+  if (query_iterator >= request->query_len)
+    return -1;
+  query_iterator = oc_ri_get_query_nth_key_value(
+    request->query + query_iterator, request->query_len - query_iterator, key,
+    key_len, value, value_len, 1);
+  return 1;
+}
+
+void
+oc_indicate_separate_response(oc_request_t *request,
+                              oc_separate_response_t *response)
+{
+  request->response->separate_response = response;
+  oc_send_response(request, OC_STATUS_OK);
+}
+
+void
+oc_set_separate_response_buffer(oc_separate_response_t *handle)
+{
+  oc_rep_new(handle->buffer, COAP_MAX_BLOCK_SIZE); // check
+}
+
+void
+oc_send_separate_response(oc_separate_response_t *handle,
+                          oc_status_t response_code)
+{
+  oc_response_buffer_t response_buffer;
+  response_buffer.buffer = handle->buffer;
+  response_buffer.response_length = response_length();
+  response_buffer.code = oc_status_code(response_code);
+
+  coap_separate_t *cur = oc_list_head(handle->requests), *next = NULL;
+  coap_packet_t response[1];
+
+  while (cur != NULL) {
+    next = cur->next;
+    if (cur->observe > 0) {
+      coap_transaction_t *t =
+        coap_new_transaction(coap_get_mid(), &cur->endpoint);
+      if (t) {
+        coap_separate_resume(response, cur, oc_status_code(response_code),
+                             t->mid);
+        coap_set_header_content_format(response, APPLICATION_CBOR);
+        if (cur->observe == 1) {
+          coap_set_header_observe(response, 1);
+        }
+        if (response_buffer.response_length > 0) {
+          coap_set_payload(response, handle->buffer,
+                           response_buffer.response_length);
+        }
+        t->message->length = coap_serialize_message(response, t->message->data);
+        coap_send_transaction(t);
+      }
+      coap_separate_clear(handle, cur);
+    } else {
+      if (coap_notify_observers(NULL, &response_buffer, &cur->endpoint) == 0) {
+        coap_separate_clear(handle, cur);
+      }
+    }
+    cur = next;
+  }
+  if (oc_list_length(handle->requests) == 0) {
+    handle->active = 0;
+  }
+}
+
+int
+oc_notify_observers(oc_resource_t *resource)
+{
+  return coap_notify_observers(resource, NULL, NULL);
+}
+#endif /* OC_SERVER */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_uuid.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_uuid.c b/libs/iotivity/src/api/oc_uuid.c
new file mode 100644
index 0000000..2ceaf7a
--- /dev/null
+++ b/libs/iotivity/src/api/oc_uuid.c
@@ -0,0 +1,119 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "oc_uuid.h"
+#include "port/oc_random.h"
+#include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+void
+oc_str_to_uuid(const char *str, oc_uuid_t *uuid)
+{
+  int i, j = 0, k = 1;
+  uint8_t c = 0;
+
+  for (i = 0; i < strlen(str); i++) {
+    if (str[i] == '-')
+      continue;
+    else if (isalpha(str[i])) {
+      switch (str[i]) {
+      case 65:
+      case 97:
+        c |= 0x0a;
+        break;
+      case 66:
+      case 98:
+        c |= 0x0b;
+        break;
+      case 67:
+      case 99:
+        c |= 0x0c;
+        break;
+      case 68:
+      case 100:
+        c |= 0x0d;
+        break;
+      case 69:
+      case 101:
+        c |= 0x0e;
+        break;
+      case 70:
+      case 102:
+        c |= 0x0f;
+        break;
+      }
+    } else
+      c |= str[i] - 48;
+    if ((j + 1) * 2 == k) {
+      uuid->id[j++] = c;
+      c = 0;
+    } else
+      c = c << 4;
+    k++;
+  }
+}
+
+void
+oc_uuid_to_str(const oc_uuid_t *uuid, char *buffer, int buflen)
+{
+  int i, j = 0;
+  if (buflen < 37)
+    return;
+  for (i = 0; i < 16; i++) {
+    switch (i) {
+    case 4:
+    case 6:
+    case 8:
+    case 10:
+      snprintf(&buffer[j], 2, "-");
+      j++;
+      break;
+    }
+    snprintf(&buffer[j], 3, "%02x", uuid->id[i]);
+    j += 2;
+  }
+}
+
+void
+oc_gen_uuid(oc_uuid_t *uuid)
+{
+  int i;
+  uint16_t r;
+
+  for (i = 0; i < 8; i++) {
+    r = oc_random_rand();
+    memcpy((uint8_t *)&uuid->id[i * 2], (uint8_t *)&r, sizeof(r));
+  }
+
+  /*  From RFC 4122
+      Set the two most significant bits of the
+      clock_seq_hi_and_reserved (8th octect) to
+      zero and one, respectively.
+  */
+  uuid->id[8] &= 0x3f;
+  uuid->id[8] |= 0x40;
+
+  /*  From RFC 4122
+      Set the four most significant bits of the
+      time_hi_and_version field (6th octect) to the
+      4-bit version number from (0 1 0 0 => type 4)
+      Section 4.1.3.
+  */
+  uuid->id[6] &= 0x0f;
+  uuid->id[6] |= 0x40;
+}


[04/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/extract_number_p.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/extract_number_p.h b/libs/tinycbor/include/tinycbor/extract_number_p.h
new file mode 100644
index 0000000..b65ca44
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/extract_number_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#include "cbor.h"
+#include "cborconstants_p.h"
+#include "compilersupport_p.h"
+#include <stdlib.h>
+
+static inline uint16_t get16(const uint8_t *ptr)
+{
+    uint16_t result;
+    memcpy(&result, ptr, sizeof(result));
+    return cbor_ntohs(result);
+}
+
+static inline uint32_t get32(const uint8_t *ptr)
+{
+    uint32_t result;
+    memcpy(&result, ptr, sizeof(result));
+    return cbor_ntohl(result);
+}
+
+static inline uint64_t get64(const uint8_t *ptr)
+{
+    uint64_t result;
+    memcpy(&result, ptr, sizeof(result));
+    return cbor_ntohll(result);
+}
+
+static CborError extract_number(const uint8_t **ptr, const uint8_t *end, uint64_t *len)
+{
+    uint8_t additional_information = **ptr & SmallValueMask;
+    ++*ptr;
+    if (additional_information < Value8Bit) {
+        *len = additional_information;
+        return CborNoError;
+    }
+    if (unlikely(additional_information > Value64Bit))
+        return CborErrorIllegalNumber;
+
+    size_t bytesNeeded = (size_t)(1 << (additional_information - Value8Bit));
+    if (unlikely(bytesNeeded > (size_t)(end - *ptr))) {
+        return CborErrorUnexpectedEOF;
+    } else if (bytesNeeded == 1) {
+        *len = (uint8_t)(*ptr)[0];
+    } else if (bytesNeeded == 2) {
+        *len = get16(*ptr);
+    } else if (bytesNeeded == 4) {
+        *len = get32(*ptr);
+    } else {
+        *len = get64(*ptr);
+    }
+    *ptr += bytesNeeded;
+    return CborNoError;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/math_support_p.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/math_support_p.h b/libs/tinycbor/include/tinycbor/math_support_p.h
new file mode 100644
index 0000000..676f781
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/math_support_p.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef MATH_SUPPORT_H
+#define MATH_SUPPORT_H
+
+#include <math.h>
+
+/* this function was copied & adapted from RFC 7049 Appendix D */
+static inline double decode_half(unsigned short half)
+{
+#ifdef __F16C__
+    return _cvtsh_ss(half);
+#else
+    int exp = (half >> 10) & 0x1f;
+    int mant = half & 0x3ff;
+    double val;
+    if (exp == 0) val = ldexp(mant, -24);
+    else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
+    else val = mant == 0 ? INFINITY : NAN;
+    return half & 0x8000 ? -val : val;
+#endif
+}
+
+#endif // MATH_SUPPORT_H
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/tinycbor/pkg.yml b/libs/tinycbor/pkg.yml
new file mode 100644
index 0000000..3eb846d
--- /dev/null
+++ b/libs/tinycbor/pkg.yml
@@ -0,0 +1,26 @@
+#
+# 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: libs/tinycbor 
+pkg.description: CBOR encoding/decoding library 
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.cflags: -DWITHOUT_OPEN_MEMSTREAM -I../include/tinycbor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborencoder.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborencoder.c b/libs/tinycbor/src/cborencoder.c
new file mode 100644
index 0000000..eef05cd
--- /dev/null
+++ b/libs/tinycbor/src/cborencoder.c
@@ -0,0 +1,629 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborconstants_p.h"
+#include "compilersupport_p.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "assert_p.h"       /* Always include last */
+
+/**
+ * \defgroup CborEncoding Encoding to CBOR
+ * \brief Group of functions used to encode data to CBOR.
+ *
+ * CborEncoder is used to encode data into a CBOR stream. The outermost
+ * CborEncoder is initialized by calling cbor_encoder_init(), with the buffer
+ * where the CBOR stream will be stored. The outermost CborEncoder is usually
+ * used to encode exactly one item, most often an array or map. It is possible
+ * to encode more than one item, but care must then be taken on the decoder
+ * side to ensure the state is reset after each item was decoded.
+ *
+ * Nested CborEncoder objects are created using cbor_encoder_create_array() and
+ * cbor_encoder_create_map(), later closed with cbor_encoder_close_container()
+ * or cbor_encoder_close_container_checked(). The pairs of creation and closing
+ * must be exactly matched and their parameters are always the same.
+ *
+ * CborEncoder writes directly to the user-supplied buffer, without extra
+ * buffering. CborEncoder does not allocate memory and CborEncoder objects are
+ * usually created on the stack of the encoding functions.
+ *
+ * The example below initializes a CborEncoder object with a buffer and encodes
+ * a single integer.
+ *
+ * \code
+ *      uint8_t buf[16];
+ *      CborEncoder encoder;
+ *      cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ *      cbor_encode_int(&encoder, some_value);
+ * \endcode
+ *
+ * As explained before, usually the outermost CborEncoder object is used to add
+ * one array or map, which in turn contains multiple elements. The example
+ * below creates a CBOR map with one element: a key "foo" and a boolean value.
+ *
+ * \code
+ *      uint8_t buf[16];
+ *      CborEncoder encoder, mapEncoder;
+ *      cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ *      cbor_encoder_create_map(&encoder, &mapEncoder, 1);
+ *      cbor_encode_text_stringz(&mapEncoder, "foo");
+ *      cbor_encode_boolean(&mapEncoder, some_value);
+ *      cbor_encoder_close_container(&encoder, &mapEncoder);
+ * \endcode
+ *
+ * <h3 class="groupheader">Error checking and buffer size</h2>
+ *
+ * All functions operating on CborEncoder return a condition of type CborError.
+ * If the encoding was successful, they return CborNoError. Some functions do
+ * extra checking on the input provided and may return some other error
+ * conditions (for example, cbor_encode_simple_value() checks that the type is
+ * of the correct type).
+ *
+ * In addition, all functions check whether the buffer has enough bytes to
+ * encode the item being appended. If that is not possible, they return
+ * CborErrorOutOfMemory.
+ *
+ * It is possible to continue with the encoding of data past the first function
+ * that returns CborErrorOutOfMemory. CborEncoder functions will not overrun
+ * the buffer, but will instead count how many more bytes are needed to
+ * complete the encoding. At the end, you can obtain that count by calling
+ * cbor_encoder_get_extra_bytes_needed().
+ *
+ * \section1 Finalizing the encoding
+ *
+ * Once all items have been appended and the containers have all been properly
+ * closed, the user-supplied buffer will contain the CBOR stream and may be
+ * immediately used. To obtain the size of the buffer, call
+ * cbor_encoder_get_buffer_size() with the original buffer pointer.
+ *
+ * The example below illustrates how one can encode an item with error checking
+ * and then pass on the buffer for network sending.
+ *
+ * \code
+ *      uint8_t buf[16];
+ *      CborError err;
+ *      CborEncoder encoder, mapEncoder;
+ *      cbor_encoder_init(&encoder, &buf, sizeof(buf), 0);
+ *      err = cbor_encoder_create_map(&encoder, &mapEncoder, 1);
+ *      if (!err)
+ *          return err;
+ *      err = cbor_encode_text_stringz(&mapEncoder, "foo");
+ *      if (!err)
+ *          return err;
+ *      err = cbor_encode_boolean(&mapEncoder, some_value);
+ *      if (!err)
+ *          return err;
+ *      err = cbor_encoder_close_container_checked(&encoder, &mapEncoder);
+ *      if (!err)
+ *          return err;
+ *
+ *      size_t len = cbor_encoder_get_buffer_size(&encoder, buf);
+ *      send_payload(buf, len);
+ *      return CborNoError;
+ * \endcode
+ *
+ * Finally, the example below illustrates expands on the one above and also
+ * deals with dynamically growing the buffer if the initial allocation wasn't
+ * big enough. Note the two places where the error checking was replaced with
+ * an assertion, showing where the author assumes no error can occur.
+ *
+ * \code
+ * uint8_t *encode_string_array(const char **strings, int n, size_t *bufsize)
+ * {
+ *     CborError err;
+ *     CborEncoder encoder, arrayEncoder;
+ *     size_t size = 256;
+ *     uint8_t *buf = NULL;
+ *
+ *     while (1) {
+ *         int i;
+ *         size_t more_bytes;
+ *         uint8_t *nbuf = realloc(buf, size);
+ *         if (nbuf == NULL)
+ *             goto error;
+ *         buf = nbuf;
+ *
+ *         cbor_encoder_init(&encoder, &buf, size, 0);
+ *         err = cbor_encoder_create_array(&encoder, &arrayEncoder, n);
+ *         assert(err);         // can't fail, the buffer is always big enough
+ *
+ *         for (i = 0; i < n; ++i) {
+ *             err = cbor_encode_text_stringz(&arrayEncoder, strings[i]);
+ *             if (err && err != CborErrorOutOfMemory)
+ *                 goto error;
+ *         }
+ *
+ *         err = cbor_encoder_close_container_checked(&encoder, &arrayEncoder);
+ *         assert(err);         // shouldn't fail!
+ *
+ *         more_bytes = cbor_encoder_get_extra_bytes_needed(encoder);
+ *         if (more_size) {
+ *             // buffer wasn't big enough, try again
+ *             size += more_bytes;
+ *             continue;
+ *         }
+ *
+ *         *bufsize = cbor_encoder_get_buffer_size(encoder, buf);
+ *         return buf;
+ *     }
+ *  error:
+ *     free(buf);
+ *     return NULL;
+ *  }
+ * \endcode
+ */
+
+/**
+ * \addtogroup CborEncoding
+ * @{
+ */
+
+/**
+ * \struct CborEncoder
+ * Structure used to encode to CBOR.
+ */
+
+/**
+ * Initializes a CborEncoder structure \a encoder by pointing it to buffer \a
+ * buffer of size \a size. The \a flags field is currently unused and must be
+ * zero.
+ */
+void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags)
+{
+    encoder->ptr = buffer;
+    encoder->end = buffer + size;
+    encoder->added = 0;
+    encoder->flags = flags;
+}
+
+static inline void put16(void *where, uint16_t v)
+{
+    v = cbor_htons(v);
+    memcpy(where, &v, sizeof(v));
+}
+
+/* Note: Since this is currently only used in situations where OOM is the only
+ * valid error, we KNOW this to be true.  Thus, this function now returns just 'true',
+ * but if in the future, any function starts returning a non-OOM error, this will need
+ * to be changed to the test.  At the moment, this is done to prevent more branches
+ * being created in the tinycbor output */
+static inline bool isOomError(CborError err)
+{
+    (void) err;
+    return true;
+}
+
+static inline void put32(void *where, uint32_t v)
+{
+    v = cbor_htonl(v);
+    memcpy(where, &v, sizeof(v));
+}
+
+static inline void put64(void *where, uint64_t v)
+{
+    v = cbor_htonll(v);
+    memcpy(where, &v, sizeof(v));
+}
+
+static inline bool would_overflow(CborEncoder *encoder, size_t len)
+{
+    ptrdiff_t remaining = (ptrdiff_t)encoder->end;
+    remaining -= remaining ? (ptrdiff_t)encoder->ptr : encoder->bytes_needed;
+    remaining -= (ptrdiff_t)len;
+    return unlikely(remaining < 0);
+}
+
+static inline void advance_ptr(CborEncoder *encoder, size_t n)
+{
+    if (encoder->end)
+        encoder->ptr += n;
+    else
+        encoder->bytes_needed += n;
+}
+
+static inline CborError append_to_buffer(CborEncoder *encoder, const void *data, size_t len)
+{
+    if (would_overflow(encoder, len)) {
+        if (encoder->end != NULL) {
+            len -= encoder->end - encoder->ptr;
+            encoder->end = NULL;
+            encoder->bytes_needed = 0;
+        }
+
+        advance_ptr(encoder, len);
+        return CborErrorOutOfMemory;
+    }
+
+    memcpy(encoder->ptr, data, len);
+    encoder->ptr += len;
+    return CborNoError;
+}
+
+static inline CborError append_byte_to_buffer(CborEncoder *encoder, uint8_t byte)
+{
+    return append_to_buffer(encoder, &byte, 1);
+}
+
+static inline CborError encode_number_no_update(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
+{
+    /* Little-endian would have been so much more convenient here:
+     * We could just write at the beginning of buf but append_to_buffer
+     * only the necessary bytes.
+     * Since it has to be big endian, do it the other way around:
+     * write from the end. */
+    uint64_t buf[2];
+    uint8_t *const bufend = (uint8_t *)buf + sizeof(buf);
+    uint8_t *bufstart = bufend - 1;
+    put64(buf + 1, ui);     /* we probably have a bunch of zeros in the beginning */
+
+    if (ui < Value8Bit) {
+        *bufstart += shiftedMajorType;
+    } else {
+        unsigned more = 0;
+        if (ui > 0xffU)
+            ++more;
+        if (ui > 0xffffU)
+            ++more;
+        if (ui > 0xffffffffU)
+            ++more;
+        bufstart -= (size_t)1 << more;
+        *bufstart = shiftedMajorType + Value8Bit + more;
+    }
+
+    return append_to_buffer(encoder, bufstart, bufend - bufstart);
+}
+
+static inline CborError encode_number(CborEncoder *encoder, uint64_t ui, uint8_t shiftedMajorType)
+{
+    ++encoder->added;
+    return encode_number_no_update(encoder, ui, shiftedMajorType);
+}
+
+/**
+ * Appends the unsigned 64-bit integer \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * \sa cbor_encode_negative_int, cbor_encode_int
+ */
+CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value)
+{
+    return encode_number(encoder, value, UnsignedIntegerType << MajorTypeShift);
+}
+
+/**
+ * Appends the negative 64-bit integer whose absolute value is \a
+ * absolute_value to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_uint, cbor_encode_int
+ */
+CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value)
+{
+    return encode_number(encoder, absolute_value, NegativeIntegerType << MajorTypeShift);
+}
+
+/**
+ * Appends the signed 64-bit integer \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * \sa cbor_encode_negative_int, cbor_encode_uint
+ */
+CborError cbor_encode_int(CborEncoder *encoder, int64_t value)
+{
+    /* adapted from code in RFC 7049 appendix C (pseudocode) */
+    uint64_t ui = value >> 63;              /* extend sign to whole length */
+    uint8_t majorType = ui & 0x20;          /* extract major type */
+    ui ^= value;                            /* complement negatives */
+    return encode_number(encoder, ui, majorType);
+}
+
+/**
+ * Appends the CBOR Simple Type of value \a value to the CBOR stream provided by
+ * \a encoder.
+ *
+ * This function may return error CborErrorIllegalSimpleType if the \a value
+ * variable contains a number that is not a valid simple type.
+ */
+CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value)
+{
+#ifndef CBOR_ENCODER_NO_CHECK_USER
+    /* check if this is a valid simple type */
+    if (value >= HalfPrecisionFloat && value <= Break)
+        return CborErrorIllegalSimpleType;
+#endif
+    return encode_number(encoder, value, SimpleTypesType << MajorTypeShift);
+}
+
+/**
+ * Appends the floating-point value of type \a fpType and pointed to by \a
+ * value to the CBOR stream provided by \a encoder. The value of \a fpType must
+ * be one of CborHalfFloatType, CborFloatType or CborDoubleType, otherwise the
+ * behavior of this function is undefined.
+ *
+ * This function is useful for code that needs to pass through floating point
+ * values but does not wish to have the actual floating-point code.
+ *
+ * \sa cbor_encode_half_float, cbor_encode_float, cbor_encode_double
+ */
+CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value)
+{
+    uint8_t buf[1 + sizeof(uint64_t)];
+    assert(fpType == CborHalfFloatType || fpType == CborFloatType || fpType == CborDoubleType);
+    buf[0] = fpType;
+
+    unsigned size = 2U << (fpType - CborHalfFloatType);
+    if (size == 8)
+        put64(buf + 1, *(const uint64_t*)value);
+    else if (size == 4)
+        put32(buf + 1, *(const uint32_t*)value);
+    else
+        put16(buf + 1, *(const uint16_t*)value);
+    ++encoder->added;
+    return append_to_buffer(encoder, buf, size + 1);
+}
+
+/**
+ * Appends the CBOR tag \a tag to the CBOR stream provided by \a encoder.
+ *
+ * \sa CborTag
+ */
+CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag)
+{
+    /* tags don't count towards the number of elements in an array or map */
+    return encode_number_no_update(encoder, tag, TagType << MajorTypeShift);
+}
+
+static CborError encode_string(CborEncoder *encoder, size_t length, uint8_t shiftedMajorType, const void *string)
+{
+    CborError err = encode_number(encoder, length, shiftedMajorType);
+    if (err && !isOomError(err))
+        return err;
+    return append_to_buffer(encoder, string, length);
+}
+
+/**
+ * \fn CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
+ *
+ * Appends the null-terminated text string \a string to the CBOR stream
+ * provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
+ * TinyCBOR makes no verification of correctness. The terminating null is not
+ * included in the stream.
+ *
+ * \sa cbor_encode_text_string, cbor_encode_byte_string
+ */
+
+/**
+ * Appends the text string \a string of length \a length to the CBOR stream
+ * provided by \a encoder. CBOR requires that \a string be valid UTF-8, but
+ * TinyCBOR makes no verification of correctness.
+ *
+ * \sa CborError cbor_encode_text_stringz, cbor_encode_byte_string
+ */
+CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length)
+{
+    return encode_string(encoder, length, ByteStringType << MajorTypeShift, string);
+}
+
+/**
+ * Appends the byte string \a string of length \a length to the CBOR stream
+ * provided by \a encoder. CBOR byte strings are arbitrary raw data.
+ *
+ * \sa cbor_encode_text_stringz, cbor_encode_text_string
+ */
+CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length)
+{
+    return encode_string(encoder, length, TextStringType << MajorTypeShift, string);
+}
+
+#ifdef __GNUC__
+__attribute__((noinline))
+#endif
+static CborError create_container(CborEncoder *encoder, CborEncoder *container, size_t length, uint8_t shiftedMajorType)
+{
+    CborError err;
+    container->ptr = encoder->ptr;
+    container->end = encoder->end;
+    ++encoder->added;
+    container->added = 0;
+
+    cbor_static_assert(((MapType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == CborIteratorFlag_ContainerIsMap);
+    cbor_static_assert(((ArrayType << MajorTypeShift) & CborIteratorFlag_ContainerIsMap) == 0);
+    container->flags = shiftedMajorType & CborIteratorFlag_ContainerIsMap;
+
+    if (length == CborIndefiniteLength) {
+        container->flags |= CborIteratorFlag_UnknownLength;
+        err = append_byte_to_buffer(container, shiftedMajorType + IndefiniteLength);
+    } else {
+        err = encode_number_no_update(container, length, shiftedMajorType);
+    }
+    if (err && !isOomError(err))
+        return err;
+
+    return CborNoError;
+}
+
+/**
+ * Creates a CBOR array in the CBOR stream provided by \a encoder and
+ * initializes \a arrayEncoder so that items can be added to the array using
+ * the CborEncoder functions. The array must be terminated by calling either
+ * cbor_encoder_close_container() or cbor_encoder_close_container_checked()
+ * with the same \a encoder and \a arrayEncoder parameters.
+ *
+ * The number of items inserted into the array must be exactly \a length items,
+ * otherwise the stream is invalid. If the number of items is not known when
+ * creating the array, the constant \ref CborIndefiniteLength may be passed as
+ * length instead.
+ *
+ * \sa cbor_encoder_create_map
+ */
+CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length)
+{
+    return create_container(encoder, arrayEncoder, length, ArrayType << MajorTypeShift);
+}
+
+/**
+ * Creates a CBOR map in the CBOR stream provided by \a encoder and
+ * initializes \a mapEncoder so that items can be added to the map using
+ * the CborEncoder functions. The map must be terminated by calling either
+ * cbor_encoder_close_container() or cbor_encoder_close_container_checked()
+ * with the same \a encoder and \a mapEncoder parameters.
+ *
+ * The number of pair of items inserted into the map must be exactly \a length
+ * items, otherwise the stream is invalid. If the number of items is not known
+ * when creating the map, the constant \ref CborIndefiniteLength may be passed as
+ * length instead.
+ *
+ * \b{Implementation limitation:} TinyCBOR cannot encode more than SIZE_MAX/2
+ * key-value pairs in the stream. If the length \a length is larger than this
+ * value, this function returns error CborErrorDataTooLarge.
+ *
+ * \sa cbor_encoder_create_array
+ */
+CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length)
+{
+    if (length != CborIndefiniteLength && length > SIZE_MAX / 2)
+        return CborErrorDataTooLarge;
+    return create_container(encoder, mapEncoder, length, MapType << MajorTypeShift);
+}
+
+/**
+ * Closes the CBOR container (array or map) provided by \a containerEncoder and
+ * updates the CBOR stream provided by \a encoder. Both parameters must be the
+ * same as were passed to cbor_encoder_create_array() or
+ * cbor_encoder_create_map().
+ *
+ * This function does not verify that the number of items (or pair of items, in
+ * the case of a map) was correct. To execute that verification, call
+ * cbor_encoder_close_container_checked() instead.
+ *
+ * \sa cbor_encoder_create_array(), cbor_encoder_create_map()
+ */
+CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder)
+{
+    if (encoder->end)
+        encoder->ptr = containerEncoder->ptr;
+    else
+        encoder->bytes_needed = containerEncoder->bytes_needed;
+    encoder->end = containerEncoder->end;
+    if (containerEncoder->flags & CborIteratorFlag_UnknownLength)
+        return append_byte_to_buffer(encoder, BreakByte);
+    return CborNoError;
+}
+
+/**
+ * \fn CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
+ *
+ * Appends the boolean value \a value to the CBOR stream provided by \a encoder.
+ */
+
+/**
+ * \fn CborError cbor_encode_null(CborEncoder *encoder)
+ *
+ * Appends the CBOR type representing a null value to the CBOR stream provided
+ * by \a encoder.
+ *
+ * \sa cbor_encode_undefined()
+ */
+
+/**
+ * \fn CborError cbor_encode_undefined(CborEncoder *encoder)
+ *
+ * Appends the CBOR type representing an undefined value to the CBOR stream
+ * provided by \a encoder.
+ *
+ * \sa cbor_encode_null()
+ */
+
+/**
+ * \fn CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
+ *
+ * Appends the IEEE 754 half-precision (16-bit) floating point value pointed to
+ * by \a value to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_float(), cbor_encode_double()
+ */
+
+/**
+ * \fn CborError cbor_encode_float(CborEncoder *encoder, float value)
+ *
+ * Appends the IEEE 754 single-precision (32-bit) floating point value \a value
+ * to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_double()
+ */
+
+/**
+ * \fn CborError cbor_encode_double(CborEncoder *encoder, double value)
+ *
+ * Appends the IEEE 754 double-precision (64-bit) floating point value \a value
+ * to the CBOR stream provided by \a encoder.
+ *
+ * \sa cbor_encode_floating_point(), cbor_encode_half_float(), cbor_encode_float()
+ */
+
+/**
+ * \fn size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
+ *
+ * Returns the total size of the buffer starting at \a buffer after the
+ * encoding finished without errors. The \a encoder and \a buffer arguments
+ * must be the same as supplied to cbor_encoder_init().
+ *
+ * If the encoding process had errors, the return value of this function is
+ * meaningless. If the only errors were CborErrorOutOfMemory, instead use
+ * cbor_encoder_get_extra_bytes_needed() to find out by how much to grow the
+ * buffer before encoding again.
+ *
+ * See \ref CborEncoding for an example of using this function.
+ *
+ * \sa cbor_encoder_init(), cbor_encoder_get_extra_bytes_needed(), CborEncoding
+ */
+
+/**
+ * \fn size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
+ *
+ * Returns how many more bytes the original buffer supplied to
+ * cbor_encoder_init() needs to be extended by so that no CborErrorOutOfMemory
+ * condition will happen for the encoding. If the buffer was big enough, this
+ * function returns 0. The \a encoder must be the original argument as passed
+ * to cbor_encoder_init().
+ *
+ * This function is usually called after an encoding sequence ended with one or
+ * more CborErrorOutOfMemory errors, but no other error. If any other error
+ * happened, the return value of this function is meaningless.
+ *
+ * See \ref CborEncoding for an example of using this function.
+ *
+ * \sa cbor_encoder_init(), cbor_encoder_get_buffer_size(), CborEncoding
+ */
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborencoder_close_container_checked.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborencoder_close_container_checked.c b/libs/tinycbor/src/cborencoder_close_container_checked.c
new file mode 100644
index 0000000..cad8335
--- /dev/null
+++ b/libs/tinycbor/src/cborencoder_close_container_checked.c
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborconstants_p.h"
+#include "compilersupport_p.h"
+#include "extract_number_p.h"
+
+#include <assert.h>
+
+#include "assert_p.h"       /* Always include last */
+
+/**
+ * \addtogroup CborEncoding
+ * @{
+ */
+
+/**
+ *
+ * Closes the CBOR container (array or map) provided by \a containerEncoder and
+ * updates the CBOR stream provided by \a encoder. Both parameters must be the
+ * same as were passed to cbor_encoder_create_array() or
+ * cbor_encoder_create_map().
+ *
+ * Unlike cbor_encoder_close_container(), this function checks that the number
+ * of items (or pair of items, in the case of a map) was correct. If the number
+ * of items inserted does not match the length originally passed to
+ * cbor_encoder_create_array() or cbor_encoder_create_map(), this function
+ * returns either CborErrorTooFewItems or CborErrorTooManyItems.
+ *
+ * \sa cbor_encoder_create_array(), cbor_encoder_create_map()
+ */
+CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder)
+{
+    const uint8_t *ptr = encoder->ptr;
+    CborError err = cbor_encoder_close_container(encoder, containerEncoder);
+    if (containerEncoder->flags & CborIteratorFlag_UnknownLength || encoder->end == NULL)
+        return err;
+
+    /* check what the original length was */
+    uint64_t actually_added;
+    err = extract_number(&ptr, encoder->ptr, &actually_added);
+    if (err)
+        return err;
+
+    if (containerEncoder->flags & CborIteratorFlag_ContainerIsMap) {
+        if (actually_added > SIZE_MAX / 2)
+            return CborErrorDataTooLarge;
+        actually_added *= 2;
+    }
+    return actually_added == containerEncoder->added ? CborNoError :
+           actually_added < containerEncoder->added ? CborErrorTooManyItems : CborErrorTooFewItems;
+}
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cborerrorstrings.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cborerrorstrings.c b/libs/tinycbor/src/cborerrorstrings.c
new file mode 100644
index 0000000..d2fe42f
--- /dev/null
+++ b/libs/tinycbor/src/cborerrorstrings.c
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include "cbor.h"
+
+#ifndef _
+#  define _(msg)    msg
+#endif
+
+/**
+ * \enum CborError
+ * \ingroup CborGlobals
+ * The CborError enum contains the possible error values used by the CBOR encoder and decoder.
+ *
+ * TinyCBOR functions report success by returning CborNoError, or one error
+ * condition by returning one of the values below. One exception is the
+ * out-of-memory condition (CborErrorOutOfMemory), which the functions for \ref
+ * CborEncoding may report in bit-wise OR with other conditions.
+ *
+ * This technique allows code to determine whether the only error condition was
+ * a lack of buffer space, which may not be a fatal condition if the buffer can
+ * be resized. Additionally, the functions for \ref CborEncoding may continue
+ * to be used even after CborErrorOutOfMemory is returned, and instead they
+ * will simply calculate the extra space needed.
+ *
+ * \value CborNoError                   No error occurred
+ * \omitvalue CborUnknownError
+ * \value CborErrorUnknownLength        Request for the length of an array, map or string whose length is not provided in the CBOR stream
+ * \value CborErrorAdvancePastEOF       Not enough data in the stream to decode item (decoding would advance past end of stream)
+ * \value CborErrorIO                   An I/O error occurred, probably due to an out-of-memory situation
+ * \value CborErrorGarbageAtEnd         Bytes exist past the end of the CBOR stream
+ * \value CborErrorUnexpectedEOF        End of stream reached unexpectedly
+ * \value CborErrorUnexpectedBreak      A CBOR break byte was found where not expected
+ * \value CborErrorUnknownType          An unknown type (future extension to CBOR) was found in the stream
+ * \value CborErrorIllegalType          An invalid type was found while parsing a chunked CBOR string
+ * \value CborErrorIllegalNumber        An illegal initial byte (encoding unspecified additional information) was found
+ * \value CborErrorIllegalSimpleType    An illegal encoding of a CBOR Simple Type of value less than 32 was found
+ * \omitvalue CborErrorUnknownSimpleType
+ * \omitvalue CborErrorUnknownTag
+ * \omitvalue CborErrorInappropriateTagForType
+ * \omitvalue CborErrorDuplicateObjectKeys
+ * \value CborErrorInvalidUtf8TextString Illegal UTF-8 encoding found while parsing CBOR Text String
+ * \value CborErrorTooManyItems         Too many items were added to CBOR map or array of pre-determined length
+ * \value CborErrorTooFewItems          Too few items were added to CBOR map or array of pre-determeined length
+ * \value CborErrorDataTooLarge         Data item size exceeds TinyCBOR's implementation limits
+ * \value CborErrorNestingTooDeep       Data item nesting exceeds TinyCBOR's implementation limits
+ * \omitvalue CborErrorUnsupportedType
+ * \value CborErrorJsonObjectKeyIsAggregate Conversion to JSON failed because the key in a map is a CBOR map or array
+ * \value CborErrorJsonObjectKeyNotString Conversion to JSON failed because the key in a map is not a text string
+ * \value CborErrorOutOfMemory          During CBOR encoding, the buffer provided is insufficient for encoding the data item;
+ *                                      in other situations, TinyCBOR failed to allocate memory
+ * \value CborErrorInternalError        An internal error occurred in TinyCBOR
+ */
+
+/**
+ * \ingroup CborGlobals
+ * Returns the error string corresponding to the CBOR error condition \a error.
+ */
+const char *cbor_error_string(CborError error)
+{
+    switch (error) {
+    case CborNoError:
+        return "";
+
+    case CborUnknownError:
+        return _("unknown error");
+
+    case CborErrorOutOfMemory:
+        return _("out of memory/need more memory");
+
+    case CborErrorUnknownLength:
+        return _("unknown length (attempted to get the length of a map/array/string of indeterminate length");
+
+    case CborErrorAdvancePastEOF:
+        return _("attempted to advance past EOF");
+
+    case CborErrorIO:
+        return _("I/O error");
+
+    case CborErrorGarbageAtEnd:
+        return _("garbage after the end of the content");
+
+    case CborErrorUnexpectedEOF:
+        return _("unexpected end of data");
+
+    case CborErrorUnexpectedBreak:
+        return _("unexpected 'break' byte");
+
+    case CborErrorUnknownType:
+        return _("illegal byte (encodes future extension type)");
+
+    case CborErrorIllegalType:
+        return _("mismatched string type in chunked string");
+
+    case CborErrorIllegalNumber:
+        return _("illegal initial byte (encodes unspecified additional information)");
+
+    case CborErrorIllegalSimpleType:
+        return _("illegal encoding of simple type smaller than 32");
+
+    case CborErrorUnknownSimpleType:
+        return _("unknown simple type");
+
+    case CborErrorUnknownTag:
+        return _("unknown tag");
+
+    case CborErrorInappropriateTagForType:
+        return _("inappropriate tag for type");
+
+    case CborErrorDuplicateObjectKeys:
+        return _("duplicate keys in object");
+
+    case CborErrorInvalidUtf8TextString:
+        return _("invalid UTF-8 content in string");
+
+    case CborErrorTooManyItems:
+        return _("too many items added to encoder");
+
+    case CborErrorTooFewItems:
+        return _("too few items added to encoder");
+
+    case CborErrorDataTooLarge:
+        return _("internal error: data too large");
+
+    case CborErrorNestingTooDeep:
+        return _("internal error: too many nested containers found in recursive function");
+
+    case CborErrorUnsupportedType:
+        return _("unsupported type");
+
+    case CborErrorJsonObjectKeyIsAggregate:
+        return _("conversion to JSON failed: key in object is an array or map");
+
+    case CborErrorJsonObjectKeyNotString:
+        return _("conversion to JSON failed: key in object is not a string");
+
+    case CborErrorJsonNotImplemented:
+        return _("conversion to JSON failed: open_memstream unavailable");
+
+    case CborErrorInternalError:
+        return _("internal error");
+    }
+    return cbor_error_string(CborUnknownError);
+}



[02/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/cbortojson.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/cbortojson.c b/libs/tinycbor/src/cbortojson.c
new file mode 100644
index 0000000..953f2aa
--- /dev/null
+++ b/libs/tinycbor/src/cbortojson.c
@@ -0,0 +1,686 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#define _GNU_SOURCE 1
+#define _POSIX_C_SOURCE 200809L
+#ifndef __STDC_LIMIT_MACROS
+#  define __STDC_LIMIT_MACROS 1
+#endif
+
+#include "cbor.h"
+#include "cborjson.h"
+#include "compilersupport_p.h"
+#include "math_support_p.h"
+
+#include <float.h>
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/**
+ * \defgroup CborToJson Converting CBOR to JSON
+ * \brief Group of functions used to convert CBOR to JSON.
+ *
+ * This group contains two functions that are can be used to convert one
+ * CborValue object to an equivalent JSON representation. This module attempts
+ * to follow the recommendations from RFC 7049 section 4.1 "Converting from
+ * CBOR to JSON", though it has a few differences. They are noted below.
+ *
+ * These functions produce a "minified" JSON output, with no spacing,
+ * indentation or line breaks. If those are necessary, they need to be applied
+ * in a post-processing phase.
+ *
+ * Note that JSON cannot support all CBOR types with fidelity, so the
+ * conversion is usually lossy. For that reason, TinyCBOR supports adding a set
+ * of metadata JSON values that can be used by a JSON-to-CBOR converter to
+ * restore the original data types.
+ *
+ * The TinyCBOR library does not provide a way to convert from JSON
+ * representation back to encoded form. However, it provides a tool called
+ * \c json2cbor which can be used for that purpose. That tool supports the
+ * metadata format that these functions may produce.
+ *
+ * Either of the functions in this section will attempt to convert exactly one
+ * CborValue object to JSON. Those functions may return any error documented
+ * for the functions for CborParsing. In addition, if the C standard library
+ * stream functions return with error, the text conversion will return with
+ * error CborErrorIO.
+ *
+ * These functions also perform UTF-8 validation in CBOR text strings. If they
+ * encounter a sequence of bytes that not permitted in UTF-8, they will return
+ * CborErrorInvalidUtf8TextString. That includes encoding of surrogate points
+ * in UTF-8.
+ *
+ * \warning The metadata produced by these functions is not guaranteed to
+ * remain stable. A future update of TinyCBOR may produce different output for
+ * the same input and parsers may be unable to handle them.
+ *
+ * \sa CborParsing, CborPretty, cbor_parser_init()
+ */
+
+/**
+ * \addtogroup CborToJson
+ * @{
+ * <h2 class="groupheader">Conversion limitations</h2>
+ *
+ * When converting from CBOR to JSON, there may be information loss. This
+ * section lists the possible scenarios.
+ *
+ * \par Number precision:
+ * ALL JSON numbers, due to its JavaScript heritage, are IEEE 754
+ * double-precision floating point. This means JSON is not capable of
+ * representing integers numbers outside the range [-(2<sup>53</sup>)+1,
+ * 2<sup>53</sup>-1] and is not capable of representing NaN or infinite. If the
+ * CBOR data contains a number outside the valid range, the conversion will
+ * lose precision. If the input was NaN or infinite, the result of the
+ * conversion will be "null". In addition, the distinction between half-,
+ * single- and double-precision is lost.
+ *
+ * \par
+ * If enabled, the original value and original type are stored in the metadata.
+ *
+ * \par Non-native types:
+ * CBOR's type system is richer than JSON's, which means some data values
+ * cannot be represented when converted to JSON. The conversion silently turns
+ * them into strings: CBOR simple types become "simple(nn)" where \c nn is the
+ * simple type's value, with the exception of CBOR undefined, which becomes
+ * "undefined", while CBOR byte strings are converted to an Base16, Base64, or
+ * Base64url encoding
+ *
+ * \par
+ * If enabled, the original type is stored in the metadata.
+ *
+ * \par Presence of tags:
+ * JSON has no support for tagged values, so by default tags are dropped when
+ * converting to JSON. However, if the CborConvertObeyByteStringTags option is
+ * active (default), then certain known tags are honored and are used to format
+ * the conversion of the tagged byte string to JSON.
+ *
+ * \par
+ * If the CborConvertTagsToObjects option is active, then the tag and the
+ * tagged value are converted to to a JSON object. Otherwise, if enabled, the
+ * last (innermost) tag is stored in the metadata.
+ *
+ * \par Non-string keys in maps:
+ * JSON requires all Object keys to be strings, while CBOR does not. By
+ * default, if a non-string key is found, the conversion fails with error
+ * CborErrorJsonObjectKeyNotString. If the CborConvertStringifyMapKeys option
+ * is active, then the conversion attempts to create a string representation
+ * using CborPretty. Note that the \c json2cbor tool is not able to parse this
+ * back to the original form.
+ *
+ * \par Duplicate keys in maps:
+ * Neither JSON nor CBOR allow duplicated keys, but current TinyCBOR does not
+ * validate that this is the case. If there are duplicated keys in the input,
+ * they will be repeated in the output, which may JSON tools may flag as
+ * invalid. In addition to that, if the CborConvertStringifyMapKeys option is
+ * active, it is possible that a non-string key in a CBOR map will be converted
+ * to a string form that is identical to another key.
+ *
+ * \par
+ * When metadata support is active, the conversion will add extra key-value
+ * pairs to the JSON output so it can store the metadata. It is possible that
+ * the keys for the metadata clash with existing keys in the JSON map.
+ */
+
+extern FILE *open_memstream(char **bufptr, size_t *sizeptr);
+
+enum ConversionStatusFlags {
+    TypeWasNotNative            = 0x100,    /* anything but strings, boolean, null, arrays and maps */
+    TypeWasTagged               = 0x200,
+    NumberPrecisionWasLost      = 0x400,
+    NumberWasNaN                = 0x800,
+    NumberWasInfinite           = 0x1000,
+    NumberWasNegative           = 0x2000,   /* always used with NumberWasInifite or NumberWasTooBig */
+
+    FinalTypeMask               = 0xff
+};
+
+typedef struct ConversionStatus {
+    CborTag lastTag;
+    uint64_t originalNumber;
+    int flags;
+} ConversionStatus;
+
+static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status);
+
+static CborError dump_bytestring_base16(char **result, CborValue *it)
+{
+    static const char characters[] = "0123456789abcdef";
+    size_t i;
+    size_t n = 0;
+    uint8_t *buffer;
+    CborError err = cbor_value_calculate_string_length(it, &n);
+    if (err)
+        return err;
+
+    /* a Base16 (hex) output is twice as big as our buffer */
+    buffer = (uint8_t *)malloc(n * 2 + 1);
+    *result = (char *)buffer;
+
+    /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
+    ++n;
+    err = cbor_value_copy_byte_string(it, buffer + n - 1, &n, it);
+    assert(err == CborNoError);
+
+    for (i = 0; i < n; ++i) {
+        uint8_t byte = buffer[n + i];
+        buffer[2*i]     = characters[byte >> 4];
+        buffer[2*i + 1] = characters[byte & 0xf];
+    }
+    return CborNoError;
+}
+
+static CborError generic_dump_base64(char **result, CborValue *it, const char alphabet[65])
+{
+    size_t n = 0, i;
+    uint8_t *buffer, *out, *in;
+    CborError err = cbor_value_calculate_string_length(it, &n);
+    if (err)
+        return err;
+
+    /* a Base64 output (untruncated) has 4 bytes for every 3 in the input */
+    size_t len = (n + 5) / 3 * 4;
+    out = buffer = (uint8_t *)malloc(len + 1);
+    *result = (char *)buffer;
+
+    /* we read our byte string at the tail end of the buffer
+     * so we can do an in-place conversion while iterating forwards */
+    in = buffer + len - n;
+
+    /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
+    ++n;
+    err = cbor_value_copy_byte_string(it, in, &n, it);
+    assert(err == CborNoError);
+
+    uint_least32_t val = 0;
+    for (i = 0; n - i >= 3; i += 3) {
+        /* read 3 bytes x 8 bits = 24 bits */
+        if (false) {
+#ifdef __GNUC__
+        } else if (i) {
+            __builtin_memcpy(&val, in + i - 1, sizeof(val));
+            val = cbor_ntohl(val);
+#endif
+        } else {
+            val = (in[i] << 16) | (in[i + 1] << 8) | in[i + 2];
+        }
+
+        /* write 4 chars x 6 bits = 24 bits */
+        *out++ = alphabet[(val >> 18) & 0x3f];
+        *out++ = alphabet[(val >> 12) & 0x3f];
+        *out++ = alphabet[(val >> 6) & 0x3f];
+        *out++ = alphabet[val & 0x3f];
+    }
+
+    /* maybe 1 or 2 bytes left */
+    if (n - i) {
+        /* we can read in[i + 1] even if it's past the end of the string because
+         * we know (by construction) that it's a NUL byte */
+#ifdef __GNUC__
+        uint16_t val16;
+        __builtin_memcpy(&val16, in + i, sizeof(val16));
+        val = cbor_ntohs(val16);
+#else
+        val = (in[i] << 8) | in[i + 1];
+#endif
+        val <<= 8;
+
+        /* the 65th character in the alphabet is our filler: either '=' or '\0' */
+        out[4] = '\0';
+        out[3] = alphabet[64];
+        if (n - i == 2) {
+            /* write the third char in 3 chars x 6 bits = 18 bits */
+            out[2] = alphabet[(val >> 6) & 0x3f];
+        } else {
+            out[2] = alphabet[64];  /* filler */
+        }
+        out[1] = alphabet[(val >> 12) & 0x3f];
+        out[0] = alphabet[(val >> 18) & 0x3f];
+    } else {
+        out[0] = '\0';
+    }
+
+    return CborNoError;
+}
+
+static CborError dump_bytestring_base64(char **result, CborValue *it)
+{
+    static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+                                   "ghijklmn" "opqrstuv" "wxyz0123" "456789+/" "=";
+    return generic_dump_base64(result, it, alphabet);
+}
+
+static CborError dump_bytestring_base64url(char **result, CborValue *it)
+{
+    static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+                                   "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
+    return generic_dump_base64(result, it, alphabet);
+}
+
+static CborError add_value_metadata(FILE *out, CborType type, const ConversionStatus *status)
+{
+    int flags = status->flags;
+    if (flags & TypeWasTagged) {
+        /* extract the tagged type, which may be JSON native */
+        type = flags & FinalTypeMask;
+        flags &= ~(FinalTypeMask | TypeWasTagged);
+
+        if (fprintf(out, "\"tag\":\"%" PRIu64 "\"%s", status->lastTag,
+                    flags & ~TypeWasTagged ? "," : "") < 0)
+            return CborErrorIO;
+    }
+
+    if (!flags)
+        return CborNoError;
+
+    /* print at least the type */
+    if (fprintf(out, "\"t\":%d", type) < 0)
+        return CborErrorIO;
+
+    if (flags & NumberWasNaN)
+        if (fprintf(out, ",\"v\":\"nan\"") < 0)
+            return CborErrorIO;
+    if (flags & NumberWasInfinite)
+        if (fprintf(out, ",\"v\":\"%sinf\"", flags & NumberWasNegative ? "-" : "") < 0)
+            return CborErrorIO;
+    if (flags & NumberPrecisionWasLost)
+        if (fprintf(out, ",\"v\":\"%c%" PRIx64 "\"", flags & NumberWasNegative ? '-' : '+',
+                    status->originalNumber) < 0)
+            return CborErrorIO;
+    if (type == CborSimpleType)
+        if (fprintf(out, ",\"v\":%d", (int)status->originalNumber) < 0)
+            return CborErrorIO;
+    return CborNoError;
+}
+
+static CborError find_tagged_type(CborValue *it, CborTag *tag, CborType *type)
+{
+    CborError err = CborNoError;
+    *type = cbor_value_get_type(it);
+    while (*type == CborTagType) {
+        cbor_value_get_tag(it, tag);    /* can't fail */
+        err = cbor_value_advance_fixed(it);
+        if (err)
+            return err;
+
+        *type = cbor_value_get_type(it);
+    }
+    return err;
+}
+
+static CborError tagged_value_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
+{
+    CborTag tag;
+    CborError err;
+
+    if (flags & CborConvertTagsToObjects) {
+        cbor_value_get_tag(it, &tag);       /* can't fail */
+        err = cbor_value_advance_fixed(it);
+        if (err)
+            return err;
+
+        if (fprintf(out, "{\"tag%" PRIu64 "\":", tag) < 0)
+            return CborErrorIO;
+
+        CborType type = cbor_value_get_type(it);
+        err = value_to_json(out, it, flags, type, status);
+        if (err)
+            return err;
+        if (flags & CborConvertAddMetadata && status->flags) {
+            if (fprintf(out, ",\"tag%" PRIu64 "$cbor\":{", tag) < 0 ||
+                    add_value_metadata(out, type, status) != CborNoError ||
+                    fputc('}', out) < 0)
+                return CborErrorIO;
+        }
+        if (fputc('}', out) < 0)
+            return CborErrorIO;
+        status->flags = TypeWasNotNative | CborTagType;
+        return CborNoError;
+    }
+
+    CborType type;
+    err = find_tagged_type(it, &status->lastTag, &type);
+    if (err)
+        return err;
+    tag = status->lastTag;
+
+    /* special handling of byte strings? */
+    if (type == CborByteStringType && (flags & CborConvertByteStringsToBase64Url) == 0 &&
+            (tag == CborNegativeBignumTag || tag == CborExpectedBase16Tag || tag == CborExpectedBase64Tag)) {
+        char *str;
+        char *pre = "";
+
+        if (tag == CborNegativeBignumTag) {
+            pre = "~";
+            err = dump_bytestring_base64url(&str, it);
+        } else if (tag == CborExpectedBase64Tag) {
+            err = dump_bytestring_base64(&str, it);
+        } else { /* tag == CborExpectedBase16Tag */
+            err = dump_bytestring_base16(&str, it);
+        }
+        if (err)
+            return err;
+        err = fprintf(out, "\"%s%s\"", pre, str) < 0 ? CborErrorIO : CborNoError;
+        free(str);
+        status->flags = TypeWasNotNative | TypeWasTagged | CborByteStringType;
+        return err;
+    }
+
+    /* no special handling */
+    err = value_to_json(out, it, flags, type, status);
+    status->flags |= TypeWasTagged | type;
+    return err;
+}
+
+static CborError stringify_map_key(char **key, CborValue *it, int flags, CborType type)
+{
+    (void)flags;    /* unused */
+    (void)type;     /* unused */
+#ifdef WITHOUT_OPEN_MEMSTREAM
+    (void)key;      /* unused */
+    (void)it;       /* unused */
+    return CborErrorJsonNotImplemented;
+#else
+    size_t size;
+
+    FILE *memstream = open_memstream(key, &size);
+    if (memstream == NULL)
+        return CborErrorOutOfMemory;        /* could also be EMFILE, but it's unlikely */
+    CborError err = cbor_value_to_pretty_advance(memstream, it);
+
+    if (unlikely(fclose(memstream) < 0 || *key == NULL))
+        return CborErrorInternalError;
+    return err;
+#endif
+}
+
+static CborError array_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
+{
+    const char *comma = "";
+    while (!cbor_value_at_end(it)) {
+        if (fprintf(out, "%s", comma) < 0)
+            return CborErrorIO;
+        comma = ",";
+
+        CborError err = value_to_json(out, it, flags, cbor_value_get_type(it), status);
+        if (err)
+            return err;
+    }
+    return CborNoError;
+}
+
+static CborError map_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
+{
+    const char *comma = "";
+    CborError err;
+    while (!cbor_value_at_end(it)) {
+        char *key;
+        if (fprintf(out, "%s", comma) < 0)
+            return CborErrorIO;
+        comma = ",";
+
+        CborType keyType = cbor_value_get_type(it);
+        if (likely(keyType == CborTextStringType)) {
+            size_t n = 0;
+            err = cbor_value_dup_text_string(it, &key, &n, it);
+        } else if (flags & CborConvertStringifyMapKeys) {
+            err = stringify_map_key(&key, it, flags, keyType);
+        } else {
+            return CborErrorJsonObjectKeyNotString;
+        }
+        if (err)
+            return err;
+
+        /* first, print the key */
+        if (fprintf(out, "\"%s\":", key) < 0)
+            return CborErrorIO;
+
+        /* then, print the value */
+        CborType valueType = cbor_value_get_type(it);
+        err = value_to_json(out, it, flags, valueType, status);
+
+        /* finally, print any metadata we may have */
+        if (flags & CborConvertAddMetadata) {
+            if (!err && keyType != CborTextStringType) {
+                if (fprintf(out, ",\"%s$keycbordump\":true", key) < 0)
+                    err = CborErrorIO;
+            }
+            if (!err && status->flags) {
+                if (fprintf(out, ",\"%s$cbor\":{", key) < 0 ||
+                        add_value_metadata(out, valueType, status) != CborNoError ||
+                        fputc('}', out) < 0)
+                    err = CborErrorIO;
+            }
+        }
+
+        free(key);
+        if (err)
+            return err;
+    }
+    return CborNoError;
+}
+
+static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status)
+{
+    CborError err;
+    status->flags = 0;
+
+    switch (type) {
+    case CborArrayType:
+    case CborMapType: {
+        /* recursive type */
+        CborValue recursed;
+        err = cbor_value_enter_container(it, &recursed);
+        if (err) {
+            it->ptr = recursed.ptr;
+            return err;       /* parse error */
+        }
+        if (fputc(type == CborArrayType ? '[' : '{', out) < 0)
+            return CborErrorIO;
+
+        err = (type == CborArrayType) ?
+                  array_to_json(out, &recursed, flags, status) :
+                  map_to_json(out, &recursed, flags, status);
+        if (err) {
+            it->ptr = recursed.ptr;
+            return err;       /* parse error */
+        }
+
+        if (fputc(type == CborArrayType ? ']' : '}', out) < 0)
+            return CborErrorIO;
+        err = cbor_value_leave_container(it, &recursed);
+        if (err)
+            return err;       /* parse error */
+
+        status->flags = 0;    /* reset, there are never conversion errors for us */
+        return CborNoError;
+    }
+
+    case CborIntegerType: {
+        double num;     /* JS numbers are IEEE double precision */
+        uint64_t val;
+        cbor_value_get_raw_integer(it, &val);    /* can't fail */
+        num = (double)val;
+
+        if (cbor_value_is_negative_integer(it)) {
+            num = -num - 1;                     /* convert to negative */
+            if ((uint64_t)(-num - 1) != val) {
+                status->flags = NumberPrecisionWasLost | NumberWasNegative;
+                status->originalNumber = val;
+            }
+        } else {
+            if ((uint64_t)num != val) {
+                status->flags = NumberPrecisionWasLost;
+                status->originalNumber = val;
+            }
+        }
+        if (fprintf(out, "%.0f", num) < 0)  /* this number has no fraction, so no decimal points please */
+            return CborErrorIO;
+        break;
+    }
+
+    case CborByteStringType:
+    case CborTextStringType: {
+        char *str;
+        if (type == CborByteStringType) {
+            err = dump_bytestring_base64url(&str, it);
+            status->flags = TypeWasNotNative;
+        } else {
+            size_t n = 0;
+            err = cbor_value_dup_text_string(it, &str, &n, it);
+        }
+        if (err)
+            return err;
+        err = (fprintf(out, "\"%s\"", str) < 0) ? CborErrorIO : CborNoError;
+        free(str);
+        return err;
+    }
+
+    case CborTagType:
+        return tagged_value_to_json(out, it, flags, status);
+
+    case CborSimpleType: {
+        uint8_t simple_type;
+        cbor_value_get_simple_type(it, &simple_type);  /* can't fail */
+        status->flags = TypeWasNotNative;
+        status->originalNumber = simple_type;
+        if (fprintf(out, "\"simple(%" PRIu8 ")\"", simple_type) < 0)
+            return CborErrorIO;
+        break;
+    }
+
+    case CborNullType:
+        if (fprintf(out, "null") < 0)
+            return CborErrorIO;
+        break;
+
+    case CborUndefinedType:
+        status->flags = TypeWasNotNative;
+        if (fprintf(out, "\"undefined\"") < 0)
+            return CborErrorIO;
+        break;
+
+    case CborBooleanType: {
+        bool val;
+        cbor_value_get_boolean(it, &val);       /* can't fail */
+        if (fprintf(out, val ? "true" : "false") < 0)
+            return CborErrorIO;
+        break;
+    }
+
+    case CborDoubleType: {
+        double val;
+        if (false) {
+            float f;
+    case CborFloatType:
+            status->flags = TypeWasNotNative;
+            cbor_value_get_float(it, &f);
+            val = f;
+        } else if (false) {
+            uint16_t f16;
+    case CborHalfFloatType:
+            status->flags = TypeWasNotNative;
+            cbor_value_get_half_float(it, &f16);
+            val = decode_half(f16);
+        } else {
+            cbor_value_get_double(it, &val);
+        }
+
+        int r = fpclassify(val);
+        if (r == FP_NAN || r == FP_INFINITE) {
+            if (fprintf(out, "null") < 0)
+                return CborErrorIO;
+            status->flags |= r == FP_NAN ? NumberWasNaN :
+                                           NumberWasInfinite | (val < 0 ? NumberWasNegative : 0);
+        } else {
+            uint64_t ival = (uint64_t)fabs(val);
+            if ((double)ival == fabs(val)) {
+                /* print as integer so we get the full precision */
+                r = fprintf(out, "%s%" PRIu64, val < 0 ? "-" : "", ival);
+                status->flags |= TypeWasNotNative;   /* mark this integer number as a double */
+            } else {
+                /* this number is definitely not a 64-bit integer */
+                r = fprintf(out, "%." DBL_DECIMAL_DIG_STR "g", val);
+            }
+            if (r < 0)
+                return CborErrorIO;
+        }
+        break;
+    }
+
+    case CborInvalidType:
+        return CborErrorUnknownType;
+    }
+
+    return cbor_value_advance_fixed(it);
+}
+
+/**
+ * \enum CborToJsonFlags
+ * The CborToJsonFlags enum contains flags that control the conversion of CBOR to JSON.
+ *
+ * \value CborConvertAddMetadata        Adds metadata to facilitate restoration of the original CBOR data.
+ * \value CborConvertTagsToObjects      Converts CBOR tags to JSON objects
+ * \value CborConvertIgnoreTags         (default) Ignore CBOR tags, except for byte strings
+ * \value CborConvertObeyByteStringTags (default) Honor formatting of CBOR byte strings if so tagged
+ * \value CborConvertByteStringsToBase64Url Force the conversion of all CBOR byte strings to Base64url encoding, despite any tags
+ * \value CborConvertRequireMapStringKeys (default) Require CBOR map keys to be strings, failing the conversion if they are not
+ * \value CborConvertStringifyMapKeys   Convert non-string keys in CBOR maps to a string form
+ * \value CborConvertDefaultFlags       Default conversion flags.
+ */
+
+/**
+ * \fn CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
+ *
+ * Converts the current CBOR type pointed by \a value to JSON and writes that
+ * to the \a out stream. If an error occurs, this function returns an error
+ * code similar to CborParsing. The \a flags parameter indicates one of the
+ * flags from CborToJsonFlags that control the conversion.
+ *
+ * \sa cbor_value_to_json_advance(), cbor_value_to_pretty()
+ */
+
+/**
+ * Converts the current CBOR type pointed by \a value to JSON and writes that
+ * to the \a out stream. If an error occurs, this function returns an error
+ * code similar to CborParsing. The \a flags parameter indicates one of the
+ * flags from CborToJsonFlags that control the conversion.
+ *
+ * If no error ocurred, this function advances \a value to the next element.
+ *
+ * \sa cbor_value_to_json(), cbor_value_to_pretty_advance()
+ */
+CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags)
+{
+    ConversionStatus status;
+    return value_to_json(out, value, flags, cbor_value_get_type(value), &status);
+}
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/src/open_memstream.c
----------------------------------------------------------------------
diff --git a/libs/tinycbor/src/open_memstream.c b/libs/tinycbor/src/open_memstream.c
new file mode 100644
index 0000000..eaa53e5
--- /dev/null
+++ b/libs/tinycbor/src/open_memstream.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#define _BSD_SOURCE 1
+#define _DEFAULT_SOURCE 1
+#define _GNU_SOURCE 1
+
+#ifndef WITHOUT_OPEN_MEMSTREAM
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__unix__) || defined(__APPLE__)
+#  include <unistd.h>
+#endif
+#ifdef __APPLE__
+typedef int RetType;
+typedef int LenType;
+#elif __GLIBC__
+typedef ssize_t RetType;
+typedef size_t LenType;
+#else
+#  error "Cannot implement open_memstream!"
+#endif
+
+#include "compilersupport_p.h"
+
+struct Buffer
+{
+    char **ptr;
+    size_t *len;
+    size_t alloc;
+};
+
+static RetType write_to_buffer(void *cookie, const char *data, LenType len)
+{
+    struct Buffer *b = (struct Buffer *)cookie;
+    char *ptr = *b->ptr;
+    size_t newsize;
+
+    errno = EFBIG;
+    if (unlikely(add_check_overflow(*b->len, len, &newsize)))
+        return -1;
+
+    if (newsize > b->alloc) {
+        // make room
+        size_t newalloc = newsize + newsize / 2 + 1;    // give 50% more room
+        ptr = realloc(ptr, newalloc);
+        if (ptr == NULL)
+            return -1;
+        b->alloc = newalloc;
+        *b->ptr = ptr;
+    }
+
+    memcpy(ptr + *b->len, data, len);
+    *b->len = newsize;
+    return len;
+}
+
+static int close_buffer(void *cookie)
+{
+    struct Buffer *b = (struct Buffer *)cookie;
+    if (*b->ptr)
+        (*b->ptr)[*b->len] = '\0';
+    free(b);
+    return 0;
+}
+
+FILE *open_memstream(char **bufptr, size_t *lenptr)
+{
+    struct Buffer *b = (struct Buffer *)malloc(sizeof(struct Buffer));
+    if (b == NULL)
+        return NULL;
+    b->alloc = 0;
+    b->len = lenptr;
+    b->ptr = bufptr;
+    *bufptr = NULL;
+    *lenptr = 0;
+
+#ifdef __APPLE__
+    return funopen(b, NULL, write_to_buffer, NULL, close_buffer);
+#elif __GLIBC__
+    static const cookie_io_functions_t vtable = {
+        NULL,
+        write_to_buffer,
+        NULL,
+        close_buffer
+    };
+    return fopencookie(b, "w", vtable);
+#endif
+}
+
+#endif


[07/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/observe.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/observe.c b/libs/iotivity/src/messaging/coap/observe.c
new file mode 100644
index 0000000..4bd1d96
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/observe.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#include "config.h"
+
+#ifdef OC_SERVER
+
+#include "observe.h"
+#include "util/oc_memb.h"
+#include <stdio.h>
+#include <string.h>
+
+#include "oc_coap.h"
+#include "oc_rep.h"
+#include "oc_ri.h"
+/*-------------------*/
+uint64_t observe_counter = 3;
+/*---------------------------------------------------------------------------*/
+OC_LIST(observers_list);
+OC_MEMB(observers_memb, coap_observer_t, COAP_MAX_OBSERVERS);
+
+/*---------------------------------------------------------------------------*/
+/*- Internal API ------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+static int
+add_observer(oc_resource_t *resource, oc_endpoint_t *endpoint,
+             const uint8_t *token, size_t token_len, const char *uri,
+             int uri_len)
+{
+  /* Remove existing observe relationship, if any. */
+  int dup = coap_remove_observer_by_uri(endpoint, uri);
+
+  coap_observer_t *o = oc_memb_alloc(&observers_memb);
+
+  if (o) {
+    int max = sizeof(o->url) - 1;
+    if (max > uri_len) {
+      max = uri_len;
+    }
+    memcpy(o->url, uri, max);
+    o->url[max] = 0;
+    memcpy(&o->endpoint, endpoint, sizeof(oc_endpoint_t));
+    o->token_len = token_len;
+    memcpy(o->token, token, token_len);
+    o->last_mid = 0;
+    o->obs_counter = observe_counter;
+    o->resource = resource;
+    resource->num_observers++;
+    LOG("Adding observer (%u/%u) for /%s [0x%02X%02X]\n",
+        oc_list_length(observers_list) + 1, COAP_MAX_OBSERVERS, o->url,
+        o->token[0], o->token[1]);
+    oc_list_add(observers_list, o);
+    return dup;
+  }
+  return -1;
+}
+/*---------------------------------------------------------------------------*/
+/*- Removal -----------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+void
+coap_remove_observer(coap_observer_t *o)
+{
+  LOG("Removing observer for /%s [0x%02X%02X]\n", o->url, o->token[0],
+      o->token[1]);
+  oc_memb_free(&observers_memb, o);
+  oc_list_remove(observers_list, o);
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_remove_observer_by_client(oc_endpoint_t *endpoint)
+{
+  int removed = 0;
+  coap_observer_t *obs = (coap_observer_t *)oc_list_head(observers_list), *next;
+
+  LOG("Unregistering observers for client at: ");
+  LOGipaddr(*endpoint);
+
+  while (obs) {
+    next = obs->next;
+    if (memcmp(&obs->endpoint, endpoint, sizeof(oc_endpoint_t)) == 0) {
+      obs->resource->num_observers--;
+      coap_remove_observer(obs);
+      removed++;
+    }
+    obs = next;
+  }
+  LOG("Removed %d observers\n", removed);
+  return removed;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_remove_observer_by_token(oc_endpoint_t *endpoint, uint8_t *token,
+                              size_t token_len)
+{
+  int removed = 0;
+  coap_observer_t *obs = (coap_observer_t *)oc_list_head(observers_list);
+  LOG("Unregistering observers for request token 0x%02X%02X\n", token[0],
+      token[1]);
+  while (obs) {
+    if (memcmp(&obs->endpoint, endpoint, sizeof(oc_endpoint_t)) == 0 &&
+        obs->token_len == token_len &&
+        memcmp(obs->token, token, token_len) == 0) {
+      obs->resource->num_observers--;
+      coap_remove_observer(obs);
+      removed++;
+      break;
+    }
+    obs = obs->next;
+  }
+  LOG("Removed %d observers\n", removed);
+  return removed;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_remove_observer_by_uri(oc_endpoint_t *endpoint, const char *uri)
+{
+  LOG("Unregistering observers for resource uri /%s", uri);
+  int removed = 0;
+  coap_observer_t *obs = (coap_observer_t *)oc_list_head(observers_list), *next;
+
+  while (obs) {
+    next = obs->next;
+    if (((memcmp(&obs->endpoint, endpoint, sizeof(oc_endpoint_t)) == 0)) &&
+        (obs->url == uri || memcmp(obs->url, uri, strlen(obs->url)) == 0)) {
+      obs->resource->num_observers--;
+      coap_remove_observer(obs);
+      removed++;
+    }
+    obs = next;
+  }
+  LOG("Removed %d observers\n", removed);
+  return removed;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_remove_observer_by_mid(oc_endpoint_t *endpoint, uint16_t mid)
+{
+  int removed = 0;
+  coap_observer_t *obs = NULL;
+  LOG("Unregistering observers for request MID %u\n", mid);
+
+  for (obs = (coap_observer_t *)oc_list_head(observers_list); obs != NULL;
+       obs = obs->next) {
+    if (memcmp(&obs->endpoint, endpoint, sizeof(*endpoint)) == 0 &&
+        obs->last_mid == mid) {
+      obs->resource->num_observers--;
+      coap_remove_observer(obs);
+      removed++;
+      break;
+    }
+  }
+  LOG("Removed %d observers\n", removed);
+  return removed;
+}
+/*---------------------------------------------------------------------------*/
+/*- Notification ------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+int
+coap_notify_observers(oc_resource_t *resource,
+                      oc_response_buffer_t *response_buf,
+                      oc_endpoint_t *endpoint)
+{
+  int num_observers = 0;
+  if (resource) {
+    if (!resource->num_observers) {
+      LOG("coap_notify_observers: no observers; returning\n");
+      return 0;
+    }
+    num_observers = resource->num_observers;
+  }
+  uint8_t buffer[COAP_MAX_BLOCK_SIZE];
+  oc_request_t request = {};
+  oc_response_t response = {};
+  response.separate_response = 0;
+  oc_response_buffer_t response_buffer;
+  if (!response_buf && resource && (resource->properties & OC_PERIODIC)) {
+    LOG("coap_notify_observers: Issue GET request to resource\n");
+    /* performing GET on the resource */
+    response_buffer.buffer = buffer;
+    response_buffer.buffer_size = COAP_MAX_BLOCK_SIZE;
+    response_buffer.block_offset = NULL;
+    response.response_buffer = &response_buffer;
+    request.resource = resource;
+    request.response = &response;
+    request.request_payload = NULL;
+    oc_rep_new(buffer, COAP_MAX_BLOCK_SIZE);
+    resource->get_handler(&request, resource->default_interface);
+    response_buf = &response_buffer;
+    if (response_buf->code == OC_IGNORE) {
+      LOG("coap_notify_observers: Resource ignored request\n");
+      return num_observers;
+    }
+  }
+
+  coap_observer_t *obs = NULL;
+  /* iterate over observers */
+  for (obs = (coap_observer_t *)oc_list_head(observers_list);
+       obs && ((resource && obs->resource == resource) ||
+               (endpoint &&
+                memcmp(&obs->endpoint, endpoint, sizeof(oc_endpoint_t)) == 0));
+       obs = obs->next) {
+    num_observers = obs->resource->num_observers;
+    if (response.separate_response != NULL &&
+        response_buf->code == oc_status_code(OC_STATUS_OK)) {
+      coap_packet_t req[1];
+      /*
+  req->block1_num = 0;
+  req->block1_size = 0;
+  req->block2_num = 0;
+  req->block2_size = 0;
+      */
+      coap_init_message(req, COAP_TYPE_NON, CONTENT_2_05, 0);
+      memcpy(req->token, obs->token, obs->token_len);
+      req->token_len = obs->token_len;
+      LOG("Resource is SLOW; creating separate response\n");
+      if (coap_separate_accept(req, response.separate_response, &obs->endpoint,
+                               0) == 1)
+        response.separate_response->active = 1;
+    } else {
+      LOG("coap_notify_observers: notifying observer\n");
+      coap_transaction_t *transaction = NULL;
+      if (response_buf && (transaction = coap_new_transaction(
+                             coap_get_mid(), &obs->endpoint))) {
+        memcpy(transaction->message->data + COAP_MAX_HEADER_SIZE,
+               response_buf->buffer, response_buf->response_length);
+
+        /* update last MID for RST matching */
+        obs->last_mid = transaction->mid;
+
+        /* prepare response */
+        /* build notification */
+        coap_packet_t notification
+          [1]; /* this way the packet can be treated as pointer as usual */
+        coap_init_message(notification, COAP_TYPE_NON, CONTENT_2_05, 0);
+
+        notification->mid = transaction->mid;
+        if (obs->obs_counter % COAP_OBSERVE_REFRESH_INTERVAL == 0) {
+          LOG("coap_observe_notify: forcing CON notification to check for "
+              "client liveness\n");
+          notification->type = COAP_TYPE_CON;
+        }
+        coap_set_payload(notification, response_buf->buffer,
+                         response_buf->response_length);
+        coap_set_status_code(notification, response_buf->code);
+        if (notification->code < BAD_REQUEST_4_00 &&
+            obs->resource->num_observers) {
+          coap_set_header_observe(notification, (obs->obs_counter)++);
+          observe_counter++;
+        } else {
+          coap_set_header_observe(notification, 1);
+        }
+        coap_set_token(notification, obs->token, obs->token_len);
+
+        transaction->message->length =
+          coap_serialize_message(notification, transaction->message->data);
+
+        coap_send_transaction(transaction);
+      }
+    }
+  }
+  return num_observers;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_observe_handler(void *request, void *response, oc_resource_t *resource,
+                     oc_endpoint_t *endpoint)
+{
+  coap_packet_t *const coap_req = (coap_packet_t *)request;
+  coap_packet_t *const coap_res = (coap_packet_t *)response;
+  int dup = -1;
+  if (coap_req->code == COAP_GET &&
+      coap_res->code < 128) { /* GET request and response without error code */
+    if (IS_OPTION(coap_req, COAP_OPTION_OBSERVE)) {
+      if (coap_req->observe == 0) {
+        dup =
+          add_observer(resource, endpoint, coap_req->token, coap_req->token_len,
+                       coap_req->uri_path, coap_req->uri_path_len);
+      } else if (coap_req->observe == 1) {
+        /* remove client if it is currently observe */
+        dup = coap_remove_observer_by_token(endpoint, coap_req->token,
+                                            coap_req->token_len);
+      }
+    }
+  }
+  return dup;
+}
+/*---------------------------------------------------------------------------*/
+
+#endif /* OC_SERVER */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/observe.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/observe.h b/libs/iotivity/src/messaging/coap/observe.h
new file mode 100644
index 0000000..3f2cfb6
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/observe.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef OBSERVE_H
+#define OBSERVE_H
+
+#include "coap.h"
+#include "transactions.h"
+#include "util/oc_list.h"
+
+/* OIC stack headers */
+#include "oc_ri.h"
+
+#define COAP_OBSERVER_URL_LEN 20
+
+typedef struct coap_observer
+{
+  struct coap_observer *next; /* for LIST */
+
+  oc_resource_t *resource;
+
+  char url[COAP_OBSERVER_URL_LEN];
+  oc_endpoint_t endpoint;
+  uint8_t token_len;
+  uint8_t token[COAP_TOKEN_LEN];
+  uint16_t last_mid;
+
+  int32_t obs_counter;
+
+  struct oc_etimer retrans_timer;
+  uint8_t retrans_counter;
+} coap_observer_t;
+
+oc_list_t coap_get_observers(void);
+void coap_remove_observer(coap_observer_t *o);
+int coap_remove_observer_by_client(oc_endpoint_t *endpoint);
+int coap_remove_observer_by_token(oc_endpoint_t *endpoint, uint8_t *token,
+                                  size_t token_len);
+int coap_remove_observer_by_uri(oc_endpoint_t *endpoint, const char *uri);
+int coap_remove_observer_by_mid(oc_endpoint_t *endpoint, uint16_t mid);
+
+int coap_notify_observers(oc_resource_t *resource,
+                          oc_response_buffer_t *response_buf,
+                          oc_endpoint_t *endpoint);
+// int coap_notify_observers_sub(oc_resource_t *resource, const char *subpath);
+
+int coap_observe_handler(void *request, void *response, oc_resource_t *resource,
+                         oc_endpoint_t *endpoint);
+
+#endif /* OBSERVE_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/oc_coap.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/oc_coap.h b/libs/iotivity/src/messaging/coap/oc_coap.h
new file mode 100644
index 0000000..b393048
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/oc_coap.h
@@ -0,0 +1,39 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_COAP_H
+#define OC_COAP_H
+
+#include "separate.h"
+#include "util/oc_list.h"
+
+typedef struct oc_separate_response_s
+{
+  OC_LIST_STRUCT(requests);
+  int active;
+  uint8_t buffer[COAP_MAX_BLOCK_SIZE];
+} oc_separate_response_t;
+
+typedef struct oc_response_buffer_s
+{
+  uint8_t *buffer;
+  uint16_t buffer_size;
+  int32_t *block_offset;
+  uint16_t response_length;
+  int code;
+} oc_response_buffer_t;
+
+#endif /* OC_COAP_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/separate.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/separate.c b/libs/iotivity/src/messaging/coap/separate.c
new file mode 100644
index 0000000..5be01e7
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/separate.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#include "config.h"
+
+#ifdef OC_SERVER
+
+#include "oc_buffer.h"
+#include "separate.h"
+#include "transactions.h"
+#include "util/oc_memb.h"
+#include <stdio.h>
+#include <string.h>
+
+OC_MEMB(separate_requests, coap_separate_t, MAX_NUM_CONCURRENT_REQUESTS);
+
+/*---------------------------------------------------------------------------*/
+/*- Separate Response API ---------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Initiate a separate response with an empty ACK
+ * \param request The request to accept
+ * \param separate_store A pointer to the data structure that will store the
+ *   relevant information for the response
+ *
+ * When the server does not have enough resources left to store the information
+ * for a separate response or otherwise cannot execute the resource handler,
+ * this function will respond with 5.03 Service Unavailable. The client can
+ * then retry later.
+ */
+int
+coap_separate_accept(void *request, oc_separate_response_t *separate_response,
+                     oc_endpoint_t *endpoint, int observe)
+{
+  if (separate_response->active == 0) {
+    OC_LIST_STRUCT_INIT(separate_response, requests);
+  }
+
+  coap_packet_t *const coap_req = (coap_packet_t *)request;
+
+  for (coap_separate_t *item = oc_list_head(separate_response->requests);
+       item != NULL; item = oc_list_item_next(separate_response->requests)) {
+    if (item->token_len == coap_req->token_len &&
+        memcmp(item->token, coap_req->token, item->token_len) == 0) {
+      return 0;
+    }
+  }
+
+  coap_separate_t *separate_store = oc_memb_alloc(&separate_requests);
+
+  if (!separate_store)
+    return 0;
+
+  oc_list_add(separate_response->requests, separate_store);
+
+  erbium_status_code = CLEAR_TRANSACTION;
+  /* send separate ACK for CON */
+  if (coap_req->type == COAP_TYPE_CON) {
+    LOG("Sending ACK for separate response\n");
+    coap_packet_t ack[1];
+    /* ACK with empty code (0) */
+    coap_init_message(ack, COAP_TYPE_ACK, 0, coap_req->mid);
+    if (observe < 2) {
+      coap_set_header_observe(ack, observe);
+    }
+    coap_set_token(ack, coap_req->token, coap_req->token_len);
+    oc_message_t *message = oc_allocate_message();
+    if (message != NULL) {
+      message->endpoint.flags = IP;
+      memcpy(&message->endpoint, endpoint, sizeof(oc_endpoint_t));
+      message->length = coap_serialize_message(ack, message->data);
+      coap_send_message(message);
+    } else {
+      coap_separate_clear(separate_response, separate_store);
+      erbium_status_code = SERVICE_UNAVAILABLE_5_03;
+      return 0;
+    }
+  }
+  memcpy(&separate_store->endpoint, endpoint, sizeof(oc_endpoint_t));
+
+  /* store correct response type */
+  separate_store->type = COAP_TYPE_NON;
+
+  memcpy(separate_store->token, coap_req->token, coap_req->token_len);
+  separate_store->token_len = coap_req->token_len;
+
+  separate_store->block1_num = coap_req->block1_num;
+  separate_store->block1_size = coap_req->block1_size;
+
+  separate_store->block2_num = coap_req->block2_num;
+  separate_store->block2_size =
+    coap_req->block2_size > 0 ? MIN(COAP_MAX_BLOCK_SIZE, coap_req->block2_size)
+                              : COAP_MAX_BLOCK_SIZE;
+
+  separate_store->observe = observe;
+  return 1;
+}
+/*----------------------------------------------------------------------------*/
+void
+coap_separate_resume(void *response, coap_separate_t *separate_store,
+                     uint8_t code, uint16_t mid)
+{
+  coap_init_message(response, separate_store->type, code, mid);
+  if (separate_store->token_len) {
+    coap_set_token(response, separate_store->token, separate_store->token_len);
+  }
+  if (separate_store->block1_size) {
+    coap_set_header_block1(response, separate_store->block1_num, 0,
+                           separate_store->block1_size);
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+coap_separate_clear(oc_separate_response_t *separate_response,
+                    coap_separate_t *separate_store)
+{
+  oc_list_remove(separate_response->requests, separate_store);
+  oc_memb_free(&separate_requests, separate_store);
+}
+
+#endif /* OC_SERVER */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/separate.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/separate.h b/libs/iotivity/src/messaging/coap/separate.h
new file mode 100644
index 0000000..8a64de2
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/separate.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef SEPARATE_H
+#define SEPARATE_H
+
+#include "coap.h"
+#include "transactions.h"
+
+/* OIC stack headers */
+#include "oc_coap.h"
+#include "oc_ri.h"
+
+typedef struct coap_separate
+{
+  struct coap_separate *next;
+  coap_message_type_t type;
+
+  uint8_t token_len;
+  uint8_t token[COAP_TOKEN_LEN];
+
+  uint32_t block1_num;
+  uint16_t block1_size;
+
+  uint32_t block2_num;
+  uint16_t block2_size;
+
+  int32_t observe;
+
+  oc_endpoint_t endpoint;
+} coap_separate_t;
+
+int coap_separate_accept(void *request,
+                         oc_separate_response_t *separate_response,
+                         oc_endpoint_t *endpoint, int observe);
+void coap_separate_resume(void *response, coap_separate_t *separate_store,
+                          uint8_t code, uint16_t mid);
+void coap_separate_clear(oc_separate_response_t *separate_response,
+                         coap_separate_t *separate_store);
+
+#endif /* SEPARATE_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/transactions.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/transactions.c b/libs/iotivity/src/messaging/coap/transactions.c
new file mode 100644
index 0000000..851cce1
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/transactions.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#include "transactions.h"
+#include "observe.h"
+#include "oc_buffer.h"
+#include "util/oc_list.h"
+#include "util/oc_memb.h"
+#include <string.h>
+
+#ifdef OC_CLIENT
+#include "oc_client_state.h"
+#endif /* OC_CLIENT */
+
+#ifdef OC_SECURITY
+#include "security/oc_dtls.h"
+#endif
+
+/*---------------------------------------------------------------------------*/
+OC_MEMB(transactions_memb, coap_transaction_t, COAP_MAX_OPEN_TRANSACTIONS);
+OC_LIST(transactions_list);
+
+static struct oc_process *transaction_handler_process = NULL;
+
+/*---------------------------------------------------------------------------*/
+/*- Internal API ------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+void
+coap_register_as_transaction_handler()
+{
+  transaction_handler_process = OC_PROCESS_CURRENT();
+}
+
+coap_transaction_t *
+coap_new_transaction(uint16_t mid, oc_endpoint_t *endpoint)
+{
+  coap_transaction_t *t = oc_memb_alloc(&transactions_memb);
+  if (t) {
+    oc_message_t *message = oc_allocate_message();
+    if (message) {
+      LOG("Created new transaction %d %ld\n", mid, message->length);
+      t->mid = mid;
+      t->retrans_counter = 0;
+
+      t->message = message;
+
+      /* save client address */
+      memcpy(&t->message->endpoint, endpoint, sizeof(oc_endpoint_t));
+
+      oc_list_add(
+        transactions_list,
+        t); /* list itself makes sure same element is not added twice */
+    } else {
+      oc_memb_free(&transactions_memb, t);
+      t = NULL;
+    }
+  }
+
+  return t;
+}
+
+/*---------------------------------------------------------------------------*/
+void
+coap_send_transaction(coap_transaction_t *t)
+{
+  LOG("Sending transaction %u\n", t->mid);
+  bool confirmable = false;
+
+  confirmable =
+    (COAP_TYPE_CON == ((COAP_HEADER_TYPE_MASK & t->message->data[0]) >>
+                       COAP_HEADER_TYPE_POSITION))
+      ? true
+      : false;
+
+  if (confirmable) {
+    if (t->retrans_counter < COAP_MAX_RETRANSMIT) {
+      /* not timed out yet */
+      LOG("Keeping transaction %u\n", t->mid);
+
+      if (t->retrans_counter == 0) {
+        t->retrans_timer.timer.interval =
+          COAP_RESPONSE_TIMEOUT_TICKS +
+          (oc_random_rand() %
+           (oc_clock_time_t)COAP_RESPONSE_TIMEOUT_BACKOFF_MASK);
+        LOG("Initial interval %llu\n", t->retrans_timer.timer.interval);
+      } else {
+        t->retrans_timer.timer.interval <<= 1; /* double */
+        LOG("Doubled %llu\n", t->retrans_timer.timer.interval);
+      }
+
+      OC_PROCESS_CONTEXT_BEGIN(transaction_handler_process);
+      oc_etimer_restart(&t->retrans_timer); /* interval updated above */
+      OC_PROCESS_CONTEXT_END(transaction_handler_process);
+
+      coap_send_message(t->message);
+
+      oc_message_add_ref(t->message);
+
+      t = NULL;
+    } else {
+      /* timed out */
+      LOG("Timeout\n");
+
+#ifdef OC_SERVER
+      LOG("timeout.. so removing observers\n");
+      /* handle observers */
+      coap_remove_observer_by_client(&t->message->endpoint);
+#endif /* OC_SERVER */
+
+#ifdef OC_SECURITY
+      if (t->message->endpoint.flags & SECURED) {
+        oc_sec_dtls_close_init(&t->message->endpoint);
+      }
+#endif /* OC_SECURITY */
+
+#ifdef OC_CLIENT
+      oc_ri_remove_client_cb_by_mid(t->mid);
+#endif /* OC_CLIENT */
+
+      coap_clear_transaction(t);
+    }
+  } else {
+    coap_send_message(t->message);
+    oc_message_add_ref(t->message);
+
+    coap_clear_transaction(t);
+  }
+}
+/*---------------------------------------------------------------------------*/
+void
+coap_clear_transaction(coap_transaction_t *t)
+{
+  if (t) {
+    LOG("Freeing transaction %u: %p\n", t->mid, t);
+
+    oc_etimer_stop(&t->retrans_timer);
+    oc_message_unref(t->message);
+    oc_list_remove(transactions_list, t);
+    oc_memb_free(&transactions_memb, t);
+  }
+}
+coap_transaction_t *
+coap_get_transaction_by_mid(uint16_t mid)
+{
+  coap_transaction_t *t = NULL;
+
+  for (t = (coap_transaction_t *)oc_list_head(transactions_list); t;
+       t = t->next) {
+    if (t->mid == mid) {
+      LOG("Found transaction for MID %u: %p\n", t->mid, t);
+      return t;
+    }
+  }
+  return NULL;
+}
+
+/*---------------------------------------------------------------------------*/
+void
+coap_check_transactions()
+{
+  coap_transaction_t *t = NULL;
+
+  for (t = (coap_transaction_t *)oc_list_head(transactions_list); t;
+       t = t->next) {
+    if (oc_etimer_expired(&t->retrans_timer)) {
+      ++(t->retrans_counter);
+      LOG("Retransmitting %u (%u)\n", t->mid, t->retrans_counter);
+      coap_send_transaction(t);
+    }
+  }
+}
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/transactions.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/transactions.h b/libs/iotivity/src/messaging/coap/transactions.h
new file mode 100644
index 0000000..0b6fd9e
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/transactions.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef TRANSACTIONS_H
+#define TRANSACTIONS_H
+
+#include "coap.h"
+#include "util/oc_etimer.h"
+
+/*
+ * Modulo mask (thus +1) for a random number to get the tick number for the
+ * random
+ * retransmission time between COAP_RESPONSE_TIMEOUT and
+ * COAP_RESPONSE_TIMEOUT*COAP_RESPONSE_RANDOM_FACTOR.
+ */
+#define COAP_RESPONSE_TIMEOUT_TICKS (OC_CLOCK_SECOND * COAP_RESPONSE_TIMEOUT)
+#define COAP_RESPONSE_TIMEOUT_BACKOFF_MASK                                     \
+  (long)((OC_CLOCK_SECOND * COAP_RESPONSE_TIMEOUT *                            \
+          ((float)COAP_RESPONSE_RANDOM_FACTOR - 1.0)) +                        \
+         0.5) +                                                                \
+    1
+
+/* container for transactions with message buffer and retransmission info */
+typedef struct coap_transaction
+{
+  struct coap_transaction *next; /* for LIST */
+
+  uint16_t mid;
+  struct oc_etimer retrans_timer;
+  uint8_t retrans_counter;
+  oc_message_t *message;
+
+} coap_transaction_t;
+
+void coap_register_as_transaction_handler(void);
+
+coap_transaction_t *coap_new_transaction(uint16_t mid, oc_endpoint_t *endpoint);
+
+void coap_send_transaction(coap_transaction_t *t);
+void coap_clear_transaction(coap_transaction_t *t);
+coap_transaction_t *coap_get_transaction_by_mid(uint16_t mid);
+
+void coap_check_transactions(void);
+
+#endif /* TRANSACTIONS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/mynewt/config.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/mynewt/config.h b/libs/iotivity/src/port/mynewt/config.h
new file mode 100644
index 0000000..803a99d
--- /dev/null
+++ b/libs/iotivity/src/port/mynewt/config.h
@@ -0,0 +1,50 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+/* Time resolution */
+#include <stdint.h>
+#include <os/os.h>
+
+typedef uint64_t oc_clock_time_t;
+#define OC_CLOCK_CONF_TICKS_PER_SECOND (OS_TICKS_PER_SEC)
+
+/* Memory pool sizes */
+#define OC_BYTES_POOL_SIZE (2048)
+#define OC_INTS_POOL_SIZE (16)
+#define OC_DOUBLES_POOL_SIZE (16)
+
+/* Server-side parameters */
+/* Maximum number of server resources */
+#define MAX_APP_RESOURCES (2)
+
+/* Common paramters */
+/* Maximum number of concurrent requests */
+#define MAX_NUM_CONCURRENT_REQUESTS (2)
+
+/* Estimated number of nodes in payload tree structure */
+#define EST_NUM_REP_OBJECTS (100)
+
+/* Maximum size of request/response PDUs */
+#define MAX_PAYLOAD_SIZE (612)
+
+/* Number of devices on the OCF platform */
+#define MAX_NUM_DEVICES (1)
+
+/* Platform payload size */
+#define MAX_PLATFORM_PAYLOAD_SIZE (256)
+
+/* Device payload size */
+#define MAX_DEVICE_PAYLOAD_SIZE (256)
+
+/* Security layer */
+/* Maximum number of authorized clients */
+//#define MAX_NUM_SUBJECTS (2)
+
+/* Maximum number of concurrent DTLS sessions */
+//#define MAX_DTLS_PEERS (1)
+
+/* Max inactivity timeout before tearing down DTLS connection */
+//#define DTLS_INACTIVITY_TIMEOUT (10)
+
+#endif /* CONFIG_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_assert.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_assert.h b/libs/iotivity/src/port/oc_assert.h
new file mode 100644
index 0000000..a3323cf
--- /dev/null
+++ b/libs/iotivity/src/port/oc_assert.h
@@ -0,0 +1,42 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_ASSERT_H
+#define OC_ASSERT_H
+
+#include "port/oc_log.h"
+
+#ifdef __linux__
+#include <stdlib.h>
+#define abort_impl() abort()
+#else
+void abort_impl(void);
+#endif
+
+#define oc_abort(msg)                                                          \
+  do {                                                                         \
+    LOG("\n%s:%d:%s: error: %s\nAbort.\n", __FILE__, __LINE__, __func__, msg); \
+    abort_impl();                                                              \
+  } while (0)
+
+#define oc_assert(cond)                                                        \
+  do {                                                                         \
+    if (!(cond)) {                                                             \
+      oc_abort("Assertion (" #cond ") failed.");                               \
+    }                                                                          \
+  } while (0)
+
+#endif /* OC_ASSERT_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_clock.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_clock.h b/libs/iotivity/src/port/oc_clock.h
new file mode 100644
index 0000000..e012bb5
--- /dev/null
+++ b/libs/iotivity/src/port/oc_clock.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \defgroup clock Clock library
+ *
+ * The clock library is the interface between Contiki and the platform
+ * specific clock functionality. The clock library defines a macro,
+ * CLOCK_SECOND, to convert seconds into the tick resolution of the platform.
+ * Typically this is 1-10 milliseconds, e.g. 4*CLOCK_SECOND could be 512.
+ * A 16 bit counter would thus overflow every 1-10 minutes.
+ * Platforms use the tick interrupt to maintain a long term count
+ * of seconds since startup.
+ *
+ */
+
+#ifndef OC_CLOCK_H
+#define OC_CLOCK_H
+
+#include "config.h"
+#include <stdint.h>
+
+/**
+ * A second, measured in system clock time.
+ *
+ * \hideinitializer
+ */
+#ifndef OC_CLOCK_CONF_TICKS_PER_SECOND
+#error "Please define OC_CLOCK_CONF_TICKS_PER_SECOND in config.h"
+#else
+#define OC_CLOCK_SECOND OC_CLOCK_CONF_TICKS_PER_SECOND
+#endif
+
+/**
+ * Initialize the clock library.
+ *
+ * This function initializes the clock library and should be called
+ * from the main() function of the system.
+ *
+ */
+void oc_clock_init(void);
+
+/**
+ * Get the current clock time.
+ *
+ * This function returns the current system clock time.
+ *
+ * \return The current clock time, measured in system ticks.
+ */
+oc_clock_time_t oc_clock_time(void);
+
+/**
+ * Get the current value of the platform seconds.
+ *
+ * This could be the number of seconds since startup, or
+ * since a standard epoch.
+ *
+ * \return The value.
+ */
+unsigned long oc_clock_seconds(void);
+
+/**
+ * Wait for a given number of ticks.
+ * \param t   How many ticks.
+ *
+ */
+void oc_clock_wait(oc_clock_time_t t);
+
+#endif /* OC_CLOCK_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_connectivity.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_connectivity.h b/libs/iotivity/src/port/oc_connectivity.h
new file mode 100644
index 0000000..1c36171
--- /dev/null
+++ b/libs/iotivity/src/port/oc_connectivity.h
@@ -0,0 +1,83 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_CONNECTIVITY_H
+#define OC_CONNECTIVITY_H
+
+#include "config.h"
+#include "oc_network_events.h"
+#include "port/oc_log.h"
+#include "util/oc_process.h"
+#include <stdint.h>
+
+typedef struct
+{
+  uint16_t port;
+  uint8_t address[16];
+  uint8_t scope;
+} oc_ipv6_addr_t;
+
+typedef struct
+{
+  uint8_t type;
+  uint8_t address[6];
+} oc_le_addr_t;
+
+typedef struct
+{
+  enum transport_flags
+  {
+    IP = 1 << 0,
+    GATT = 1 << 1,
+    IPSP = 1 << 2,
+    MULTICAST = 1 << 3,
+    SECURED = 1 << 4
+  } flags;
+
+  union
+  {
+    oc_ipv6_addr_t ipv6_addr;
+    oc_le_addr_t bt_addr;
+  };
+} oc_endpoint_t;
+
+#define oc_make_ip_endpoint(__name__, __flags__, __port__, ...)                \
+  oc_endpoint_t __name__ = {.flags = __flags__,                                \
+                            .ipv6_addr = {.port = __port__,                    \
+                                          .address = { __VA_ARGS__ } } }
+
+typedef struct oc_message_s
+{
+  struct oc_message_s *next;
+  oc_endpoint_t endpoint;
+  size_t length;
+  uint8_t ref_count;
+  uint8_t data[MAX_PAYLOAD_SIZE];
+} oc_message_t;
+
+void oc_send_buffer(oc_message_t *message);
+
+#ifdef OC_SECURITY
+uint16_t oc_connectivity_get_dtls_port(void);
+#endif /* OC_SECURITY */
+
+int oc_connectivity_init(void);
+
+void oc_connectivity_shutdown(void);
+
+void oc_send_multicast_message(oc_message_t *message);
+
+#endif /* OC_CONNECTIVITY_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_log.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_log.h b/libs/iotivity/src/port/oc_log.h
new file mode 100644
index 0000000..a9676b9
--- /dev/null
+++ b/libs/iotivity/src/port/oc_log.h
@@ -0,0 +1,46 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_LOG_H
+#define OC_LOG_H
+
+#include <stdio.h>
+
+#define PRINT(...) printf(__VA_ARGS__)
+
+#define PRINTipaddr(endpoint)                                                  \
+  PRINT(                                                                       \
+    "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%"    \
+    "02x]:%d",                                                                 \
+    ((endpoint).ipv6_addr.address)[0], ((endpoint).ipv6_addr.address)[1],      \
+    ((endpoint).ipv6_addr.address)[2], ((endpoint).ipv6_addr.address)[3],      \
+    ((endpoint).ipv6_addr.address)[4], ((endpoint).ipv6_addr.address)[5],      \
+    ((endpoint).ipv6_addr.address)[6], ((endpoint).ipv6_addr.address)[7],      \
+    ((endpoint).ipv6_addr.address)[8], ((endpoint).ipv6_addr.address)[9],      \
+    ((endpoint).ipv6_addr.address)[10], ((endpoint).ipv6_addr.address)[11],    \
+    ((endpoint).ipv6_addr.address)[12], ((endpoint).ipv6_addr.address)[13],    \
+    ((endpoint).ipv6_addr.address)[14], ((endpoint).ipv6_addr.address)[15],    \
+    (endpoint).ipv6_addr.port)
+
+#if DEBUG
+#define LOG(...) PRINT(__VA_ARGS__)
+#define LOGipaddr(endpoint) PRINTipaddr(endpoint)
+#else
+#define LOG(...)
+#define LOGipaddr(endpoint)
+#endif
+
+#endif /* OC_LOG_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_network_events_mutex.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_network_events_mutex.h b/libs/iotivity/src/port/oc_network_events_mutex.h
new file mode 100644
index 0000000..40c1b09
--- /dev/null
+++ b/libs/iotivity/src/port/oc_network_events_mutex.h
@@ -0,0 +1,26 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_NETWORK_EVENTS_MUTEX_H
+#define OC_NETWORK_EVENTS_MUTEX_H
+
+void oc_network_event_handler_mutex_init(void);
+
+void oc_network_event_handler_mutex_lock(void);
+
+void oc_network_event_handler_mutex_unlock(void);
+
+#endif /* OC_NETWORK_EVENTS_MUTEX_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_random.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_random.h b/libs/iotivity/src/port/oc_random.h
new file mode 100644
index 0000000..758ed19
--- /dev/null
+++ b/libs/iotivity/src/port/oc_random.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+#ifndef OC_RANDOM_H
+#define OC_RANDOM_H
+
+/*
+ * Initialize the pseudo-random generator.
+ *
+ */
+void oc_random_init(unsigned short seed);
+
+/*
+ * Calculate a pseudo random number between 0 and 65535.
+ *
+ * \return A pseudo-random number between 0 and 65535.
+ */
+unsigned short oc_random_rand(void);
+
+/* In gcc int rand() uses RAND_MAX and long random() uses RANDOM_MAX */
+/* Since random_rand casts to unsigned short, we'll use this maxmimum */
+#define RANDOM_RAND_MAX 65535U
+
+void oc_random_destroy(void);
+
+#endif /* OC_RANDOM_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_signal_main_loop.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_signal_main_loop.h b/libs/iotivity/src/port/oc_signal_main_loop.h
new file mode 100644
index 0000000..7f18f9a
--- /dev/null
+++ b/libs/iotivity/src/port/oc_signal_main_loop.h
@@ -0,0 +1,22 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_SIGNAL_MAIN_LOOP_H
+#define OC_SIGNAL_MAIN_LOOP_H
+
+void oc_signal_main_loop(void);
+
+#endif /* OC_SIGNAL_MAIN_LOOP_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/port/oc_storage.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/port/oc_storage.h b/libs/iotivity/src/port/oc_storage.h
new file mode 100644
index 0000000..48ec0c8
--- /dev/null
+++ b/libs/iotivity/src/port/oc_storage.h
@@ -0,0 +1,27 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_STORAGE_H
+#define OC_STORAGE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+int oc_storage_config(const char *store);
+long oc_storage_read(const char *store, uint8_t *buf, size_t size);
+long oc_storage_write(const char *store, uint8_t *buf, size_t size);
+
+#endif /* OC_STORAGE_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_acl.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_acl.c b/libs/iotivity/src/security/oc_acl.c
new file mode 100644
index 0000000..173873b
--- /dev/null
+++ b/libs/iotivity/src/security/oc_acl.c
@@ -0,0 +1,412 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_acl.h"
+#include "config.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+#include "oc_dtls.h"
+#include "oc_rep.h"
+#include <stddef.h>
+#include <strings.h>
+
+#define MAX_NUM_RES_PERM_PAIRS                                                 \
+  (NUM_OC_CORE_RESOURCES + (MAX_NUM_SUBJECTS + 1) * (MAX_APP_RESOURCES))
+OC_MEMB(ace_l, oc_sec_ace_t, MAX_NUM_SUBJECTS + 1);
+OC_MEMB(res_l, oc_sec_acl_res_t, MAX_NUM_RES_PERM_PAIRS);
+static oc_uuid_t WILDCARD = {.id = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                     0, 0 } };
+static oc_sec_acl_t ac_list = { 0 };
+
+static void
+get_sub_perm_groups(oc_sec_ace_t *ace, uint16_t *groups, int *n)
+{
+  int i = 0, j;
+  oc_sec_acl_res_t *res = oc_list_head(ace->resources);
+  while (res != NULL) {
+    groups[i++] = res->permissions;
+    res = res->next;
+  }
+  for (i = 0; i < (*n - 1); i++) {
+    for (j = (i + 1); j < *n; j++) {
+      if (groups[i] > groups[j]) {
+        uint16_t t = groups[i];
+        groups[i] = groups[j];
+        groups[j] = t;
+      }
+    }
+  }
+  j = 0;
+  for (i = 1; i < *n; i++) {
+    if (groups[j] != groups[i])
+      groups[++j] = groups[i];
+  }
+  *n = j + 1;
+}
+
+void
+oc_sec_encode_acl(void)
+{
+  int i, n;
+  char uuid[37];
+  oc_rep_start_root_object();
+  oc_process_baseline_interface(oc_core_get_resource_by_index(OCF_SEC_ACL));
+  oc_rep_set_object(root, aclist);
+  oc_rep_set_array(aclist, aces);
+  oc_sec_ace_t *sub = oc_list_head(ac_list.subjects);
+  while (sub != NULL) {
+    if (strncmp(sub->subjectuuid.id, WILDCARD.id, 16) == 0) {
+      uuid[0] = '*';
+      uuid[1] = '\0';
+    } else {
+      oc_uuid_to_str(&sub->subjectuuid, uuid, 37);
+    }
+    LOG("oc_sec_acl_encode: subject %s\n", uuid);
+    n = oc_list_length(sub->resources);
+    uint16_t groups[n];
+    get_sub_perm_groups(sub, groups, &n);
+    for (i = 0; i < n; i++) {
+      oc_rep_object_array_start_item(aces);
+      oc_rep_set_text_string(aces, subjectuuid, uuid);
+      oc_rep_set_uint(aces, permission, groups[i]);
+      oc_rep_set_array(aces, resources);
+      oc_sec_acl_res_t *res = oc_list_head(sub->resources);
+      while (res != NULL) {
+        if (res->permissions == groups[i]) {
+          LOG("oc_sec_acl_encode: adding resource %s\n",
+              oc_string(res->resource->uri));
+          oc_rep_object_array_start_item(resources);
+          oc_rep_set_text_string(resources, href,
+                                 oc_string(res->resource->uri));
+          oc_rep_set_text_string(resources, rel, "");
+          oc_rep_set_text_string(resources, rt, "");
+          oc_rep_set_text_string(resources, if, "");
+          oc_rep_object_array_end_item(resources);
+        }
+        res = res->next;
+      }
+      oc_rep_close_array(aces, resources);
+      oc_rep_object_array_end_item(aces);
+    }
+    sub = sub->next;
+  }
+  oc_rep_close_array(aclist, aces);
+  oc_rep_close_object(root, aclist);
+  oc_uuid_to_str(&ac_list.rowneruuid, uuid, 37);
+  oc_rep_set_text_string(root, rowneruuid, uuid);
+  oc_rep_end_root_object();
+}
+
+static oc_sec_acl_res_t *
+oc_sec_acl_get_ace(oc_uuid_t *subjectuuid, oc_resource_t *resource, bool create)
+{
+  oc_sec_ace_t *ace = (oc_sec_ace_t *)oc_list_head(ac_list.subjects);
+  oc_sec_acl_res_t *res = NULL;
+
+#ifdef DEBUG
+  char uuid[37];
+  oc_uuid_to_str(subjectuuid, uuid, 37);
+#endif
+
+  while (ace != NULL) {
+    if (strncmp(ace->subjectuuid.id, subjectuuid->id, 16) == 0)
+      goto got_ace;
+    ace = oc_list_item_next(ace);
+  }
+
+  if (create)
+    goto new_ace;
+
+  LOG("Could not find ACE for subject %s\n", uuid);
+
+  goto done;
+
+got_ace:
+  LOG("Found ACE for subject %s\n", uuid);
+  res = (oc_sec_acl_res_t *)oc_list_head(ace->resources);
+
+  while (res != NULL) {
+    if (res->resource == resource) {
+      LOG("Found permissions mask for resource %s in ACE\n",
+          oc_string(res->resource->uri));
+      goto done;
+    }
+    res = oc_list_item_next(res);
+  }
+
+  if (create)
+    goto new_res;
+
+  goto done;
+
+new_ace:
+  ace = oc_memb_alloc(&ace_l);
+
+  if (!ace)
+    goto done;
+
+  LOG("Created new ACE for subject %s\n", uuid);
+
+  OC_LIST_STRUCT_INIT(ace, resources);
+  strncpy(ace->subjectuuid.id, subjectuuid->id, 16);
+  oc_list_add(ac_list.subjects, ace);
+
+new_res:
+  res = oc_memb_alloc(&res_l);
+  if (res) {
+    res->resource = resource;
+    LOG("Adding new resource %s to ACE\n", oc_string(res->resource->uri));
+    oc_list_add(ace->resources, res);
+  }
+
+done:
+  return res;
+}
+
+static bool
+oc_sec_update_acl(oc_uuid_t *subjectuuid, oc_resource_t *resource,
+                  uint16_t permissions)
+{
+  oc_sec_acl_res_t *res = oc_sec_acl_get_ace(subjectuuid, resource, true);
+
+  if (!res)
+    return false;
+
+  res->permissions = permissions;
+
+  LOG("Added resource with permissions: %d\n", res->permissions);
+
+  return true;
+}
+
+void
+oc_sec_acl_init(void)
+{
+  OC_LIST_STRUCT_INIT(&ac_list, subjects);
+}
+
+void
+oc_sec_acl_default(void)
+{
+  bool success = true;
+  int i;
+  oc_resource_t *resource;
+  for (i = 0; i < NUM_OC_CORE_RESOURCES; i++) {
+    resource = oc_core_get_resource_by_index(i);
+    if (i < OCF_SEC_DOXM || i > OCF_SEC_CRED)
+      success &= oc_sec_update_acl(&WILDCARD, resource, 2);
+    else
+      success &= oc_sec_update_acl(&WILDCARD, resource, 6);
+  }
+  LOG("ACL for core resources initialized %d\n", success);
+  oc_uuid_t *device = oc_core_get_device_id(0);
+  memcpy(&ac_list.rowneruuid, device, sizeof(oc_uuid_t));
+}
+
+bool
+oc_sec_check_acl(oc_method_t method, oc_resource_t *resource,
+                 oc_endpoint_t *endpoint)
+{
+  bool granted = false;
+  oc_sec_acl_res_t *res = NULL;
+  oc_uuid_t *identity = (oc_uuid_t *)oc_sec_dtls_get_peer_uuid(endpoint);
+
+  if (identity) {
+    res = oc_sec_acl_get_ace(identity, resource, false);
+  }
+
+  if (!res) { // Try Anonymous
+    res = oc_sec_acl_get_ace(&WILDCARD, resource, false);
+  }
+
+  if (!res)
+    return granted;
+
+  LOG("Got permissions mask %d\n", res->permissions);
+
+  if (res->permissions & OC_PERM_CREATE || res->permissions & OC_PERM_UPDATE) {
+    switch (method) {
+    case OC_PUT:
+    case OC_POST:
+      granted = true;
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (res->permissions & OC_PERM_RETRIEVE ||
+      res->permissions & OC_PERM_NOTIFY) {
+    switch (method) {
+    case OC_GET:
+      granted = true;
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (res->permissions & OC_PERM_DELETE) {
+    switch (method) {
+    case OC_DELETE:
+      granted = true;
+      break;
+    default:
+      break;
+    }
+  }
+
+  return granted;
+}
+
+bool
+oc_sec_decode_acl(oc_rep_t *rep)
+{
+  uint16_t permissions = 0;
+  oc_uuid_t subjectuuid;
+  oc_rep_t *resources = 0;
+  int len = 0;
+  while (rep != NULL) {
+    len = oc_string_len(rep->name);
+    switch (rep->type) {
+    case STRING:
+      if (len == 10 && strncmp(oc_string(rep->name), "rowneruuid", 10) == 0) {
+        oc_str_to_uuid(oc_string(rep->value_string), &ac_list.rowneruuid);
+      }
+      break;
+    case OBJECT: {
+      oc_rep_t *aclist = rep->value_object;
+      while (aclist != NULL) {
+        switch (aclist->type) {
+        case OBJECT_ARRAY: {
+          oc_rep_t *aces = aclist->value_object_array;
+          while (aces != NULL) {
+            oc_rep_t *ace = aces->value_object;
+            while (ace != NULL) {
+              len = oc_string_len(ace->name);
+              switch (ace->type) {
+              case STRING:
+                if (len == 11 &&
+                    strncmp(oc_string(ace->name), "subjectuuid", 11) == 0) {
+                  if (strncmp(oc_string(ace->value_string), "*", 1) == 0)
+                    strncpy(subjectuuid.id, WILDCARD.id, 16);
+                  else
+                    oc_str_to_uuid(oc_string(ace->value_string), &subjectuuid);
+                }
+                break;
+              case INT:
+                if (len == 10 &&
+                    strncmp(oc_string(ace->name), "permission", 10) == 0)
+                  permissions = ace->value_int;
+                break;
+              case OBJECT_ARRAY:
+                if (len == 9 &&
+                    strncmp(oc_string(ace->name), "resources", 9) == 0)
+                  resources = ace->value_object_array;
+                break;
+              default:
+                break;
+              }
+              ace = ace->next;
+            }
+
+            while (resources != NULL) {
+              oc_rep_t *resource = resources->value_object;
+              while (resource != NULL) {
+                switch (resource->type) {
+                case STRING:
+                  if (oc_string_len(resource->name) == 4 &&
+                      strncasecmp(oc_string(resource->name), "href", 4) == 0) {
+                    oc_resource_t *res = oc_core_get_resource_by_uri(
+                      oc_string(resource->value_string));
+
+#ifdef OC_SERVER
+                    if (!res)
+                      res = oc_ri_get_app_resource_by_uri(
+                        oc_string(resource->value_string));
+#endif /* OC_SERVER */
+
+                    if (!res) {
+                      LOG(
+                        "\n\noc_sec_acl_decode: could not find resource %s\n\n",
+                        oc_string(resource->value_string));
+                      return false;
+                    }
+
+                    if (!oc_sec_update_acl(&subjectuuid, res, permissions)) {
+                      LOG("\n\noc_sec_acl_decode: could not update ACE with "
+                          "resource %s permissions\n\n",
+                          oc_string(res->uri));
+                      return false;
+                    }
+                  }
+                  break;
+                default:
+                  break;
+                }
+                resource = resource->next;
+              }
+              resources = resources->next;
+            }
+            aces = aces->next;
+          }
+        } break;
+        default:
+          break;
+        }
+        aclist = aclist->next;
+      }
+    } break;
+    default:
+      break;
+    }
+    rep = rep->next;
+  }
+  return true;
+}
+
+/*
+  {
+  "aclist":
+  {
+  "aces":
+  [
+  {
+  "subjectuuid": "61646d69-6e44-6576-6963-655575696430",
+  "resources":
+  [
+  {"href": "/led/1", "rel": "", "rt": "", "if": ""},
+  {"href": "/switch/1", "rel": "", "rt": "", "if": ""}
+  ],
+  "permission": 31
+  }
+  ]
+  },
+  "rowneruuid": "5cdf40b1-c12e-432b-67a2-aa79a3f08c59"
+  }
+*/
+void
+post_acl(oc_request_t *request, oc_interface_mask_t interface)
+{
+  if (oc_sec_decode_acl(request->request_payload))
+    oc_send_response(request, OC_STATUS_CREATED);
+  else
+    oc_send_response(request, OC_STATUS_INTERNAL_SERVER_ERROR);
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_acl.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_acl.h b/libs/iotivity/src/security/oc_acl.h
new file mode 100644
index 0000000..5315506
--- /dev/null
+++ b/libs/iotivity/src/security/oc_acl.h
@@ -0,0 +1,63 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_ACL_H_
+#define OC_ACL_H_
+
+#include "oc_ri.h"
+#include "oc_uuid.h"
+#include "port/oc_log.h"
+#include "util/oc_list.h"
+#include "util/oc_memb.h"
+#include <stdbool.h>
+
+typedef enum {
+  OC_PERM_CREATE = (1 << 0),
+  OC_PERM_RETRIEVE = (1 << 1),
+  OC_PERM_UPDATE = (1 << 2),
+  OC_PERM_DELETE = (1 << 3),
+  OC_PERM_NOTIFY = (1 << 4)
+} oc_sec_acl_permissions_mask_t;
+
+typedef struct
+{
+  OC_LIST_STRUCT(subjects);
+  oc_uuid_t rowneruuid;
+} oc_sec_acl_t;
+
+typedef struct oc_sec_acl_res_s
+{
+  struct oc_sec_acl_res_s *next;
+  oc_resource_t *resource;
+  uint16_t permissions;
+} oc_sec_acl_res_t;
+
+typedef struct oc_sec_ace_s
+{
+  struct oc_sec_ace_s *next;
+  OC_LIST_STRUCT(resources);
+  oc_uuid_t subjectuuid;
+} oc_sec_ace_t;
+
+void oc_sec_acl_default(void);
+void oc_sec_encode_acl(void);
+bool oc_sec_decode_acl(oc_rep_t *rep);
+void oc_sec_acl_init(void);
+void post_acl(oc_request_t *request, oc_interface_mask_t interface);
+bool oc_sec_check_acl(oc_method_t method, oc_resource_t *resource,
+                      oc_endpoint_t *endpoint);
+
+#endif /* OC_ACL_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_cred.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_cred.c b/libs/iotivity/src/security/oc_cred.c
new file mode 100644
index 0000000..2cccf71
--- /dev/null
+++ b/libs/iotivity/src/security/oc_cred.c
@@ -0,0 +1,200 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_cred.h"
+#include "config.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+#include "oc_doxm.h"
+#include "oc_dtls.h"
+#include "port/oc_log.h"
+#include "util/oc_list.h"
+#include "util/oc_memb.h"
+
+OC_LIST(creds_l);
+OC_MEMB(creds, oc_sec_cred_t, MAX_NUM_SUBJECTS + 1);
+#define OXM_JUST_WORKS "oic.sec.doxm.jw"
+
+oc_sec_cred_t *
+oc_sec_find_cred(oc_uuid_t *subjectuuid)
+{
+  oc_sec_cred_t *cred = oc_list_head(creds_l);
+  while (cred != NULL) {
+    if (strncmp(cred->subjectuuid.id, subjectuuid->id, 16) == 0) {
+      return cred;
+    }
+    cred = cred->next;
+  }
+  return NULL;
+}
+
+oc_sec_cred_t *
+oc_sec_get_cred(oc_uuid_t *subjectuuid)
+{
+  oc_sec_cred_t *cred = oc_sec_find_cred(subjectuuid);
+  if (cred == NULL) {
+    cred = oc_memb_alloc(&creds);
+    strncpy(cred->subjectuuid.id, subjectuuid->id, 16);
+    oc_list_add(creds_l, cred);
+  }
+  return cred;
+}
+
+void
+oc_sec_encode_cred(void)
+{
+  oc_sec_cred_t *creds = oc_list_head(creds_l);
+  char uuid[37];
+  oc_rep_start_root_object();
+  oc_process_baseline_interface(oc_core_get_resource_by_index(OCF_SEC_CRED));
+  oc_rep_set_array(root, creds);
+  if (creds == NULL) {
+    oc_rep_object_array_start_item(creds);
+    oc_rep_object_array_end_item(creds);
+  }
+  while (creds != NULL) {
+    oc_rep_object_array_start_item(creds);
+    oc_rep_set_int(creds, credid, creds->credid);
+    oc_rep_set_int(creds, credtype, creds->credtype);
+    oc_uuid_to_str(&creds->subjectuuid, uuid, 37);
+    oc_rep_set_text_string(creds, subjectuuid, uuid);
+    oc_rep_set_object(creds, privatedata);
+    oc_rep_set_byte_string(privatedata, data, creds->key);
+    oc_rep_set_text_string(privatedata, encoding, "oic.sec.encoding.raw");
+    oc_rep_close_object(creds, privatedata);
+    oc_rep_object_array_end_item(creds);
+    creds = creds->next;
+  }
+  oc_rep_close_array(root, creds);
+  oc_rep_end_root_object();
+}
+
+bool
+oc_sec_decode_cred(oc_rep_t *rep, oc_sec_cred_t **owner)
+{
+  oc_sec_doxm_t *doxm = oc_sec_get_doxm();
+  int credid = 0, credtype = 0;
+  char subjectuuid[37] = { 0 };
+  oc_uuid_t subject;
+  oc_sec_cred_t *credobj;
+  bool got_key = false;
+  int len = 0;
+  uint8_t key[16];
+  while (rep != NULL) {
+    len = oc_string_len(rep->name);
+    switch (rep->type) {
+    case STRING:
+      if (len == 10 && strncmp(oc_string(rep->name), "rowneruuid", 10) == 0) {
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm->rowneruuid);
+      }
+      break;
+    case OBJECT_ARRAY: {
+      oc_rep_t *creds_array = rep->value_object_array;
+      while (creds_array != NULL) {
+        oc_rep_t *cred = creds_array->value_object;
+        bool valid_cred = false;
+        while (cred != NULL) {
+          len = oc_string_len(cred->name);
+          valid_cred = true;
+          switch (cred->type) {
+          case INT:
+            if (len == 6 && strncmp(oc_string(cred->name), "credid", 6) == 0)
+              credid = cred->value_int;
+            else if (len == 8 &&
+                     strncmp(oc_string(cred->name), "credtype", 8) == 0)
+              credtype = cred->value_int;
+            break;
+          case STRING:
+            if (len == 11 &&
+                strncmp(oc_string(cred->name), "subjectuuid", 11) == 0) {
+              strncpy(subjectuuid, oc_string(cred->value_string),
+                      oc_string_len(cred->value_string) + 1);
+            }
+            break;
+          case OBJECT: {
+            oc_rep_t *data = cred->value_object;
+            while (data != NULL) {
+              switch (data->type) {
+              case BYTE_STRING: {
+                got_key = true;
+                int psk = 0;
+                uint8_t *p = oc_cast(data->value_string, uint8_t);
+                size_t size = oc_string_len(data->value_string);
+                if (size != 16) {
+                  return false;
+                }
+                while (psk < size) {
+                  key[psk] = p[psk];
+                  psk++;
+                }
+              } break;
+              default:
+                break;
+              }
+              data = data->next;
+            }
+          } break;
+          default:
+            break;
+          }
+          cred = cred->next;
+        }
+        if (valid_cred) {
+          oc_str_to_uuid(subjectuuid, &subject);
+          credobj = oc_sec_get_cred(&subject);
+          credobj->credid = credid;
+          credobj->credtype = credtype;
+
+          if (got_key) {
+            memcpy(credobj->key, key, 16);
+          } else {
+            if (owner)
+              *owner = credobj;
+          }
+        }
+        creds_array = creds_array->next;
+      }
+    } break;
+    default:
+      break;
+    }
+    rep = rep->next;
+  }
+  return true;
+}
+
+void
+post_cred(oc_request_t *request, oc_interface_mask_t interface)
+{
+  oc_sec_doxm_t *doxm = oc_sec_get_doxm();
+  oc_sec_cred_t *owner = NULL;
+  bool success = oc_sec_decode_cred(request->request_payload, &owner);
+  if (owner && strncmp(owner->subjectuuid.id, doxm->rowneruuid.id, 16) == 0) {
+    oc_uuid_t *dev = oc_core_get_device_id(0);
+    oc_sec_derive_owner_psk(request->origin, OXM_JUST_WORKS,
+                            strlen(OXM_JUST_WORKS), owner->subjectuuid.id, 16,
+                            dev->id, 16, owner->key, 16);
+  }
+  if (!success) {
+    oc_send_response(request, OC_STATUS_BAD_REQUEST);
+  } else {
+    oc_send_response(request, OC_STATUS_CHANGED);
+  }
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_cred.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_cred.h b/libs/iotivity/src/security/oc_cred.h
new file mode 100644
index 0000000..81e64c5
--- /dev/null
+++ b/libs/iotivity/src/security/oc_cred.h
@@ -0,0 +1,40 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_CRED_H_
+#define OC_CRED_H_
+
+#include "oc_ri.h"
+#include "oc_uuid.h"
+#include <stdint.h>
+
+typedef struct oc_sec_cred_s
+{
+  struct oc_sec_cred_s *next;
+  int credid;
+  int credtype;
+  oc_uuid_t subjectuuid;
+  uint8_t key[16]; // Supports only 128-bit keys
+} oc_sec_cred_t;
+
+void oc_sec_encode_cred(void);
+bool oc_sec_decode_cred(oc_rep_t *rep, oc_sec_cred_t **owner);
+oc_sec_cred_t *oc_sec_find_cred(oc_uuid_t *subjectuuid);
+oc_sec_cred_t *oc_sec_get_cred(oc_uuid_t *subjectuuid);
+void put_cred(oc_request_t *request, oc_interface_mask_t interface);
+void post_cred(oc_request_t *request, oc_interface_mask_t interface);
+
+#endif /* OC_CRED_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_doxm.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_doxm.c b/libs/iotivity/src/security/oc_doxm.c
new file mode 100644
index 0000000..ceb6045
--- /dev/null
+++ b/libs/iotivity/src/security/oc_doxm.c
@@ -0,0 +1,128 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_SECURITY
+
+#include "oc_doxm.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+#include <stddef.h>
+#include <strings.h>
+
+static oc_sec_doxm_t doxm;
+
+// Fix.. multiple devices.. how many doxms, when we retrieve
+// credentials, how do we correlate between creds and devices?
+void
+oc_sec_doxm_default(void)
+{
+  doxm.oxmsel = 0;
+  doxm.sct = 1;
+  doxm.owned = false;
+  doxm.dpc = false;
+  oc_uuid_t *deviceuuid = oc_core_get_device_id(0);
+  oc_gen_uuid(deviceuuid);
+  memcpy(&doxm.deviceuuid, deviceuuid, sizeof(oc_uuid_t));
+  memset(doxm.devowneruuid.id, 0, 16);
+  memset(doxm.rowneruuid.id, 0, 16);
+}
+
+void
+oc_sec_encode_doxm(void)
+{
+  int oxms[1] = { 0 };
+  char uuid[37];
+  oc_rep_start_root_object();
+  oc_process_baseline_interface(oc_core_get_resource_by_index(OCF_SEC_DOXM));
+  oc_rep_set_int_array(root, oxms, oxms, 1);
+  oc_rep_set_int(root, oxmsel, doxm.oxmsel);
+  oc_rep_set_int(root, sct, doxm.sct);
+  oc_rep_set_boolean(root, owned, doxm.owned);
+  oc_uuid_to_str(&doxm.deviceuuid, uuid, 37);
+  oc_rep_set_text_string(root, deviceuuid, uuid);
+  oc_uuid_to_str(&doxm.devowneruuid, uuid, 37);
+  oc_rep_set_text_string(root, devowneruuid, uuid);
+  oc_uuid_to_str(&doxm.rowneruuid, uuid, 37);
+  oc_rep_set_text_string(root, rowneruuid, uuid);
+  oc_rep_end_root_object();
+}
+
+oc_sec_doxm_t *
+oc_sec_get_doxm(void)
+{
+  return &doxm;
+}
+
+void
+get_doxm(oc_request_t *request, oc_interface_mask_t interface)
+{
+  switch (interface) {
+  case OC_IF_BASELINE: {
+    char *q;
+    int ql = oc_get_query_value(request, "owned", &q);
+    if (ql && ((doxm.owned == 1 && strncasecmp(q, "false", 5) == 0) ||
+               (doxm.owned == 0 && strncasecmp(q, "true", 4) == 0))) {
+      oc_ignore_request(request);
+    } else {
+      oc_sec_encode_doxm();
+      oc_send_response(request, OC_STATUS_OK);
+    }
+  } break;
+  default:
+    break;
+  }
+}
+
+void
+oc_sec_decode_doxm(oc_rep_t *rep)
+{
+  while (rep != NULL) {
+    switch (rep->type) {
+    case BOOL:
+      if (strncmp(oc_string(rep->name), "owned", 5) == 0)
+        doxm.owned = rep->value_boolean;
+      else if (strncmp(oc_string(rep->name), "dpc", 3) == 0)
+        doxm.dpc = rep->value_boolean;
+      break;
+    case INT:
+      if (strncmp(oc_string(rep->name), "oxmsel", 6) == 0)
+        doxm.oxmsel = rep->value_int;
+      else if (strncmp(oc_string(rep->name), "sct", 3) == 0)
+        doxm.sct = rep->value_int;
+      break;
+    case STRING:
+      if (strncmp(oc_string(rep->name), "deviceuuid", 10) == 0)
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm.deviceuuid);
+      else if (strncmp(oc_string(rep->name), "devowneruuid", 12) == 0)
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm.devowneruuid);
+      else if (strncmp(oc_string(rep->name), "rowneruuid", 10) == 0)
+        oc_str_to_uuid(oc_string(rep->value_string), &doxm.rowneruuid);
+      break;
+    default:
+      break;
+    }
+    rep = rep->next;
+  }
+}
+
+void
+post_doxm(oc_request_t *request, oc_interface_mask_t interface)
+{
+  oc_sec_decode_doxm(request->request_payload);
+  oc_send_response(request, OC_STATUS_CHANGED);
+}
+
+#endif /* OC_SECURITY */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/security/oc_doxm.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/security/oc_doxm.h b/libs/iotivity/src/security/oc_doxm.h
new file mode 100644
index 0000000..17d9b5d
--- /dev/null
+++ b/libs/iotivity/src/security/oc_doxm.h
@@ -0,0 +1,45 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_DOXM_H_
+#define OC_DOXM_H_
+
+#include "oc_uuid.h"
+#include "port/oc_log.h"
+#include "util/oc_list.h"
+#include "util/oc_memb.h"
+
+#include "oc_ri.h"
+#include <stdbool.h>
+
+typedef struct
+{
+  int oxmsel;
+  int sct;
+  bool owned;
+  bool dpc;
+  oc_uuid_t deviceuuid;
+  oc_uuid_t devowneruuid;
+  oc_uuid_t rowneruuid;
+} oc_sec_doxm_t;
+
+void oc_sec_decode_doxm(oc_rep_t *rep);
+void oc_sec_encode_doxm(void);
+oc_sec_doxm_t *oc_sec_get_doxm(void);
+void oc_sec_doxm_default(void);
+void get_doxm(oc_request_t *request, oc_interface_mask_t interface);
+void post_doxm(oc_request_t *request, oc_interface_mask_t interface);
+#endif /* OC_DOXM_H_ */


[10/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
Add tinycbor and iotivity constrained to the repo.

These are not working yet.  Need to add basic test cases for cbor
Need to add the OS support for iotivity


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/ece29bb3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/ece29bb3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/ece29bb3

Branch: refs/heads/develop
Commit: ece29bb340b4ec83b635e3a13cdca8c21d458d19
Parents: 0b82d07
Author: Paul Dietrich <pa...@yahoo.com>
Authored: Wed Sep 14 13:18:31 2016 -0700
Committer: Paul Dietrich <pa...@yahoo.com>
Committed: Wed Sep 14 13:32:32 2016 -0700

----------------------------------------------------------------------
 libs/iotivity/include/iotivity/oc_api.h         |  165 +++
 libs/iotivity/include/iotivity/oc_buffer.h      |   32 +
 .../iotivity/include/iotivity/oc_client_state.h |   88 ++
 libs/iotivity/include/iotivity/oc_constants.h   |   43 +
 libs/iotivity/include/iotivity/oc_core_res.h    |   52 +
 libs/iotivity/include/iotivity/oc_discovery.h   |   22 +
 libs/iotivity/include/iotivity/oc_helpers.h     |   78 ++
 .../include/iotivity/oc_network_events.h        |   29 +
 libs/iotivity/include/iotivity/oc_rep.h         |  228 +++
 libs/iotivity/include/iotivity/oc_ri.h          |  176 +++
 libs/iotivity/include/iotivity/oc_uuid.h        |   31 +
 libs/iotivity/pkg.yml                           |   37 +
 libs/iotivity/src/api/oc_buffer.c               |  138 ++
 libs/iotivity/src/api/oc_client_api.c           |  287 ++++
 libs/iotivity/src/api/oc_core_res.c             |  280 ++++
 libs/iotivity/src/api/oc_discovery.c            |  298 ++++
 libs/iotivity/src/api/oc_events.h               |   34 +
 libs/iotivity/src/api/oc_helpers.c              |  164 +++
 libs/iotivity/src/api/oc_main.c                 |  119 ++
 libs/iotivity/src/api/oc_network_events.c       |   57 +
 libs/iotivity/src/api/oc_rep.c                  |  301 ++++
 libs/iotivity/src/api/oc_ri.c                   | 1016 ++++++++++++++
 libs/iotivity/src/api/oc_server_api.c           |  291 ++++
 libs/iotivity/src/api/oc_uuid.c                 |  119 ++
 libs/iotivity/src/messaging/coap/coap.c         | 1186 ++++++++++++++++
 libs/iotivity/src/messaging/coap/coap.h         |  297 ++++
 libs/iotivity/src/messaging/coap/conf.h         |   71 +
 libs/iotivity/src/messaging/coap/constants.h    |  158 +++
 libs/iotivity/src/messaging/coap/engine.c       |  333 +++++
 libs/iotivity/src/messaging/coap/engine.h       |   48 +
 libs/iotivity/src/messaging/coap/observe.c      |  319 +++++
 libs/iotivity/src/messaging/coap/observe.h      |   80 ++
 libs/iotivity/src/messaging/coap/oc_coap.h      |   39 +
 libs/iotivity/src/messaging/coap/separate.c     |  152 ++
 libs/iotivity/src/messaging/coap/separate.h     |   71 +
 libs/iotivity/src/messaging/coap/transactions.c |  202 +++
 libs/iotivity/src/messaging/coap/transactions.h |   75 +
 libs/iotivity/src/port/mynewt/config.h          |   50 +
 libs/iotivity/src/port/oc_assert.h              |   42 +
 libs/iotivity/src/port/oc_clock.h               |  102 ++
 libs/iotivity/src/port/oc_connectivity.h        |   83 ++
 libs/iotivity/src/port/oc_log.h                 |   46 +
 .../iotivity/src/port/oc_network_events_mutex.h |   26 +
 libs/iotivity/src/port/oc_random.h              |   56 +
 libs/iotivity/src/port/oc_signal_main_loop.h    |   22 +
 libs/iotivity/src/port/oc_storage.h             |   27 +
 libs/iotivity/src/security/oc_acl.c             |  412 ++++++
 libs/iotivity/src/security/oc_acl.h             |   63 +
 libs/iotivity/src/security/oc_cred.c            |  200 +++
 libs/iotivity/src/security/oc_cred.h            |   40 +
 libs/iotivity/src/security/oc_doxm.c            |  128 ++
 libs/iotivity/src/security/oc_doxm.h            |   45 +
 libs/iotivity/src/security/oc_dtls.c            |  372 +++++
 libs/iotivity/src/security/oc_dtls.h            |   50 +
 libs/iotivity/src/security/oc_pstat.c           |  119 ++
 libs/iotivity/src/security/oc_pstat.h           |   39 +
 libs/iotivity/src/security/oc_store.c           |  158 +++
 libs/iotivity/src/security/oc_store.h           |   26 +
 libs/iotivity/src/security/oc_svr.c             |   51 +
 libs/iotivity/src/security/oc_svr.h             |   22 +
 libs/iotivity/src/util/oc_etimer.c              |  263 ++++
 libs/iotivity/src/util/oc_etimer.h              |  247 ++++
 libs/iotivity/src/util/oc_list.c                |  317 +++++
 libs/iotivity/src/util/oc_list.h                |  144 ++
 libs/iotivity/src/util/oc_memb.c                |  111 ++
 libs/iotivity/src/util/oc_memb.h                |  127 ++
 libs/iotivity/src/util/oc_mmem.c                |  154 +++
 libs/iotivity/src/util/oc_mmem.h                |   53 +
 libs/iotivity/src/util/oc_process.c             |  346 +++++
 libs/iotivity/src/util/oc_process.h             |  527 +++++++
 libs/iotivity/src/util/oc_timer.c               |  131 ++
 libs/iotivity/src/util/oc_timer.h               |   88 ++
 libs/iotivity/src/util/pt/lc-addrlabels.h       |   86 ++
 libs/iotivity/src/util/pt/lc-switch.h           |   79 ++
 libs/iotivity/src/util/pt/lc.h                  |  130 ++
 libs/iotivity/src/util/pt/pt-sem.h              |  233 ++++
 libs/iotivity/src/util/pt/pt.h                  |  333 +++++
 libs/tinycbor/include/tinycbor/assert_p.h       |   29 +
 libs/tinycbor/include/tinycbor/cbor.h           |  479 +++++++
 .../tinycbor/include/tinycbor/cborconstants_p.h |   52 +
 libs/tinycbor/include/tinycbor/cborjson.h       |   62 +
 .../include/tinycbor/compilersupport_p.h        |  218 +++
 .../include/tinycbor/extract_number_p.h         |   78 ++
 libs/tinycbor/include/tinycbor/math_support_p.h |   47 +
 libs/tinycbor/pkg.yml                           |   26 +
 libs/tinycbor/src/cborencoder.c                 |  629 +++++++++
 .../src/cborencoder_close_container_checked.c   |   82 ++
 libs/tinycbor/src/cborerrorstrings.c            |  165 +++
 libs/tinycbor/src/cborparser.c                  | 1293 ++++++++++++++++++
 libs/tinycbor/src/cborparser_dup_string.c       |  113 ++
 libs/tinycbor/src/cborpretty.c                  |  470 +++++++
 libs/tinycbor/src/cbortojson.c                  |  686 ++++++++++
 libs/tinycbor/src/open_memstream.c              |  117 ++
 93 files changed, 17210 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_api.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_api.h b/libs/iotivity/include/iotivity/oc_api.h
new file mode 100644
index 0000000..e607668
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_api.h
@@ -0,0 +1,165 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_API_H
+#define OC_API_H
+
+#include "messaging/coap/oc_coap.h"
+#include "oc_ri.h"
+#include "port/oc_signal_main_loop.h"
+#include "port/oc_storage.h"
+
+typedef struct
+{
+  void (*init)(void);
+
+#ifdef OC_SECURITY
+  void (*get_credentials)(void);
+#endif /* OC_SECURITY */
+
+#ifdef OC_SERVER
+  void (*register_resources)(void);
+#endif /* OC_SERVER */
+
+#ifdef OC_CLIENT
+  void (*requests_entry)(void);
+#endif /* OC_CLIENT */
+} oc_handler_t;
+
+typedef void (*oc_init_platform_cb_t)(void *data);
+typedef void (*oc_add_device_cb_t)(void *data);
+
+int oc_main_init(oc_handler_t *handler);
+
+oc_clock_time_t oc_main_poll(void);
+
+void oc_main_shutdown(void);
+
+void oc_add_device(const char *uri, const char *rt, const char *name,
+                   const char *spec_version, const char *data_model_version,
+                   oc_add_device_cb_t add_device_cb, void *data);
+
+#define oc_set_custom_device_property(prop, value)                             \
+  oc_rep_set_text_string(root, prop, value)
+
+void oc_init_platform(const char *mfg_name,
+                      oc_init_platform_cb_t init_platform_cb, void *data);
+
+#define oc_set_custom_platform_property(prop, value)                           \
+  oc_rep_set_text_string(root, prop, value)
+
+/** Server side */
+oc_resource_t *oc_new_resource(const char *uri, uint8_t num_resource_types,
+                               int device);
+void oc_resource_bind_resource_interface(oc_resource_t *resource,
+                                         uint8_t interface);
+void oc_resource_set_default_interface(oc_resource_t *resource,
+                                       oc_interface_mask_t interface);
+void oc_resource_bind_resource_type(oc_resource_t *resource, const char *type);
+
+void oc_process_baseline_interface(oc_resource_t *resource);
+
+#ifdef OC_SECURITY
+void oc_resource_make_secure(oc_resource_t *resource);
+#endif /* OC_SECURITY */
+
+void oc_resource_set_discoverable(oc_resource_t *resource);
+void oc_resource_set_observable(oc_resource_t *resource);
+void oc_resource_set_periodic_observable(oc_resource_t *resource,
+                                         uint16_t seconds);
+void oc_resource_set_request_handler(oc_resource_t *resource,
+                                     oc_method_t method,
+                                     oc_request_handler_t handler);
+bool oc_add_resource(oc_resource_t *resource);
+void oc_delete_resource(oc_resource_t *resource);
+void oc_deactivate_resource(oc_resource_t *resource);
+
+void oc_init_query_iterator(oc_request_t *request);
+int oc_interate_query(oc_request_t *request, char **key, int *key_len,
+                      char **value, int *value_len);
+int oc_get_query_value(oc_request_t *request, const char *key, char **value);
+
+void oc_send_response(oc_request_t *request, oc_status_t response_code);
+void oc_ignore_request(oc_request_t *request);
+
+void oc_indicate_separate_response(oc_request_t *request,
+                                   oc_separate_response_t *response);
+void oc_set_separate_response_buffer(oc_separate_response_t *handle);
+void oc_send_separate_response(oc_separate_response_t *handle,
+                               oc_status_t response_code);
+
+int oc_notify_observers(oc_resource_t *resource);
+
+/** Client side */
+#include "oc_client_state.h"
+
+bool oc_do_ip_discovery(const char *rt, oc_discovery_cb_t handler);
+
+bool oc_do_get(const char *uri, oc_server_handle_t *server, const char *query,
+               oc_response_handler_t handler, oc_qos_t qos);
+
+bool oc_do_delete(const char *uri, oc_server_handle_t *server,
+                  oc_response_handler_t handler, oc_qos_t qos);
+
+bool oc_init_put(const char *uri, oc_server_handle_t *server, const char *query,
+                 oc_response_handler_t handler, oc_qos_t qos);
+
+bool oc_do_put(void);
+
+bool oc_init_post(const char *uri, oc_server_handle_t *server,
+                  const char *query, oc_response_handler_t handler,
+                  oc_qos_t qos);
+
+bool oc_do_post(void);
+
+bool oc_do_observe(const char *uri, oc_server_handle_t *server,
+                   const char *query, oc_response_handler_t handler,
+                   oc_qos_t qos);
+
+bool oc_stop_observe(const char *uri, oc_server_handle_t *server);
+
+/** Common operations */
+
+void oc_set_delayed_callback(void *cb_data, oc_trigger_t callback,
+                             uint16_t seconds);
+void oc_remove_delayed_callback(void *cb_data, oc_trigger_t callback);
+
+/** API for setting handlers for interrupts */
+
+#define oc_signal_interrupt_handler(name)                                      \
+  do {                                                                         \
+    oc_process_poll(&(name##_interrupt_x));                                    \
+    oc_signal_main_loop();                                                     \
+  } while (0)
+
+#define oc_activate_interrupt_handler(name)                                    \
+  (oc_process_start(&(name##_interrupt_x), 0))
+
+#define oc_define_interrupt_handler(name)                                      \
+  void name##_interrupt_x_handler(void);                                       \
+  OC_PROCESS(name##_interrupt_x, "");                                          \
+  OC_PROCESS_THREAD(name##_interrupt_x, ev, data)                              \
+  {                                                                            \
+    OC_PROCESS_POLLHANDLER(name##_interrupt_x_handler());                      \
+    OC_PROCESS_BEGIN();                                                        \
+    while (oc_process_is_running(&(name##_interrupt_x))) {                     \
+      OC_PROCESS_YIELD();                                                      \
+    }                                                                          \
+    OC_PROCESS_END();                                                          \
+  }                                                                            \
+  void name##_interrupt_x_handler(void)
+
+#endif /* OC_API_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_buffer.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_buffer.h b/libs/iotivity/include/iotivity/oc_buffer.h
new file mode 100644
index 0000000..55373e6
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_buffer.h
@@ -0,0 +1,32 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_BUFFER_H
+#define OC_BUFFER_H
+
+#include "port/oc_connectivity.h"
+#include "util/oc_process.h"
+#include <stdbool.h>
+
+OC_PROCESS_NAME(message_buffer_handler);
+oc_message_t *oc_allocate_message(void);
+void oc_message_add_ref(oc_message_t *message);
+void oc_message_unref(oc_message_t *message);
+
+void oc_recv_message(oc_message_t *message);
+void oc_send_message(oc_message_t *message);
+
+#endif /* OC_BUFFER_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_client_state.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_client_state.h b/libs/iotivity/include/iotivity/oc_client_state.h
new file mode 100644
index 0000000..7049c32
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_client_state.h
@@ -0,0 +1,88 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_CLIENT_STATE_H
+#define OC_CLIENT_STATE_H
+
+#include "messaging/coap/constants.h"
+#include "oc_ri.h"
+#include <stdbool.h>
+
+typedef enum { HIGH_QOS = 0, LOW_QOS } oc_qos_t;
+
+typedef struct
+{
+  oc_rep_t *payload;
+  oc_status_t code;
+  int observe_option;
+} oc_client_response_t;
+
+typedef struct
+{
+  oc_endpoint_t endpoint;
+} oc_server_handle_t;
+
+typedef enum {
+  OC_STOP_DISCOVERY = 0,
+  OC_CONTINUE_DISCOVERY
+} oc_discovery_flags_t;
+
+typedef oc_discovery_flags_t(oc_discovery_cb_t)(const char *, const char *,
+                                                oc_string_array_t,
+                                                oc_interface_mask_t,
+                                                oc_server_handle_t *);
+
+typedef void (*oc_response_handler_t)(oc_client_response_t *);
+
+typedef struct oc_client_cb_s
+{
+  struct oc_client_cb_s *next;
+  oc_string_t uri;
+  uint8_t token[COAP_TOKEN_LEN];
+  uint8_t token_len;
+  uint16_t mid;
+
+  oc_server_handle_t server;
+
+  void *handler;
+
+  bool discovery;
+  int32_t observe_seq;
+  oc_clock_time_t timestamp;
+  oc_qos_t qos;
+  oc_method_t method;
+} oc_client_cb_t;
+
+bool oc_ri_invoke_client_cb(void *response, oc_endpoint_t *endpoint);
+
+oc_client_cb_t *oc_ri_alloc_client_cb(const char *uri,
+                                      oc_server_handle_t *server,
+                                      oc_method_t method, void *handler,
+                                      oc_qos_t qos);
+
+oc_client_cb_t *oc_ri_get_client_cb(const char *uri, oc_server_handle_t *server,
+                                    oc_method_t method);
+
+void oc_ri_remove_client_cb_by_mid(uint16_t mid);
+
+oc_discovery_flags_t oc_ri_process_discovery_payload(uint8_t *payload, int len,
+                                                     oc_discovery_cb_t *handler,
+                                                     oc_endpoint_t *endpoint);
+
+bool oc_ri_send_rst(oc_endpoint_t *endpoint, uint8_t *token, uint8_t token_len,
+                    uint16_t mid);
+
+#endif /* OC_CLIENT_STATE_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_constants.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_constants.h b/libs/iotivity/include/iotivity/oc_constants.h
new file mode 100644
index 0000000..0413ddc
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_constants.h
@@ -0,0 +1,43 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_CONSTANTS_H
+#define OC_CONSTANTS_H
+
+/* OCF standard resource interfaces */
+#define OC_NUM_STD_INTERFACES (7)
+#define OC_RSRVD_IF_BASELINE "oic.if.baseline"
+#define OC_BASELINE_IF_LEN (15)
+#define OC_RSRVD_IF_LL "oic.if.ll"
+#define OC_LL_IF_LEN (9)
+#define OC_RSRVD_IF_B "oic.if.b"
+#define OC_B_IF_LEN (8)
+#define OC_RSRVD_IF_R "oic.if.r"
+#define OC_R_IF_LEN (8)
+#define OC_RSRVD_IF_RW "oic.if.rw"
+#define OC_RW_IF_LEN (9)
+#define OC_RSRVD_IF_A "oic.if.a"
+#define OC_A_IF_LEN (8)
+#define OC_RSRVD_IF_S "oic.if.s"
+#define OC_S_IF_LEN (8)
+
+/* OCF Core resource URIs */
+#define OC_RSRVD_WELL_KNOWN_URI "/oic/res"
+#define OC_MULTICAST_DISCOVERY_URI "/oic/res"
+#define OC_RSRVD_DEVICE_URI "/oic/d"
+#define OC_RSRVD_PLATFORM_URI "/oic/p"
+
+#endif /* OC_CONSTANTS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_core_res.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_core_res.h b/libs/iotivity/include/iotivity/oc_core_res.h
new file mode 100644
index 0000000..69e5879
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_core_res.h
@@ -0,0 +1,52 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_CORE_RES_H
+#define OC_CORE_RES_H
+
+#include "oc_ri.h"
+
+typedef void (*oc_core_init_platform_cb_t)(void *data);
+typedef void (*oc_core_add_device_cb_t)(void *data);
+
+oc_string_t *oc_core_init_platform(const char *mfg_name,
+                                   oc_core_init_platform_cb_t init_cb,
+                                   void *data);
+
+oc_string_t *oc_core_add_new_device(const char *uri, const char *rt,
+                                    const char *name, const char *spec_version,
+                                    const char *data_model_version,
+                                    oc_core_add_device_cb_t add_device_cb,
+                                    void *data);
+
+int oc_core_get_num_devices(void);
+
+oc_uuid_t *oc_core_get_device_id(int device);
+
+void oc_core_encode_interfaces_mask(CborEncoder *parent,
+                                    oc_interface_mask_t interface);
+
+oc_resource_t *oc_core_get_resource_by_index(int type);
+
+oc_resource_t *oc_core_get_resource_by_uri(const char *uri);
+
+void oc_core_populate_resource(
+  int type, const char *uri, const char *rt, oc_interface_mask_t interfaces,
+  oc_interface_mask_t default_interface, oc_resource_properties_t properties,
+  oc_request_handler_t get, oc_request_handler_t put, oc_request_handler_t post,
+  oc_request_handler_t delete, int device);
+
+#endif /* OC_CORE_RES_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_discovery.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_discovery.h b/libs/iotivity/include/iotivity/oc_discovery.h
new file mode 100644
index 0000000..6fd3f29
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_discovery.h
@@ -0,0 +1,22 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_DISCOVERY_H
+#define OC_DISCOVERY_H
+
+void oc_create_discovery_resource(void);
+
+#endif /* OC_DISCOVERY_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_helpers.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_helpers.h b/libs/iotivity/include/iotivity/oc_helpers.h
new file mode 100644
index 0000000..4a8cd1e
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_helpers.h
@@ -0,0 +1,78 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_HELPERS_H
+#define OC_HELPERS_H
+
+#include "util/oc_list.h"
+#include "util/oc_mmem.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct oc_mmem oc_handle_t, oc_string_t, oc_array_t, oc_string_array_t;
+
+#define oc_cast(block, type) ((type *)(OC_MMEM_PTR(&(block))))
+#define oc_string(ocstring) (oc_cast(ocstring, char))
+
+void oc_new_string(oc_string_t *ocstring, const char str[]);
+void oc_alloc_string(oc_string_t *ocstring, int size);
+void oc_free_string(oc_string_t *ocstring);
+void oc_concat_strings(oc_string_t *concat, const char *str1, const char *str2);
+#define oc_string_len(ocstring) ((ocstring).size ? (ocstring).size - 1 : 0)
+
+void _oc_new_array(oc_array_t *ocarray, uint8_t size, pool type);
+void _oc_free_array(oc_array_t *ocarray, pool type);
+#define oc_new_int_array(ocarray, size) (_oc_new_array(ocarray, size, INT_POOL))
+#define oc_new_bool_array(ocarray, size)                                       \
+  (_oc_new_array(ocarray, size, BYTE_POOL))
+#define oc_new_double_array(ocarray, size)                                     \
+  (_oc_new_array(ocarray, size, DOUBLE_POOL))
+#define oc_free_int_array(ocarray) (_oc_free_array(ocarray, INT_POOL))
+#define oc_free_bool_array(ocarray) (_oc_free_array(ocarray, BYTE_POOL))
+#define oc_free_double_array(ocarray) (_oc_free_array(ocarray, DOUBLE_POOL))
+#define oc_int_array_size(ocintarray) ((ocintarray).size / sizeof(int64_t))
+#define oc_bool_array_size(ocboolarray) ((ocboolarray).size / sizeof(bool))
+#define oc_double_array_size(ocdoublearray)                                    \
+  ((ocdoublearray).size / sizeof(double))
+#define oc_int_array(ocintarray) (oc_cast(ocintarray, int64_t))
+#define oc_bool_array(ocboolarray) (oc_cast(ocboolarray, bool))
+#define oc_double_array(ocdoublearray) (oc_cast(ocdoublearray, double))
+
+#define STRING_ARRAY_ITEM_MAX_LEN 24
+void _oc_alloc_string_array(oc_string_array_t *ocstringarray, uint8_t size);
+bool _oc_copy_string_to_string_array(oc_string_array_t *ocstringarray,
+                                     const char str[], uint8_t index);
+bool _oc_string_array_add_item(oc_string_array_t *ocstringarray,
+                               const char str[]);
+void oc_join_string_array(oc_string_array_t *ocstringarray,
+                          oc_string_t *ocstring);
+#define oc_new_string_array(ocstringarray, size)                               \
+  (_oc_alloc_string_array(ocstringarray, size))
+#define oc_free_string_array(ocstringarray) (oc_free_string(ocstringarray))
+#define oc_string_array_add_item(ocstringarray, str)                           \
+  (_oc_string_array_add_item(&(ocstringarray), str))
+#define oc_string_array_get_item(ocstringarray, index)                         \
+  (oc_string(ocstringarray) + index * STRING_ARRAY_ITEM_MAX_LEN)
+#define oc_string_array_set_item(ocstringarray, str, index)                    \
+  (_oc_copy_string_to_string_array(&(ocstringarray), str, index))
+#define oc_string_array_get_item_size(ocstringarray, index)                    \
+  (strlen((const char *)oc_string_array_get_item(ocstringarray, index)))
+#define oc_string_array_get_allocated_size(ocstringarray)                      \
+  ((ocstringarray).size / STRING_ARRAY_ITEM_MAX_LEN)
+
+#endif /* OC_HELPERS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_network_events.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_network_events.h b/libs/iotivity/include/iotivity/oc_network_events.h
new file mode 100644
index 0000000..a678666
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_network_events.h
@@ -0,0 +1,29 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_NETWORK_EVENTS_H
+#define OC_NETWORK_EVENTS_H
+
+#include "port/oc_network_events_mutex.h"
+#include "util/oc_process.h"
+
+OC_PROCESS_NAME(oc_network_events);
+
+typedef struct oc_message_s oc_message_t;
+
+void oc_network_event(oc_message_t *message);
+
+#endif /* OC_NETWORK_EVENTS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_rep.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_rep.h b/libs/iotivity/include/iotivity/oc_rep.h
new file mode 100644
index 0000000..b7a88be
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_rep.h
@@ -0,0 +1,228 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_REP_H
+#define OC_REP_H
+
+#include <tinycbor/cbor.h>
+#include "oc_constants.h"
+#include "oc_helpers.h"
+#include <config.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+extern CborEncoder g_encoder, root_map, links_array;
+extern CborError g_err;
+
+void oc_rep_new(uint8_t *payload, int size);
+void oc_rep_reset(void);
+int oc_rep_finalize(void);
+
+#define oc_rep_object(name) &name##_map
+#define oc_rep_array(name) &name##_array
+
+#define oc_rep_set_double(object, key, value)                                  \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_double(&object##_map, value);                         \
+  } while (0)
+
+#define oc_rep_set_int(object, key, value)                                     \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_int(&object##_map, value);                            \
+  } while (0)
+
+#define oc_rep_set_uint(object, key, value)                                    \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_uint(&object##_map, value);                           \
+  } while (0)
+
+#define oc_rep_set_boolean(object, key, value)                                 \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_boolean(&object##_map, value);                        \
+  } while (0)
+
+#define oc_rep_set_text_string(object, key, value)                             \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_text_string(&object##_map, value, strlen(value));     \
+  } while (0)
+
+#define oc_rep_set_byte_string(object, key, value)                             \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    g_err |= cbor_encode_byte_string(&object##_map, value, strlen(value));     \
+  } while (0)
+
+#define oc_rep_start_array(parent, key)                                        \
+  do {                                                                         \
+    CborEncoder key##_array;                                                   \
+  g_err |=                                                                     \
+    cbor_encoder_create_array(&parent, &key##_array, CborIndefiniteLength)
+
+#define oc_rep_end_array(parent, key)                                          \
+  g_err |= cbor_encoder_close_container(&parent, &key##_array);                \
+  }                                                                            \
+  while (0)
+
+#define oc_rep_start_links_array()                                             \
+  g_err |=                                                                     \
+    cbor_encoder_create_array(&g_encoder, &links_array, CborIndefiniteLength)
+
+#define oc_rep_end_links_array()                                               \
+  g_err |= cbor_encoder_close_container(&g_encoder, &links_array)
+
+#define oc_rep_start_root_object()                                             \
+  g_err |= cbor_encoder_create_map(&g_encoder, &root_map, CborIndefiniteLength)
+
+#define oc_rep_end_root_object()                                               \
+  g_err |= cbor_encoder_close_container(&g_encoder, &root_map)
+
+#define oc_rep_add_byte_string(parent, value)                                  \
+  g_err |= cbor_encode_byte_string(&parent##_array, value, strlen(value))
+
+#define oc_rep_add_text_string(parent, value)                                  \
+  g_err |= cbor_encode_text_string(&parent##_array, value, strlen(value))
+
+#define oc_rep_set_key(parent, key)                                            \
+  g_err |= cbor_encode_text_string(&parent, key, strlen(key))
+
+#define oc_rep_set_array(object, key)                                          \
+  g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));         \
+  oc_rep_start_array(object##_map, key)
+
+#define oc_rep_close_array(object, key) oc_rep_end_array(object##_map, key)
+
+#define oc_rep_start_object(parent, key)                                       \
+  do {                                                                         \
+    CborEncoder key##_map;                                                     \
+  g_err |= cbor_encoder_create_map(&parent, &key##_map, CborIndefiniteLength)
+
+#define oc_rep_end_object(parent, key)                                         \
+  g_err |= cbor_encoder_close_container(&parent, &key##_map);                  \
+  }                                                                            \
+  while (0)
+
+#define oc_rep_object_array_start_item(key)                                    \
+  oc_rep_start_object(key##_array, key)
+
+#define oc_rep_object_array_end_item(key) oc_rep_end_object(key##_array, key)
+
+#define oc_rep_set_object(object, key)                                         \
+  g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));         \
+  oc_rep_start_object(object##_map, key)
+
+#define oc_rep_close_object(object, key) oc_rep_end_object(object##_map, key)
+
+#define oc_rep_set_int_array(object, key, values, length)                      \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    CborEncoder key##_value_array;                                             \
+    g_err |=                                                                   \
+      cbor_encoder_create_array(&object##_map, &key##_value_array, length);    \
+    int i;                                                                     \
+    for (i = 0; i < length; i++) {                                             \
+      g_err |= cbor_encode_int(&key##_value_array, values[i]);                 \
+    }                                                                          \
+    g_err |= cbor_encoder_close_container(&object##_map, &key##_value_array);  \
+  } while (0)
+
+#define oc_rep_set_bool_array(object, key, values, length)                     \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    CborEncoder key##_value_array;                                             \
+    g_err |=                                                                   \
+      cbor_encoder_create_array(&object##_map, &key##_value_array, length);    \
+    int i;                                                                     \
+    for (i = 0; i < length; i++) {                                             \
+      g_err |= cbor_encode_boolean(&key##_value_array, values[i]);             \
+    }                                                                          \
+    g_err |= cbor_encoder_close_container(&object##_map, &key##_value_array);  \
+  } while (0)
+
+#define oc_rep_set_double_array(object, key, values, length)                   \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    CborEncoder key##_value_array;                                             \
+    g_err |=                                                                   \
+      cbor_encoder_create_array(&object##_map, &key##_value_array, length);    \
+    int i;                                                                     \
+    for (i = 0; i < length; i++) {                                             \
+      g_err |= cbor_encode_floating_point(&key##_value_array, CborDoubleType,  \
+                                          &values[i]);                         \
+    }                                                                          \
+    g_err |= cbor_encoder_close_container(&object##_map, &key##_value_array);  \
+  } while (0)
+
+#define oc_rep_set_string_array(object, key, values)                           \
+  do {                                                                         \
+    g_err |= cbor_encode_text_string(&object##_map, #key, strlen(#key));       \
+    CborEncoder key##_value_array;                                             \
+    g_err |=                                                                   \
+      cbor_encoder_create_array(&object##_map, &key##_value_array,             \
+                                oc_string_array_get_allocated_size(values));   \
+    int i;                                                                     \
+    for (i = 0; i < oc_string_array_get_allocated_size(values); i++) {         \
+      g_err |= cbor_encode_text_string(                                        \
+        &key##_value_array, oc_string_array_get_item(values, i),               \
+        oc_string_array_get_item_size(values, i));                             \
+    }                                                                          \
+    g_err |= cbor_encoder_close_container(&object##_map, &key##_value_array);  \
+  } while (0)
+
+typedef enum {
+  NIL = 0,
+  INT = 0x01,
+  DOUBLE = 0x02,
+  BOOL = 0x03,
+  BYTE_STRING = 0x04,
+  STRING = 0x05,
+  OBJECT = 0x06,
+  ARRAY = 0x08,
+  INT_ARRAY = 0x09,
+  DOUBLE_ARRAY = 0x0A,
+  BOOL_ARRAY = 0x0B,
+  BYTE_STRING_ARRAY = 0x0C,
+  STRING_ARRAY = 0x0D,
+  OBJECT_ARRAY = 0x0E
+} oc_rep_value_type_t;
+
+typedef struct oc_rep_s
+{
+  oc_rep_value_type_t type;
+  struct oc_rep_s *next;
+  oc_string_t name;
+  union
+  {
+    int64_t value_int;
+    bool value_boolean;
+    double value_double;
+    oc_string_t value_string;
+    oc_array_t value_array;
+    struct oc_rep_s *value_object;
+    struct oc_rep_s *value_object_array;
+  };
+} oc_rep_t;
+
+uint16_t oc_parse_rep(const uint8_t *payload, uint16_t payload_size,
+                      oc_rep_t **value_list);
+
+void oc_free_rep(oc_rep_t *rep);
+
+#endif /* OC_REP_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_ri.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_ri.h b/libs/iotivity/include/iotivity/oc_ri.h
new file mode 100644
index 0000000..5e96656
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_ri.h
@@ -0,0 +1,176 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_RI_H
+#define OC_RI_H
+
+#include "config.h"
+#include "oc_rep.h"
+#include "oc_uuid.h"
+#include "port/oc_connectivity.h"
+#include "util/oc_etimer.h"
+
+typedef enum { OC_GET = 1, OC_POST, OC_PUT, OC_DELETE } oc_method_t;
+
+typedef enum {
+  OC_DISCOVERABLE = (1 << 0),
+  OC_OBSERVABLE = (1 << 1),
+  OC_ACTIVE = (1 << 2),
+  OC_SECURE = (1 << 4),
+  OC_PERIODIC = (1 << 6),
+} oc_resource_properties_t;
+
+typedef enum {
+  OC_STATUS_OK = 0,
+  OC_STATUS_CREATED,
+  OC_STATUS_CHANGED,
+  OC_STATUS_DELETED,
+  OC_STATUS_NOT_MODIFIED,
+  OC_STATUS_BAD_REQUEST,
+  OC_STATUS_UNAUTHORIZED,
+  OC_STATUS_BAD_OPTION,
+  OC_STATUS_FORBIDDEN,
+  OC_STATUS_NOT_FOUND,
+  OC_STATUS_METHOD_NOT_ALLOWED,
+  OC_STATUS_NOT_ACCEPTABLE,
+  OC_STATUS_REQUEST_ENTITY_TOO_LARGE,
+  OC_STATUS_UNSUPPORTED_MEDIA_TYPE,
+  OC_STATUS_INTERNAL_SERVER_ERROR,
+  OC_STATUS_NOT_IMPLEMENTED,
+  OC_STATUS_BAD_GATEWAY,
+  OC_STATUS_SERVICE_UNAVAILABLE,
+  OC_STATUS_GATEWAY_TIMEOUT,
+  OC_STATUS_PROXYING_NOT_SUPPORTED,
+  __NUM_OC_STATUS_CODES__,
+  OC_IGNORE
+} oc_status_t;
+
+typedef struct oc_separate_response_s oc_separate_response_t;
+
+typedef struct oc_response_buffer_s oc_response_buffer_t;
+
+typedef struct
+{
+  oc_separate_response_t *separate_response;
+  oc_response_buffer_t *response_buffer;
+} oc_response_t;
+
+typedef enum {
+  OC_IF_BASELINE = 1 << 1,
+  OC_IF_LL = 1 << 2,
+  OC_IF_B = 1 << 3,
+  OC_IF_R = 1 << 4,
+  OC_IF_RW = 1 << 5,
+  OC_IF_A = 1 << 6,
+  OC_IF_S = 1 << 7,
+} oc_interface_mask_t;
+
+typedef enum {
+  OCF_RES = 0,
+  OCF_P,
+#ifdef OC_SECURITY
+  OCF_SEC_DOXM,
+  OCF_SEC_PSTAT,
+  OCF_SEC_ACL,
+  OCF_SEC_CRED,
+#endif
+  __NUM_OC_CORE_RESOURCES__
+} oc_core_resource_t;
+
+#define NUM_OC_CORE_RESOURCES (__NUM_OC_CORE_RESOURCES__ + MAX_NUM_DEVICES)
+
+typedef struct oc_resource_s oc_resource_t;
+
+typedef struct
+{
+  oc_endpoint_t *origin;
+  oc_resource_t *resource;
+  const char *query;
+  int query_len;
+  oc_rep_t *request_payload;
+  oc_response_t *response;
+} oc_request_t;
+
+typedef void (*oc_request_handler_t)(oc_request_t *, oc_interface_mask_t);
+
+typedef struct oc_resource_s
+{
+  struct oc_resource_s *next;
+  int device;
+  oc_string_t uri;
+  oc_string_array_t types;
+  oc_interface_mask_t interfaces;
+  oc_interface_mask_t default_interface;
+  oc_resource_properties_t properties;
+  oc_request_handler_t get_handler;
+  oc_request_handler_t put_handler;
+  oc_request_handler_t post_handler;
+  oc_request_handler_t delete_handler;
+  uint16_t observe_period_seconds;
+  uint8_t num_observers;
+} oc_resource_t;
+
+typedef enum { DONE = 0, CONTINUE } oc_event_callback_retval_t;
+
+typedef oc_event_callback_retval_t (*oc_trigger_t)(void *);
+
+typedef struct oc_event_callback_s
+{
+  struct oc_event_callback_s *next;
+  struct oc_etimer timer;
+  oc_trigger_t callback;
+  void *data;
+} oc_event_callback_t;
+
+void oc_ri_init(void);
+
+void oc_ri_shutdown(void);
+
+void oc_ri_add_timed_event_callback_ticks(void *cb_data,
+                                          oc_trigger_t event_callback,
+                                          oc_clock_time_t ticks);
+
+#define oc_ri_add_timed_event_callback_seconds(cb_data, event_callback,        \
+                                               seconds)                        \
+  do {                                                                         \
+    oc_ri_add_timed_event_callback_ticks(                                      \
+      cb_data, event_callback, (oc_clock_time_t)(seconds * OC_CLOCK_SECOND));  \
+  } while (0)
+
+void oc_ri_remove_timed_event_callback(void *cb_data,
+                                       oc_trigger_t event_callback);
+
+int oc_status_code(oc_status_t key);
+
+oc_resource_t *oc_ri_get_app_resource_by_uri(const char *uri);
+
+oc_resource_t *oc_ri_get_app_resources(void);
+
+#ifdef OC_SERVER
+oc_resource_t *oc_ri_alloc_resource(void);
+bool oc_ri_add_resource(oc_resource_t *resource);
+void oc_ri_delete_resource(oc_resource_t *resource);
+#endif
+
+int oc_ri_get_query_nth_key_value(const char *query, int query_len, char **key,
+                                  int *key_len, char **value, int *value_len,
+                                  int n);
+int oc_ri_get_query_value(const char *query, int query_len, const char *key,
+                          char **value);
+
+oc_interface_mask_t oc_ri_get_interface_mask(char *iface, int if_len);
+
+#endif /* OC_RI_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/include/iotivity/oc_uuid.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/include/iotivity/oc_uuid.h b/libs/iotivity/include/iotivity/oc_uuid.h
new file mode 100644
index 0000000..b1e5b26
--- /dev/null
+++ b/libs/iotivity/include/iotivity/oc_uuid.h
@@ -0,0 +1,31 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 OC_UUID_H
+#define OC_UUID_H
+
+#include <stdint.h>
+
+typedef struct
+{
+  uint8_t id[16];
+} oc_uuid_t;
+
+void oc_str_to_uuid(const char *str, oc_uuid_t *uuid);
+void oc_uuid_to_str(const oc_uuid_t *uuid, char *buffer, int buflen);
+void oc_gen_uuid(oc_uuid_t *uuid);
+
+#endif /* OC_UUID_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/iotivity/pkg.yml b/libs/iotivity/pkg.yml
new file mode 100644
index 0000000..f8f9f03
--- /dev/null
+++ b/libs/iotivity/pkg.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.
+#
+
+pkg.name: libs/iotivity
+pkg.description: OCF contstrained iotivity stack
+pkg.author: "https://github.com/iotivity/iotivity-constrained"
+pkg.homepage: "https://www.iotivity.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/libs/tinycbor"
+    - "@apache-mynewt-core/libs/os"
+
+pkg.cflags: -DDEBUG=1
+        -DSECURE=0
+        -I./port/mynewt
+        -I../port/mynewt
+        -I../../port/mynewt
+        -I../include/iotivity
+        -I../../include/iotivity
+        -I../../../include/iotivity
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_buffer.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_buffer.c b/libs/iotivity/src/api/oc_buffer.c
new file mode 100644
index 0000000..e623221
--- /dev/null
+++ b/libs/iotivity/src/api/oc_buffer.c
@@ -0,0 +1,138 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "messaging/coap/engine.h"
+#include "port/oc_signal_main_loop.h"
+#include "util/oc_memb.h"
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef OC_SECURITY
+#include "security/oc_dtls.h"
+#endif
+
+#include "config.h"
+#include "oc_buffer.h"
+#include "oc_events.h"
+
+OC_PROCESS(message_buffer_handler, "OC Message Buffer Handler");
+OC_MEMB(oc_buffers_s, oc_message_t, (MAX_NUM_CONCURRENT_REQUESTS * 2));
+
+oc_message_t *
+oc_allocate_message(void)
+{
+  oc_message_t *message = (oc_message_t *)oc_memb_alloc(&oc_buffers_s);
+  if (message) {
+    message->length = 0;
+    message->next = 0;
+    message->ref_count = 1;
+    LOG("buffer: Allocated TX/RX buffer; num free: %d\n",
+        oc_memb_numfree(&oc_buffers_s));
+  } else
+    LOG("buffer: No free TX/RX buffers!\n");
+  return message;
+}
+
+void
+oc_message_add_ref(oc_message_t *message)
+{
+  if (message)
+    message->ref_count++;
+}
+
+void
+oc_message_unref(oc_message_t *message)
+{
+  if (message) {
+    message->ref_count--;
+    if (message->ref_count == 0) {
+      oc_memb_free(&oc_buffers_s, message);
+      LOG("buffer: freed TX/RX buffer; num free: %d\n",
+          oc_memb_numfree(&oc_buffers_s));
+    }
+  }
+}
+
+void
+oc_recv_message(oc_message_t *message)
+{
+  oc_process_post(&message_buffer_handler, oc_events[INBOUND_NETWORK_EVENT],
+                  message);
+}
+
+void
+oc_send_message(oc_message_t *message)
+{
+  oc_process_post(&message_buffer_handler, oc_events[OUTBOUND_NETWORK_EVENT],
+                  message);
+
+  oc_signal_main_loop();
+}
+
+OC_PROCESS_THREAD(message_buffer_handler, ev, data)
+{
+  OC_PROCESS_BEGIN();
+  LOG("Started buffer handler process\n");
+  while (1) {
+    OC_PROCESS_YIELD();
+
+    if (ev == oc_events[INBOUND_NETWORK_EVENT]) {
+#ifdef OC_SECURITY
+      uint8_t b = (uint8_t)((oc_message_t *)data)->data[0];
+      if (b > 19 && b < 64) {
+        LOG("Inbound network event: encrypted request\n");
+        oc_process_post(&oc_dtls_handler, oc_events[UDP_TO_DTLS_EVENT], data);
+      } else {
+        LOG("Inbound network event: decrypted request\n");
+        oc_process_post(&coap_engine, oc_events[INBOUND_RI_EVENT], data);
+      }
+#else
+      LOG("Inbound network event: decrypted request\n");
+      oc_process_post(&coap_engine, oc_events[INBOUND_RI_EVENT], data);
+#endif
+    } else if (ev == oc_events[OUTBOUND_NETWORK_EVENT]) {
+      oc_message_t *message = (oc_message_t *)data;
+
+#ifdef OC_CLIENT
+      if (message->endpoint.flags & MULTICAST) {
+        LOG("Outbound network event: multicast request\n");
+        oc_send_multicast_message(message);
+        oc_message_unref(message);
+      } else
+#endif
+#ifdef OC_SECURITY
+        if (message->endpoint.flags & SECURED) {
+        LOG("Outbound network event: forwarding to DTLS\n");
+
+        if (!oc_sec_dtls_connected(&message->endpoint)) {
+          LOG("Posting INIT_DTLS_CONN_EVENT\n");
+          oc_process_post(&oc_dtls_handler, oc_events[INIT_DTLS_CONN_EVENT],
+                          data);
+        } else {
+          LOG("Posting RI_TO_DTLS_EVENT\n");
+          oc_process_post(&oc_dtls_handler, oc_events[RI_TO_DTLS_EVENT], data);
+        }
+      } else
+#endif
+      {
+        LOG("Outbound network event: unicast message\n");
+        oc_send_buffer(message);
+        oc_message_unref(message);
+      }
+    }
+  }
+  OC_PROCESS_END();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_client_api.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_client_api.c b/libs/iotivity/src/api/oc_client_api.c
new file mode 100644
index 0000000..bd73da3
--- /dev/null
+++ b/libs/iotivity/src/api/oc_client_api.c
@@ -0,0 +1,287 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "messaging/coap/coap.h"
+#include "messaging/coap/transactions.h"
+#include "oc_api.h"
+
+#ifdef OC_CLIENT
+#define OC_CLIENT_CB_TIMEOUT_SECS COAP_RESPONSE_TIMEOUT
+
+static oc_message_t *message;
+static coap_transaction_t *transaction;
+coap_packet_t request[1];
+
+static bool
+dispatch_coap_request(void)
+{
+  int response_length = oc_rep_finalize();
+  if (!transaction) {
+    if (message) {
+      if (response_length) {
+        coap_set_payload(request, message->data + COAP_MAX_HEADER_SIZE,
+                         response_length);
+        coap_set_header_content_format(request, APPLICATION_CBOR);
+      }
+      message->length = coap_serialize_message(request, message->data);
+      coap_send_message(message);
+      message = 0;
+      return true;
+    }
+  } else {
+    if (response_length) {
+      coap_set_payload(request,
+                       transaction->message->data + COAP_MAX_HEADER_SIZE,
+                       response_length);
+      coap_set_header_content_format(request, APPLICATION_CBOR);
+    }
+    transaction->message->length =
+      coap_serialize_message(request, transaction->message->data);
+    coap_send_transaction(transaction);
+    transaction = 0;
+    return true;
+  }
+  return false;
+}
+
+static bool
+prepare_coap_request(oc_client_cb_t *cb, oc_string_t *query)
+{
+  coap_message_type_t type = COAP_TYPE_NON;
+
+  if (cb->qos == HIGH_QOS) {
+    type = COAP_TYPE_CON;
+    transaction = coap_new_transaction(cb->mid, &cb->server.endpoint);
+    if (!transaction)
+      return false;
+    oc_rep_new(transaction->message->data + COAP_MAX_HEADER_SIZE,
+               COAP_MAX_BLOCK_SIZE);
+  } else {
+    message = oc_allocate_message();
+    if (!message)
+      return false;
+    memcpy(&message->endpoint, &cb->server.endpoint, sizeof(oc_endpoint_t));
+    oc_rep_new(message->data + COAP_MAX_HEADER_SIZE, COAP_MAX_BLOCK_SIZE);
+  }
+
+  coap_init_message(request, type, cb->method, cb->mid);
+
+  coap_set_header_accept(request, APPLICATION_CBOR);
+
+  coap_set_token(request, cb->token, cb->token_len);
+
+  coap_set_header_uri_path(request, oc_string(cb->uri));
+
+  if (cb->observe_seq != -1)
+    coap_set_header_observe(request, cb->observe_seq);
+
+  if (query && oc_string_len(*query))
+    coap_set_header_uri_query(request, oc_string(*query));
+
+  if (cb->observe_seq == -1 && cb->qos == LOW_QOS) {
+    extern oc_event_callback_retval_t oc_ri_remove_client_cb(void *data);
+
+    oc_set_delayed_callback(cb, &oc_ri_remove_client_cb,
+                            OC_CLIENT_CB_TIMEOUT_SECS);
+  }
+
+  return true;
+}
+
+bool
+oc_do_delete(const char *uri, oc_server_handle_t *server,
+             oc_response_handler_t handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb =
+    oc_ri_alloc_client_cb(uri, server, OC_DELETE, handler, qos);
+  if (!cb)
+    return false;
+
+  bool status = false;
+
+  status = prepare_coap_request(cb, NULL);
+
+  if (status)
+    status = dispatch_coap_request();
+
+  return status;
+}
+
+bool
+oc_do_get(const char *uri, oc_server_handle_t *server, const char *query,
+          oc_response_handler_t handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
+  if (!cb)
+    return false;
+
+  bool status = false;
+
+  if (query && strlen(query)) {
+    oc_string_t q;
+    oc_concat_strings(&q, "?", query);
+    status = prepare_coap_request(cb, &q);
+    oc_free_string(&q);
+  } else {
+    status = prepare_coap_request(cb, NULL);
+  }
+
+  if (status)
+    status = dispatch_coap_request();
+
+  return status;
+}
+
+bool
+oc_init_put(const char *uri, oc_server_handle_t *server, const char *query,
+            oc_response_handler_t handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_PUT, handler, qos);
+  if (!cb)
+    return false;
+
+  bool status = false;
+
+  if (query && strlen(query)) {
+    oc_string_t q;
+    oc_concat_strings(&q, "?", query);
+    status = prepare_coap_request(cb, &q);
+    oc_free_string(&q);
+  } else {
+    status = prepare_coap_request(cb, NULL);
+  }
+
+  return status;
+}
+
+bool
+oc_init_post(const char *uri, oc_server_handle_t *server, const char *query,
+             oc_response_handler_t handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb =
+    oc_ri_alloc_client_cb(uri, server, OC_POST, handler, qos);
+  if (!cb)
+    return false;
+
+  bool status = false;
+
+  if (query && strlen(query)) {
+    oc_string_t q;
+    oc_concat_strings(&q, "?", query);
+    status = prepare_coap_request(cb, &q);
+    oc_free_string(&q);
+  } else {
+    status = prepare_coap_request(cb, NULL);
+  }
+
+  return status;
+}
+
+bool
+oc_do_put(void)
+{
+  return dispatch_coap_request();
+}
+
+bool
+oc_do_post(void)
+{
+  return dispatch_coap_request();
+}
+
+bool
+oc_do_observe(const char *uri, oc_server_handle_t *server, const char *query,
+              oc_response_handler_t handler, oc_qos_t qos)
+{
+  oc_client_cb_t *cb = oc_ri_alloc_client_cb(uri, server, OC_GET, handler, qos);
+  if (!cb)
+    return false;
+
+  cb->observe_seq = 0;
+
+  bool status = false;
+
+  if (query && strlen(query)) {
+    oc_string_t q;
+    oc_concat_strings(&q, "?", query);
+    status = prepare_coap_request(cb, &q);
+    oc_free_string(&q);
+  } else {
+    status = prepare_coap_request(cb, NULL);
+  }
+
+  if (status)
+    status = dispatch_coap_request();
+
+  return status;
+}
+
+bool
+oc_stop_observe(const char *uri, oc_server_handle_t *server)
+{
+  oc_client_cb_t *cb = oc_ri_get_client_cb(uri, server, OC_GET);
+
+  if (!cb)
+    return false;
+
+  cb->observe_seq = 1;
+
+  bool status = false;
+
+  status = prepare_coap_request(cb, NULL);
+
+  if (status)
+    status = dispatch_coap_request();
+
+  return status;
+}
+
+bool
+oc_do_ip_discovery(const char *rt, oc_discovery_cb_t handler)
+{
+  oc_make_ip_endpoint(mcast, IP | MULTICAST, 5683, 0xff, 0x02, 0, 0, 0, 0, 0, 0,
+                      0, 0, 0, 0, 0, 0, 0, 0xfd);
+  mcast.ipv6_addr.scope = 0;
+
+  oc_server_handle_t handle;
+  memcpy(&handle.endpoint, &mcast, sizeof(oc_endpoint_t));
+
+  oc_client_cb_t *cb =
+    oc_ri_alloc_client_cb("/oic/res", &handle, OC_GET, handler, LOW_QOS);
+
+  if (!cb)
+    return false;
+
+  cb->discovery = true;
+
+  bool status = false;
+
+  oc_string_t query;
+
+  if (rt && strlen(rt) > 0) {
+    oc_concat_strings(&query, "if=oic.if.ll&rt=", rt);
+  } else {
+    oc_new_string(&query, "if=oic.if.ll");
+  }
+  status = prepare_coap_request(cb, &query);
+  oc_free_string(&query);
+
+  if (status)
+    status = dispatch_coap_request();
+
+  return status;
+}
+#endif /* OC_CLIENT */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_core_res.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_core_res.c b/libs/iotivity/src/api/oc_core_res.c
new file mode 100644
index 0000000..ced0f88
--- /dev/null
+++ b/libs/iotivity/src/api/oc_core_res.c
@@ -0,0 +1,280 @@
+/*
+ // Copyright (c) 2016 Intel Corporation
+ //
+ // Licensed 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 "oc_core_res.h"
+#include "messaging/coap/oc_coap.h"
+#include "oc_rep.h"
+#include "oc_ri.h"
+
+#ifdef OC_SECURITY
+#include "security/oc_pstat.h"
+#endif /* OC_SECURITY */
+
+static oc_resource_t core_resources[NUM_OC_CORE_RESOURCES];
+struct oc_device_info_t
+{
+  oc_uuid_t uuid;
+  oc_string_t payload;
+} oc_device_info[MAX_NUM_DEVICES];
+static int device_count;
+static oc_string_t oc_platform_payload;
+
+void
+oc_core_encode_interfaces_mask(CborEncoder *parent,
+                               oc_interface_mask_t interface)
+{
+  oc_rep_set_key((*parent), "if");
+  oc_rep_start_array((*parent), if);
+  if (interface & OC_IF_LL) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_LL);
+  }
+  if (interface & OC_IF_B) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_B);
+  }
+  if (interface & OC_IF_R) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_R);
+  }
+  if (interface & OC_IF_RW) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_RW);
+  }
+  if (interface & OC_IF_A) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_A);
+  }
+  if (interface & OC_IF_S) {
+    oc_rep_add_text_string(if, OC_RSRVD_IF_S);
+  }
+  oc_rep_add_text_string(if, OC_RSRVD_IF_BASELINE);
+  oc_rep_end_array((*parent), if);
+}
+
+static void
+oc_core_device_handler(oc_request_t *request, oc_interface_mask_t interface)
+{
+  uint8_t *buffer = request->response->response_buffer->buffer;
+  uint16_t buffer_size = request->response->response_buffer->buffer_size;
+  int payload_size = oc_device_info[request->resource->device].payload.size;
+
+  if (buffer_size < payload_size) {
+    request->response->response_buffer->response_length = 0;
+    request->response->response_buffer->code =
+      oc_status_code(OC_STATUS_INTERNAL_SERVER_ERROR);
+    return;
+  }
+
+  switch (interface) {
+  case OC_IF_R:
+  case OC_IF_BASELINE:
+    memcpy(buffer,
+           oc_cast(oc_device_info[request->resource->device].payload, uint8_t),
+           payload_size);
+    request->response->response_buffer->response_length = payload_size;
+    request->response->response_buffer->code = oc_status_code(OC_STATUS_OK);
+    break;
+  default:
+    break;
+  }
+}
+
+int
+oc_core_get_num_devices(void)
+{
+  return device_count;
+}
+
+static int
+finalize_payload(oc_string_t *temp_buffer, oc_string_t *payload)
+{
+  oc_rep_end_root_object();
+  int size = oc_rep_finalize();
+  if (size != -1) {
+    oc_alloc_string(payload, size);
+    memcpy(oc_cast(*payload, uint8_t), oc_cast(*temp_buffer, uint8_t), size);
+    oc_free_string(temp_buffer);
+    return 1;
+  }
+
+  oc_free_string(temp_buffer);
+  return -1;
+}
+
+oc_string_t *
+oc_core_add_new_device(const char *uri, const char *rt, const char *name,
+                       const char *spec_version, const char *data_model_version,
+                       oc_core_add_device_cb_t add_device_cb, void *data)
+{
+  if (device_count == MAX_NUM_DEVICES)
+    return false;
+
+  oc_string_t temp_buffer;
+/* Once provisioned, UUID is retrieved from the credential store.
+   If not yet provisioned, a default is generated in the security
+   layer.
+*/
+#ifdef OC_SECURITY /*fix if add new devices after provisioning, need to reset  \
+                      or it will generate non-standard uuid */
+  /* where are secondary device ids persisted? */
+  if (!oc_sec_provisioned() && device_count > 0)
+    oc_gen_uuid(&oc_device_info[device_count].uuid);
+#else
+  oc_gen_uuid(&oc_device_info[device_count].uuid);
+#endif
+
+  int ocf_d = NUM_OC_CORE_RESOURCES - 1 - device_count;
+
+  /* Construct device resource */
+  oc_core_populate_resource(ocf_d, uri, rt, OC_IF_R | OC_IF_BASELINE,
+                            OC_IF_BASELINE, OC_ACTIVE | OC_DISCOVERABLE,
+                            oc_core_device_handler, 0, 0, 0, device_count);
+
+  /* Encoding device resource payload */
+  oc_alloc_string(&temp_buffer, MAX_DEVICE_PAYLOAD_SIZE);
+  oc_rep_new(oc_cast(temp_buffer, uint8_t), MAX_DEVICE_PAYLOAD_SIZE);
+
+  oc_rep_start_root_object();
+
+  oc_rep_set_string_array(root, rt, core_resources[ocf_d].types);
+  oc_core_encode_interfaces_mask(oc_rep_object(root),
+                                 core_resources[ocf_d].interfaces);
+  oc_rep_set_uint(root, p, core_resources[ocf_d].properties);
+
+  char uuid[37];
+  oc_uuid_to_str(&oc_device_info[device_count].uuid, uuid, 37);
+  oc_rep_set_text_string(root, di, uuid);
+  oc_rep_set_text_string(root, n, name);
+  oc_rep_set_text_string(root, icv, spec_version);
+  oc_rep_set_text_string(root, dmv, data_model_version);
+
+  if (add_device_cb)
+    add_device_cb(data);
+  if (!finalize_payload(&temp_buffer, &oc_device_info[device_count].payload))
+    return NULL;
+
+  return &oc_device_info[device_count++].payload;
+}
+
+void
+oc_core_platform_handler(oc_request_t *request, oc_interface_mask_t interface)
+{
+  uint8_t *buffer = request->response->response_buffer->buffer;
+  uint16_t buffer_size = request->response->response_buffer->buffer_size;
+  int payload_size = oc_platform_payload.size;
+
+  if (buffer_size < payload_size) {
+    request->response->response_buffer->response_length = 0;
+    request->response->response_buffer->code =
+      oc_status_code(OC_STATUS_INTERNAL_SERVER_ERROR);
+    return;
+  }
+
+  switch (interface) {
+  case OC_IF_R:
+  case OC_IF_BASELINE:
+    memcpy(buffer, oc_cast(oc_platform_payload, uint8_t), payload_size);
+    request->response->response_buffer->response_length = payload_size;
+    request->response->response_buffer->code = oc_status_code(OC_STATUS_OK);
+    break;
+  default:
+    break;
+  }
+}
+
+oc_string_t *
+oc_core_init_platform(const char *mfg_name, oc_core_init_platform_cb_t init_cb,
+                      void *data)
+{
+  if (oc_platform_payload.size > 0)
+    return NULL;
+
+  oc_string_t temp_buffer;
+  /* Populating resource obuject */
+  oc_core_populate_resource(OCF_P, OC_RSRVD_PLATFORM_URI, "oic.wk.p",
+                            OC_IF_R | OC_IF_BASELINE, OC_IF_BASELINE,
+                            OC_ACTIVE | OC_DISCOVERABLE,
+                            oc_core_platform_handler, 0, 0, 0, 0);
+
+  /* Encoding platform resource payload */
+  oc_alloc_string(&temp_buffer, MAX_PLATFORM_PAYLOAD_SIZE);
+  oc_rep_new(oc_cast(temp_buffer, uint8_t), MAX_PLATFORM_PAYLOAD_SIZE);
+  oc_rep_start_root_object();
+  oc_rep_set_string_array(root, rt, core_resources[OCF_P].types);
+
+  oc_core_encode_interfaces_mask(oc_rep_object(root),
+                                 core_resources[OCF_P].interfaces);
+  oc_rep_set_uint(root, p, core_resources[OCF_P].properties & ~OC_PERIODIC);
+
+  oc_uuid_t uuid; /*fix uniqueness of platform id?? */
+  oc_gen_uuid(&uuid);
+  char uuid_str[37];
+
+  oc_uuid_to_str(&uuid, uuid_str, 37);
+  oc_rep_set_text_string(root, pi, uuid_str);
+  oc_rep_set_text_string(root, mnmn, mfg_name);
+
+  if (init_cb)
+    init_cb(data);
+
+  if (!finalize_payload(&temp_buffer, &oc_platform_payload))
+    return NULL;
+
+  return &oc_platform_payload;
+}
+
+void
+oc_core_populate_resource(int type, const char *uri, const char *rt,
+                          oc_interface_mask_t interfaces,
+                          oc_interface_mask_t default_interface,
+                          oc_resource_properties_t properties,
+                          oc_request_handler_t get, oc_request_handler_t put,
+                          oc_request_handler_t post,
+                          oc_request_handler_t delete, int device)
+{
+  oc_resource_t *r = &core_resources[type];
+  r->device = device;
+  oc_new_string(&r->uri, uri);
+  r->properties = properties;
+  oc_new_string_array(&r->types, 1);
+  oc_string_array_add_item(r->types, rt);
+  r->interfaces = interfaces;
+  r->default_interface = default_interface;
+  r->get_handler = get;
+  r->put_handler = put;
+  r->post_handler = post;
+  r->delete_handler = delete;
+}
+
+oc_uuid_t *
+oc_core_get_device_id(int device)
+{
+  return &oc_device_info[device].uuid;
+}
+
+oc_resource_t *
+oc_core_get_resource_by_index(int type)
+{
+  return &core_resources[type];
+}
+
+oc_resource_t *
+oc_core_get_resource_by_uri(const char *uri)
+{
+  int i;
+  for (i = 0; i < NUM_OC_CORE_RESOURCES; i++) {
+    if (oc_string_len(core_resources[i].uri) == strlen(uri) &&
+        strncmp(uri, oc_string(core_resources[i].uri), strlen(uri)) == 0)
+      return &core_resources[i];
+  }
+  return NULL;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_discovery.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_discovery.c b/libs/iotivity/src/api/oc_discovery.c
new file mode 100644
index 0000000..34d34b8
--- /dev/null
+++ b/libs/iotivity/src/api/oc_discovery.c
@@ -0,0 +1,298 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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.
+*/
+
+#ifdef OC_CLIENT
+#include "oc_client_state.h"
+#endif /* OC_CLIENT */
+
+#include "messaging/coap/oc_coap.h"
+#include "oc_api.h"
+#include "oc_core_res.h"
+
+static bool
+filter_resource(oc_resource_t *resource, const char *rt, int rt_len,
+                CborEncoder *links)
+{
+  int i;
+  bool match = true;
+  if (rt_len > 0) {
+    match = false;
+    for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) {
+      int size = oc_string_array_get_item_size(resource->types, i);
+      const char *t =
+        (const char *)oc_string_array_get_item(resource->types, i);
+      if (rt_len == size && strncmp(rt, t, rt_len) == 0) {
+        match = true;
+        break;
+      }
+    }
+  }
+
+  if (!match) {
+    return false;
+  }
+
+  oc_rep_start_object(*links, res);
+
+  // uri
+  oc_rep_set_text_string(res, href, oc_string(resource->uri));
+
+  // rt
+  oc_rep_set_array(res, rt);
+  for (i = 0; i < oc_string_array_get_allocated_size(resource->types); i++) {
+    int size = oc_string_array_get_item_size(resource->types, i);
+    const char *t = (const char *)oc_string_array_get_item(resource->types, i);
+    if (size > 0)
+      oc_rep_add_text_string(rt, t);
+  }
+  oc_rep_close_array(res, rt);
+
+  // if
+  oc_core_encode_interfaces_mask(oc_rep_object(res), resource->interfaces);
+
+  // p
+  oc_rep_set_object(res, p);
+  oc_rep_set_uint(p, bm, resource->properties & ~OC_PERIODIC);
+#ifdef OC_SECURITY
+  if (resource->properties & OC_SECURE) {
+    oc_rep_set_boolean(p, sec, true);
+    oc_rep_set_uint(p, port, oc_connectivity_get_dtls_port());
+  }
+#endif /* OC_SECURITY */
+
+  oc_rep_close_object(res, p);
+
+  oc_rep_end_object(*links, res);
+  return true;
+}
+
+static int
+process_device_object(CborEncoder *device, const char *uuid, const char *rt,
+                      int rt_len)
+{
+  int dev, matches = 0;
+  oc_rep_start_object(*device, links);
+  oc_rep_set_text_string(links, di, uuid);
+  oc_rep_set_array(links, links);
+
+  if (filter_resource(oc_core_get_resource_by_index(OCF_P), rt, rt_len,
+                      oc_rep_array(links)))
+    matches++;
+
+  for (dev = 0; dev < oc_core_get_num_devices(); dev++) {
+    if (filter_resource(
+          oc_core_get_resource_by_index(NUM_OC_CORE_RESOURCES - 1 - dev), rt,
+          rt_len, oc_rep_array(links)))
+      matches++;
+  }
+
+#ifdef OC_SERVER
+  oc_resource_t *resource = oc_ri_get_app_resources();
+  for (; resource; resource = resource->next) {
+
+    if (!(resource->properties & OC_DISCOVERABLE))
+      continue;
+
+    if (filter_resource(resource, rt, rt_len, oc_rep_array(links)))
+      matches++;
+  }
+#endif
+
+#ifdef OC_SECURITY
+  if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_DOXM), rt, rt_len,
+                      oc_rep_array(links)))
+    matches++;
+#endif
+
+  oc_rep_close_array(links, links);
+  oc_rep_end_object(*device, links);
+
+  return matches;
+}
+
+static void
+oc_core_discovery_handler(oc_request_t *request, oc_interface_mask_t interface)
+{
+  char *rt = NULL;
+  int rt_len = 0, matches = 0;
+  if (request->query_len) {
+    rt_len =
+      oc_ri_get_query_value(request->query, request->query_len, "rt", &rt);
+  }
+
+  char uuid[37];
+  oc_uuid_to_str(oc_core_get_device_id(0), uuid, 37);
+
+  switch (interface) {
+  case OC_IF_LL: {
+    oc_rep_start_links_array();
+    matches = process_device_object(oc_rep_array(links), uuid, rt, rt_len);
+    oc_rep_end_links_array();
+  } break;
+  case OC_IF_BASELINE: {
+    oc_rep_start_root_object();
+    oc_process_baseline_interface(request->resource);
+    oc_rep_set_array(root, links);
+    matches = process_device_object(oc_rep_array(links), uuid, rt, rt_len);
+    oc_rep_close_array(root, links);
+    oc_rep_end_root_object();
+  } break;
+  default:
+    break;
+  }
+
+  int response_length = oc_rep_finalize();
+
+  if (matches && response_length) {
+    request->response->response_buffer->response_length = response_length;
+    request->response->response_buffer->code = oc_status_code(OC_STATUS_OK);
+  } else {
+    /* There were rt/if selections and there were no matches, so ignore */
+    request->response->response_buffer->code = OC_IGNORE;
+  }
+}
+
+void
+oc_create_discovery_resource(void)
+{
+  oc_core_populate_resource(OCF_RES, "/oic/res", "oic.wk.res",
+                            OC_IF_LL | OC_IF_BASELINE, OC_IF_LL, OC_ACTIVE,
+                            oc_core_discovery_handler, 0, 0, 0, 0);
+}
+
+#ifdef OC_CLIENT
+oc_discovery_flags_t
+oc_ri_process_discovery_payload(uint8_t *payload, int len,
+                                oc_discovery_cb_t *handler,
+                                oc_endpoint_t *endpoint)
+{
+  oc_discovery_flags_t ret = OC_CONTINUE_DISCOVERY;
+  oc_string_t uri;
+  uri.ptr = 0;
+  oc_string_t di;
+  di.ptr = 0;
+  bool secure = false;
+  uint16_t dtls_port = 0, default_port = endpoint->ipv6_addr.port;
+  oc_string_array_t types = {};
+  oc_interface_mask_t interfaces = 0;
+  oc_server_handle_t handle;
+  memcpy(&handle.endpoint, endpoint, sizeof(oc_endpoint_t));
+
+  oc_rep_t *array = 0, *rep;
+  int s = oc_parse_rep(payload, len, &rep);
+  if (s == 0)
+    array = rep;
+  while (array != NULL) {
+    oc_rep_t *device_map = array->value_object;
+    while (device_map != NULL) {
+      switch (device_map->type) {
+      case STRING:
+        if (oc_string_len(device_map->name) == 2 &&
+            strncmp(oc_string(device_map->name), "di", 2) == 0)
+          di = device_map->value_string;
+        break;
+      default:
+        break;
+      }
+      device_map = device_map->next;
+    }
+    device_map = array->value_object;
+    while (device_map != NULL) {
+      switch (device_map->type) {
+      case OBJECT_ARRAY: {
+        oc_rep_t *links = device_map->value_object_array;
+        while (links != NULL) {
+          switch (links->type) {
+          case OBJECT: {
+            oc_rep_t *resource_info = links->value_object;
+            while (resource_info != NULL) {
+              switch (resource_info->type) {
+              case STRING:
+                uri = resource_info->value_string;
+                break;
+              case STRING_ARRAY:
+                if (oc_string_len(resource_info->name) == 2 &&
+                    strncmp(oc_string(resource_info->name), "rt", 2) == 0)
+                  types = resource_info->value_array;
+                else {
+                  interfaces = 0;
+                  int i;
+                  for (i = 0; i < oc_string_array_get_allocated_size(
+                                    resource_info->value_array);
+                       i++) {
+                    interfaces |= oc_ri_get_interface_mask(
+                      oc_string_array_get_item(resource_info->value_array, i),
+                      oc_string_array_get_item_size(resource_info->value_array,
+                                                    i));
+                  }
+                }
+                break;
+              case OBJECT: {
+                oc_rep_t *policy_info = resource_info->value_object;
+                while (policy_info != NULL) {
+                  if (policy_info->type == INT &&
+                      oc_string_len(policy_info->name) == 4 &&
+                      strncmp(oc_string(policy_info->name), "port", 4) == 0) {
+                    dtls_port = policy_info->value_int;
+                  }
+                  if (policy_info->type == BOOL &&
+                      oc_string_len(policy_info->name) == 3 &&
+                      strncmp(oc_string(policy_info->name), "sec", 3) == 0 &&
+                      policy_info->value_boolean == true) {
+                    secure = true;
+                  }
+                  policy_info = policy_info->next;
+                }
+              } break;
+              default:
+                break;
+              }
+              resource_info = resource_info->next;
+            }
+            if (secure) {
+              handle.endpoint.ipv6_addr.port = dtls_port;
+              handle.endpoint.flags |= SECURED;
+            } else {
+              handle.endpoint.ipv6_addr.port = default_port;
+              handle.endpoint.flags &= ~SECURED;
+            }
+
+            if (handler(oc_string(di), oc_string(uri), types, interfaces,
+                        &handle) == OC_STOP_DISCOVERY) {
+              ret = OC_STOP_DISCOVERY;
+              goto done;
+            }
+            dtls_port = 0;
+            secure = false;
+          } break;
+          default:
+            break;
+          }
+          links = links->next;
+        }
+      } break;
+      default:
+        break;
+      }
+      device_map = device_map->next;
+    }
+    array = array->next;
+  }
+done:
+  oc_free_rep(rep);
+  return ret;
+}
+#endif /* OC_CLIENT */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_events.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_events.h b/libs/iotivity/src/api/oc_events.h
new file mode 100644
index 0000000..d79c22b
--- /dev/null
+++ b/libs/iotivity/src/api/oc_events.h
@@ -0,0 +1,34 @@
+/*
+ // Copyright (c) 2016 Intel Corporation
+ //
+ // Licensed 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 OC_EVENTS_H
+#define OC_EVENTS_H
+
+#include "util/oc_process.h"
+
+typedef enum {
+  INBOUND_NETWORK_EVENT,
+  UDP_TO_DTLS_EVENT,
+  INIT_DTLS_CONN_EVENT,
+  RI_TO_DTLS_EVENT,
+  INBOUND_RI_EVENT,
+  OUTBOUND_NETWORK_EVENT,
+  __NUM_OC_EVENT_TYPES__
+} oc_events_t;
+
+oc_process_event_t oc_events[__NUM_OC_EVENT_TYPES__];
+
+#endif /* OC_EVENTS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_helpers.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_helpers.c b/libs/iotivity/src/api/oc_helpers.c
new file mode 100644
index 0000000..4af8eeb
--- /dev/null
+++ b/libs/iotivity/src/api/oc_helpers.c
@@ -0,0 +1,164 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 "oc_helpers.h"
+#include "port/oc_assert.h"
+#include "port/oc_log.h"
+#include <stdbool.h>
+
+static bool mmem_initialized = false;
+
+static void
+oc_malloc(oc_handle_t *block, uint16_t num_bytes, pool pool_type)
+{
+  if (!mmem_initialized) {
+    oc_mmem_init();
+    mmem_initialized = true;
+  }
+  oc_assert(oc_mmem_alloc(block, num_bytes, pool_type) > 0);
+}
+
+static void
+oc_free(oc_handle_t *block, pool pool_type)
+{
+  oc_mmem_free(block, pool_type);
+  block->next = 0;
+  block->ptr = 0;
+  block->size = 0;
+}
+
+void
+oc_new_string(oc_string_t *ocstring, const char str[])
+{
+  oc_malloc(ocstring, strlen(str) + 1, BYTE_POOL);
+  memcpy(oc_string(*ocstring), (const uint8_t *)str, strlen(str));
+  memcpy(oc_string(*ocstring) + strlen(str), (const uint8_t *)"", 1);
+}
+
+void
+oc_alloc_string(oc_string_t *ocstring, int size)
+{
+  oc_malloc(ocstring, size, BYTE_POOL);
+}
+
+void
+oc_free_string(oc_string_t *ocstring)
+{
+  oc_free(ocstring, BYTE_POOL);
+}
+
+void
+oc_concat_strings(oc_string_t *concat, const char *str1, const char *str2)
+{
+  size_t len1 = strlen(str1), len2 = strlen(str2);
+  oc_alloc_string(concat, len1 + len2 + 1);
+  memcpy(oc_string(*concat), str1, len1);
+  memcpy(oc_string(*concat) + len1, str2, len2);
+  memcpy(oc_string(*concat) + len1 + len2, (const char *)"", 1);
+}
+
+void
+_oc_new_array(oc_array_t *ocarray, uint8_t size, pool type)
+{
+  switch (type) {
+  case INT_POOL:
+    oc_malloc(ocarray, size * sizeof(int64_t), INT_POOL);
+    break;
+  case BYTE_POOL:
+    oc_malloc(ocarray, size * sizeof(bool), BYTE_POOL);
+    break;
+  case DOUBLE_POOL:
+    oc_malloc(ocarray, size * sizeof(double), DOUBLE_POOL);
+    break;
+  default:
+    break;
+  }
+}
+
+void
+_oc_free_array(oc_array_t *ocarray, pool type)
+{
+  oc_free(ocarray, type);
+}
+
+void
+_oc_alloc_string_array(oc_string_array_t *ocstringarray, uint8_t size)
+{
+  oc_alloc_string(ocstringarray, size * STRING_ARRAY_ITEM_MAX_LEN);
+  int i, pos;
+  for (i = 0; i < size; i++) {
+    pos = i * STRING_ARRAY_ITEM_MAX_LEN;
+    memcpy((char *)oc_string(*ocstringarray) + pos, (const char *)"", 1);
+  }
+}
+
+bool
+_oc_copy_string_to_string_array(oc_string_array_t *ocstringarray,
+                                const char str[], uint8_t index)
+{
+  if (strlen(str) >= STRING_ARRAY_ITEM_MAX_LEN) {
+    return false;
+  }
+  uint8_t pos = index * STRING_ARRAY_ITEM_MAX_LEN;
+  memcpy(oc_string(*ocstringarray) + pos, (const uint8_t *)str, strlen(str));
+  memcpy(oc_string(*ocstringarray) + pos + strlen(str), (const uint8_t *)"", 1);
+  return true;
+}
+
+bool
+_oc_string_array_add_item(oc_string_array_t *ocstringarray, const char str[])
+{
+  bool success = false;
+  int i;
+  for (i = 0; i < oc_string_array_get_allocated_size(*ocstringarray); i++) {
+    if (strlen((const char *)oc_string_array_get_item(*ocstringarray, i)) ==
+        0) {
+      success = oc_string_array_set_item(*ocstringarray, str, i);
+      break;
+    }
+  }
+  return success;
+}
+
+void
+oc_join_string_array(oc_string_array_t *ocstringarray, oc_string_t *ocstring)
+{
+  size_t len = 0;
+  uint8_t i;
+  for (i = 0; i < oc_string_array_get_allocated_size(*ocstringarray); i++) {
+    const char *item =
+      (const char *)oc_string_array_get_item(*ocstringarray, i);
+    if (strlen(item)) {
+      len += strlen(item);
+      len++;
+    }
+  }
+  oc_alloc_string(ocstring, len);
+  len = 0;
+  for (i = 0; i < oc_string_array_get_allocated_size(*ocstringarray); i++) {
+    const char *item =
+      (const char *)oc_string_array_get_item(*ocstringarray, i);
+    if (strlen(item)) {
+      if (len > 0) {
+        oc_string(*ocstring)[len] = ' ';
+        len++;
+      }
+      strncpy((char *)oc_string(*ocstring) + len, item, strlen(item));
+      len += strlen(item);
+    }
+  }
+  strcpy((char *)oc_string(*ocstring) + len, "");
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/api/oc_main.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/api/oc_main.c b/libs/iotivity/src/api/oc_main.c
new file mode 100644
index 0000000..9086b4e
--- /dev/null
+++ b/libs/iotivity/src/api/oc_main.c
@@ -0,0 +1,119 @@
+/*
+// Copyright (c) 2016 Intel Corporation
+//
+// Licensed 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 <stdint.h>
+#include <stdio.h>
+
+#include "port/oc_assert.h"
+#include "port/oc_clock.h"
+#include "port/oc_connectivity.h"
+
+#include "util/oc_etimer.h"
+#include "util/oc_process.h"
+
+#include "oc_api.h"
+
+#ifdef OC_SECURITY
+#include "security/oc_dtls.h"
+#include "security/oc_store.h"
+#include "security/oc_svr.h"
+#endif /* OC_SECURITY */
+
+static bool initialized = false;
+
+int
+oc_main_init(oc_handler_t *handler)
+{
+  int ret;
+  extern int oc_stack_errno;
+
+  if (initialized == true)
+    return 0;
+
+  oc_ri_init();
+
+#ifdef OC_SECURITY
+  handler->get_credentials();
+
+  oc_sec_load_pstat();
+  oc_sec_load_doxm();
+  oc_sec_load_cred();
+
+  oc_sec_dtls_init_context();
+#endif
+
+  oc_network_event_handler_mutex_init();
+  ret = oc_connectivity_init();
+  if (ret < 0)
+    goto err;
+
+  handler->init();
+
+#ifdef OC_SERVER
+  handler->register_resources();
+#endif
+
+#ifdef OC_SECURITY
+  oc_sec_create_svr();
+  oc_sec_load_acl();
+#endif
+
+  if (oc_stack_errno != 0) {
+    ret = -oc_stack_errno;
+    goto err;
+  }
+
+  PRINT("oc_main: Stack successfully initialized\n");
+
+#ifdef OC_CLIENT
+  handler->requests_entry();
+#endif
+
+  initialized = true;
+  return 0;
+
+err:
+  oc_abort("oc_main: Error in stack initialization\n");
+  return ret;
+}
+
+oc_clock_time_t
+oc_main_poll(void)
+{
+  oc_clock_time_t ticks_until_next_event = oc_etimer_request_poll();
+  while (oc_process_run()) {
+    ticks_until_next_event = oc_etimer_request_poll();
+  }
+  return ticks_until_next_event;
+}
+
+void
+oc_main_shutdown(void)
+{
+  if (initialized == false) {
+    PRINT("tiny_ocf is not initialized\n");
+    return;
+  }
+
+  oc_connectivity_shutdown();
+  oc_ri_shutdown();
+
+#ifdef OC_SECURITY /* fix ensure this gets executed on constraied platforms */
+  oc_sec_dump_state();
+#endif
+
+  initialized = false;
+}



[05/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_process.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_process.h b/libs/iotivity/src/util/oc_process.h
new file mode 100644
index 0000000..a4944b3
--- /dev/null
+++ b/libs/iotivity/src/util/oc_process.h
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ */
+
+/**
+ * \defgroup process Contiki processes
+ *
+ * A process in Contiki consists of a single \ref pt "protothread".
+ *
+ * @{
+ */
+
+#ifndef OC_PROCESS_H
+#define OC_PROCESS_H
+#include "util/pt/pt.h"
+
+#ifndef NULL
+#define NULL 0
+#endif /* NULL */
+
+typedef unsigned char oc_process_event_t;
+typedef void *oc_process_data_t;
+typedef unsigned char oc_process_num_events_t;
+
+/**
+ * \name Return values
+ * @{
+ */
+
+/**
+ * \brief      Return value indicating that an operation was successful.
+ *
+ *             This value is returned to indicate that an operation
+ *             was successful.
+ */
+#define OC_PROCESS_ERR_OK 0
+/**
+ * \brief      Return value indicating that the event queue was full.
+ *
+ *             This value is returned from process_post() to indicate
+ *             that the event queue was full and that an event could
+ *             not be posted.
+ */
+#define OC_PROCESS_ERR_FULL 1
+/* @} */
+
+#define OC_PROCESS_NONE NULL
+
+#ifndef OC_PROCESS_CONF_NUMEVENTS
+#define OC_PROCESS_CONF_NUMEVENTS 10
+#endif /* OC_PROCESS_CONF_NUMEVENTS */
+
+#define OC_PROCESS_EVENT_NONE 0x80
+#define OC_PROCESS_EVENT_INIT 0x81
+#define OC_PROCESS_EVENT_POLL 0x82
+#define OC_PROCESS_EVENT_EXIT 0x83
+#define OC_PROCESS_EVENT_SERVICE_REMOVED 0x84
+#define OC_PROCESS_EVENT_CONTINUE 0x85
+#define OC_PROCESS_EVENT_MSG 0x86
+#define OC_PROCESS_EVENT_EXITED 0x87
+#define OC_PROCESS_EVENT_TIMER 0x88
+#define OC_PROCESS_EVENT_COM 0x89
+#define OC_PROCESS_EVENT_MAX 0x8a
+
+#define OC_PROCESS_BROADCAST NULL
+#define OC_PROCESS_ZOMBIE ((struct oc_process *)0x1)
+
+/**
+ * \name Process protothread functions
+ * @{
+ */
+
+/**
+ * Define the beginning of a process.
+ *
+ * This macro defines the beginning of a process, and must always
+ * appear in a OC_PROCESS_THREAD() definition. The OC_PROCESS_END() macro
+ * must come at the end of the process.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_BEGIN() PT_BEGIN(process_pt)
+
+/**
+ * Define the end of a process.
+ *
+ * This macro defines the end of a process. It must appear in a
+ * OC_PROCESS_THREAD() definition and must always be included. The
+ * process exits when the OC_PROCESS_END() macro is reached.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_END() PT_END(process_pt)
+
+/**
+ * Wait for an event to be posted to the process.
+ *
+ * This macro blocks the currently running process until the process
+ * receives an event.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_WAIT_EVENT() OC_PROCESS_YIELD()
+
+/**
+ * Wait for an event to be posted to the process, with an extra
+ * condition.
+ *
+ * This macro is similar to OC_PROCESS_WAIT_EVENT() in that it blocks the
+ * currently running process until the process receives an event. But
+ * OC_PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be
+ * true for the process to continue.
+ *
+ * \param c The condition that must be true for the process to continue.
+ * \sa PT_WAIT_UNTIL()
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_WAIT_EVENT_UNTIL(c) OC_PROCESS_YIELD_UNTIL(c)
+
+/**
+ * Yield the currently running process.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_YIELD() PT_YIELD(process_pt)
+
+/**
+ * Yield the currently running process until a condition occurs.
+ *
+ * This macro is different from OC_PROCESS_WAIT_UNTIL() in that
+ * OC_PROCESS_YIELD_UNTIL() is guaranteed to always yield at least
+ * once. This ensures that the process does not end up in an infinite
+ * loop and monopolizing the CPU.
+ *
+ * \param c The condition to wait for.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c)
+
+/**
+ * Wait for a condition to occur.
+ *
+ * This macro does not guarantee that the process yields, and should
+ * therefore be used with care. In most cases, OC_PROCESS_WAIT_EVENT(),
+ * OC_PROCESS_WAIT_EVENT_UNTIL(), OC_PROCESS_YIELD() or
+ * OC_PROCESS_YIELD_UNTIL() should be used instead.
+ *
+ * \param c The condition to wait for.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c)
+#define OC_PROCESS_WAIT_WHILE(c) PT_WAIT_WHILE(process_pt, c)
+
+/**
+ * Exit the currently running process.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_EXIT() PT_EXIT(process_pt)
+
+/**
+ * Spawn a protothread from the process.
+ *
+ * \param pt The protothread state (struct pt) for the new protothread
+ * \param thread The call to the protothread function.
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_PT_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread)
+
+/**
+ * Yield the process for a short while.
+ *
+ * This macro yields the currently running process for a short while,
+ * thus letting other processes run before the process continues.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_PAUSE()                                                     \
+  do {                                                                         \
+    process_post(OC_PROCESS_CURRENT(), OC_PROCESS_EVENT_CONTINUE, NULL);       \
+    OC_PROCESS_WAIT_EVENT_UNTIL(ev == OC_PROCESS_EVENT_CONTINUE);              \
+  } while (0)
+
+/** @} end of protothread functions */
+
+/**
+ * \name Poll and exit handlers
+ * @{
+ */
+/**
+ * Specify an action when a process is polled.
+ *
+ * \note This declaration must come immediately before the
+ * OC_PROCESS_BEGIN() macro.
+ *
+ * \param handler The action to be performed.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_POLLHANDLER(handler)                                        \
+  if (ev == OC_PROCESS_EVENT_POLL) {                                           \
+    handler;                                                                   \
+  }
+
+/**
+ * Specify an action when a process exits.
+ *
+ * \note This declaration must come immediately before the
+ * OC_PROCESS_BEGIN() macro.
+ *
+ * \param handler The action to be performed.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_EXITHANDLER(handler)                                        \
+  if (ev == OC_PROCESS_EVENT_EXIT) {                                           \
+    handler;                                                                   \
+  }
+
+/** @} */
+
+/**
+ * \name Process declaration and definition
+ * @{
+ */
+
+/**
+ * Define the body of a process.
+ *
+ * This macro is used to define the body (protothread) of a
+ * process. The process is called whenever an event occurs in the
+ * system, A process always start with the OC_PROCESS_BEGIN() macro and
+ * end with the OC_PROCESS_END() macro.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_THREAD(name, ev, data)                                      \
+  static PT_THREAD(process_thread_##name(                                      \
+    struct pt *process_pt, oc_process_event_t ev, oc_process_data_t data))
+
+/**
+ * Declare the name of a process.
+ *
+ * This macro is typically used in header files to declare the name of
+ * a process that is implemented in the C file.
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_NAME(name) extern struct oc_process name
+
+/**
+ * Declare a process.
+ *
+ * This macro declares a process. The process has two names: the
+ * variable of the process structure, which is used by the C program,
+ * and a human readable string name, which is used when debugging.
+ * A configuration option allows removal of the readable name to save RAM.
+ *
+ * \param name The variable name of the process structure.
+ * \param strname The string representation of the process' name.
+ *
+ * \hideinitializer
+ */
+#if OC_PROCESS_CONF_NO_OC_PROCESS_NAMES
+#define OC_PROCESS(name, strname)                                              \
+  OC_PROCESS_THREAD(name, ev, data);                                           \
+  struct oc_process name = { NULL, process_thread_##name }
+#else
+#define OC_PROCESS(name, strname)                                              \
+  OC_PROCESS_THREAD(name, ev, data);                                           \
+  struct oc_process name = { NULL, strname, process_thread_##name }
+#endif
+
+/** @} */
+
+struct oc_process
+{
+  struct oc_process *next;
+#if OC_PROCESS_CONF_NO_OC_PROCESS_NAMES
+#define OC_PROCESS_NAME_STRING(process) ""
+#else
+  const char *name;
+#define OC_PROCESS_NAME_STRING(process) (process)->name
+#endif
+  PT_THREAD((*thread)(struct pt *, oc_process_event_t, oc_process_data_t));
+  struct pt pt;
+  unsigned char state, needspoll;
+};
+
+/**
+ * \name Functions called from application programs
+ * @{
+ */
+
+/**
+ * Start a process.
+ *
+ * \param p A pointer to a process structure.
+ *
+ * \param data An argument pointer that can be passed to the new
+ * process
+ *
+ */
+void oc_process_start(struct oc_process *p, oc_process_data_t data);
+
+/**
+ * Post an asynchronous event.
+ *
+ * This function posts an asynchronous event to one or more
+ * processes. The handing of the event is deferred until the target
+ * process is scheduled by the kernel. An event can be broadcast to
+ * all processes, in which case all processes in the system will be
+ * scheduled to handle the event.
+ *
+ * \param ev The event to be posted.
+ *
+ * \param data The auxiliary data to be sent with the event
+ *
+ * \param p The process to which the event should be posted, or
+ * OC_PROCESS_BROADCAST if the event should be posted to all processes.
+ *
+ * \retval OC_PROCESS_ERR_OK The event could be posted.
+ *
+ * \retval OC_PROCESS_ERR_FULL The event queue was full and the event could
+ * not be posted.
+ */
+int oc_process_post(struct oc_process *p, oc_process_event_t ev,
+                    oc_process_data_t data);
+
+/**
+ * Post a synchronous event to a process.
+ *
+ * \param p A pointer to the process' process structure.
+ *
+ * \param ev The event to be posted.
+ *
+ * \param data A pointer to additional data that is posted together
+ * with the event.
+ */
+void oc_process_post_synch(struct oc_process *p, oc_process_event_t ev,
+                           oc_process_data_t data);
+
+/**
+ * \brief      Cause a process to exit
+ * \param p    The process that is to be exited
+ *
+ *             This function causes a process to exit. The process can
+ *             either be the currently executing process, or another
+ *             process that is currently running.
+ *
+ * \sa OC_PROCESS_CURRENT()
+ */
+void oc_process_exit(struct oc_process *p);
+
+/**
+ * Get a pointer to the currently running process.
+ *
+ * This macro get a pointer to the currently running
+ * process. Typically, this macro is used to post an event to the
+ * current process with process_post().
+ *
+ * \hideinitializer
+ */
+#define OC_PROCESS_CURRENT() oc_process_current
+extern struct oc_process *oc_process_current;
+
+/**
+ * Switch context to another process
+ *
+ * This function switch context to the specified process and executes
+ * the code as if run by that process. Typical use of this function is
+ * to switch context in services, called by other processes. Each
+ * OC_PROCESS_CONTEXT_BEGIN() must be followed by the
+ * OC_PROCESS_CONTEXT_END() macro to end the context switch.
+ *
+ * Example:
+ \code
+ OC_PROCESS_CONTEXT_BEGIN(&test_process);
+ etimer_set(&timer, CLOCK_SECOND);
+ OC_PROCESS_CONTEXT_END(&test_process);
+ \endcode
+ *
+ * \param p    The process to use as context
+ *
+ * \sa OC_PROCESS_CONTEXT_END()
+ * \sa OC_PROCESS_CURRENT()
+ */
+#define OC_PROCESS_CONTEXT_BEGIN(p)                                            \
+  {                                                                            \
+    struct oc_process *tmp_current = OC_PROCESS_CURRENT();                     \
+  oc_process_current = p
+
+/**
+ * End a context switch
+ *
+ * This function ends a context switch and changes back to the
+ * previous process.
+ *
+ * \param p    The process used in the context switch
+ *
+ * \sa OC_PROCESS_CONTEXT_START()
+ */
+#define OC_PROCESS_CONTEXT_END(p)                                              \
+  oc_process_current = tmp_current;                                            \
+  }
+
+/**
+ * \brief      Allocate a global event number.
+ * \return     The allocated event number
+ *
+ *             In Contiki, event numbers above 128 are global and may
+ *             be posted from one process to another. This function
+ *             allocates one such event number.
+ *
+ * \note       There currently is no way to deallocate an allocated event
+ *             number.
+ */
+oc_process_event_t oc_process_alloc_event(void);
+
+/** @} */
+
+/**
+ * \name Functions called from device drivers
+ * @{
+ */
+
+/**
+ * Request a process to be polled.
+ *
+ * This function typically is called from an interrupt handler to
+ * cause a process to be polled.
+ *
+ * \param p A pointer to the process' process structure.
+ */
+void oc_process_poll(struct oc_process *p);
+
+/** @} */
+
+/**
+ * \name Functions called by the system and boot-up code
+ * @{
+ */
+
+/**
+ * \brief      Initialize the process module.
+ *
+ *             This function initializes the process module and should
+ *             be called by the system boot-up code.
+ */
+void oc_process_init(void);
+
+/**
+ * Run the system once - call poll handlers and process one event.
+ *
+ * This function should be called repeatedly from the main() program
+ * to actually run the Contiki system. It calls the necessary poll
+ * handlers, and processes one event. The function returns the number
+ * of events that are waiting in the event queue so that the caller
+ * may choose to put the CPU to sleep when there are no pending
+ * events.
+ *
+ * \return The number of events that are currently waiting in the
+ * event queue.
+ */
+int oc_process_run(void);
+
+/**
+ * Check if a process is running.
+ *
+ * This function checks if a specific process is running.
+ *
+ * \param p The process.
+ * \retval Non-zero if the process is running.
+ * \retval Zero if the process is not running.
+ */
+int oc_process_is_running(struct oc_process *p);
+
+/**
+ *  Number of events waiting to be processed.
+ *
+ * \return The number of events that are currently waiting to be
+ * processed.
+ */
+int oc_process_nevents(void);
+
+/** @} */
+
+extern struct oc_process *oc_process_list;
+
+#define OC_PROCESS_LIST() oc_process_list
+
+#endif /* OC_PROCESS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_timer.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_timer.c b/libs/iotivity/src/util/oc_timer.c
new file mode 100644
index 0000000..5372f0b
--- /dev/null
+++ b/libs/iotivity/src/util/oc_timer.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#include "oc_timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function is used to set a timer for a time sometime in the
+ * future. The function oc_timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * \param t A pointer to the timer
+ * \param interval The interval before the timer expires.
+ *
+ */
+void
+oc_timer_set(struct oc_timer *t, oc_clock_time_t interval)
+{
+  t->interval = interval;
+  t->start = oc_clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the oc_timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * oc_timer_restart() function.
+ *
+ * \note Must not be executed before timer expired
+ *
+ * \param t A pointer to the timer.
+ * \sa oc_timer_restart()
+ */
+void
+oc_timer_reset(struct oc_timer *t)
+{
+  t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the oc_timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the oc_timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa oc_timer_reset()
+ */
+void
+oc_timer_restart(struct oc_timer *t)
+{
+  t->start = oc_clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+oc_timer_expired(struct oc_timer *t)
+{
+  /* Note: Can not return diff >= t->interval so we add 1 to diff and return
+     t->interval < diff - required to avoid an internal error in mspgcc. */
+  oc_clock_time_t diff = (oc_clock_time() - t->start) + 1;
+  return t->interval < diff;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * The time until the timer expires
+ *
+ * This function returns the time until the timer expires.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return The time until the timer expires
+ *
+ */
+oc_clock_time_t
+oc_timer_remaining(struct oc_timer *t)
+{
+  return t->start + t->interval - oc_clock_time();
+}
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/oc_timer.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/oc_timer.h b/libs/iotivity/src/util/oc_timer.h
new file mode 100644
index 0000000..9769dc8
--- /dev/null
+++ b/libs/iotivity/src/util/oc_timer.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \defgroup timer Timer library
+ *
+ * The Contiki kernel does not provide support for timed
+ * events. Rather, an application that wants to use timers needs to
+ * explicitly use the timer library.
+ *
+ * The timer library provides functions for setting, resetting and
+ * restarting timers, and for checking if a timer has expired. An
+ * application must "manually" check if its timers have expired; this
+ * is not done automatically.
+ *
+ * A timer is declared as a \c struct \c timer and all access to the
+ * timer is made by a pointer to the declared timer.
+ *
+ * \note The timer library is not able to post events when a timer
+ * expires. The \ref etimer "Event timers" should be used for this
+ * purpose.
+ *
+ * \note The timer library uses the \ref clock "Clock library" to
+ * measure time. Intervals should be specified in the format used by
+ * the clock library.
+ *
+ * \sa \ref etimer "Event timers"
+ *
+ * @{
+ */
+
+#ifndef OC_TIMER_H
+#define OC_TIMER_H
+
+#include "port/oc_clock.h"
+
+/**
+ * A timer.
+ *
+ * This structure is used for declaring a timer. The timer must be set
+ * with timer_set() before it can be used.
+ *
+ * \hideinitializer
+ */
+struct oc_timer
+{
+  oc_clock_time_t start;
+  oc_clock_time_t interval;
+};
+
+void oc_timer_set(struct oc_timer *t, oc_clock_time_t interval);
+void oc_timer_reset(struct oc_timer *t);
+void oc_timer_restart(struct oc_timer *t);
+int oc_timer_expired(struct oc_timer *t);
+oc_clock_time_t oc_timer_remaining(struct oc_timer *t);
+
+#endif /* OC_TIMER_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/pt/lc-addrlabels.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/pt/lc-addrlabels.h b/libs/iotivity/src/util/pt/lc-addrlabels.h
new file mode 100644
index 0000000..a0dedf0
--- /dev/null
+++ b/libs/iotivity/src/util/pt/lc-addrlabels.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <ad...@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ * Thanks to dividuum for finding the nice local scope label
+ * implementation.
+ */
+
+#ifndef LC_ADDRLABELS_H_
+#define LC_ADDRLABELS_H_
+
+/** \hideinitializer */
+typedef void *lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s)                                                           \
+  do {                                                                         \
+    if (s != NULL) {                                                           \
+      goto *s;                                                                 \
+    }                                                                          \
+  } while (0)
+
+#define LC_SET(s)                                                              \
+  do {                                                                         \
+    ({                                                                         \
+      __label__ resume;                                                        \
+    resume:                                                                    \
+      (s) = &&resume;                                                          \
+    });                                                                        \
+  } while (0)
+
+#define LC_END(s)
+
+#endif /* LC_ADDRLABELS_H_ */
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/pt/lc-switch.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/pt/lc-switch.h b/libs/iotivity/src/util/pt/lc-switch.h
new file mode 100644
index 0000000..3f7e819
--- /dev/null
+++ b/libs/iotivity/src/util/pt/lc-switch.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statement
+ * \author Adam Dunkels <ad...@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statements.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef LC_SWITCH_H_
+#define LC_SWITCH_H_
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s)                                                           \
+  switch (s) {                                                                 \
+  case 0:
+
+#define LC_SET(s)                                                              \
+  s = __LINE__;                                                                \
+  case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* LC_SWITCH_H_ */
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/pt/lc.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/pt/lc.h b/libs/iotivity/src/util/pt/lc.h
new file mode 100644
index 0000000..f787f51
--- /dev/null
+++ b/libs/iotivity/src/util/pt/lc.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file core/sys/lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef LC_H_
+#define LC_H_
+
+#ifdef LC_CONF_INCLUDE
+#include LC_CONF_INCLUDE
+#else /* LC_CONF_INCLUDE */
+#include "lc-switch.h"
+#endif /* LC_CONF_INCLUDE */
+
+#endif /* LC_H_ */
+
+/** @} */
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/pt/pt-sem.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/pt/pt-sem.h b/libs/iotivity/src/util/pt/pt-sem.h
new file mode 100644
index 0000000..85bdd17
--- /dev/null
+++ b/libs/iotivity/src/util/pt/pt-sem.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signaled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+
+  PT_BEGIN(pt);
+
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+
+    PT_SEM_WAIT(pt, &full);
+
+    PT_SEM_WAIT(pt, &mutex);
+    add_to_buffer(produce_item());
+    PT_SEM_SIGNAL(pt, &mutex);
+
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+
+    PT_SEM_WAIT(pt, &empty);
+
+    PT_SEM_WAIT(pt, &mutex);
+    consume_item(get_from_buffer());
+    PT_SEM_SIGNAL(pt, &mutex);
+
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+  PT_SEM_INIT(&mutex, 1);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+         consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ *
+ *
+ */
+
+/**
+ * \file
+ * Counting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#ifndef PT_SEM_H_
+#define PT_SEM_H_
+
+#include "pt.h"
+
+struct pt_sem
+{
+  unsigned int head, tail;
+};
+
+#define PT_SEM_COUNT(s) ((s)->head - (s)->tail)
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c)                                                      \
+  do {                                                                         \
+    (s)->tail = 0;                                                             \
+    (s)->head = (c);                                                           \
+  } while (0)
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s)                                                     \
+  do {                                                                         \
+    PT_WAIT_UNTIL(pt, PT_SEM_COUNT(s) > 0);                                    \
+    ++(s)->tail;                                                               \
+  } while (0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) (++(s)->head)
+
+#endif /* PT_SEM_H_ */
+
+/** @} */
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/util/pt/pt.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/util/pt/pt.h b/libs/iotivity/src/util/pt/pt.h
new file mode 100644
index 0000000..87d8173
--- /dev/null
+++ b/libs/iotivity/src/util/pt/pt.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <ad...@sics.se>
+ *
+ */
+
+#ifndef PT_H_
+#define PT_H_
+
+#include "lc.h"
+
+struct pt
+{
+  lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED 2
+#define PT_ENDED 3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt) LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt)                                                           \
+  {                                                                            \
+    char PT_YIELD_FLAG = 1;                                                    \
+    if (PT_YIELD_FLAG) {                                                       \
+      ;                                                                        \
+    }                                                                          \
+  LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt)                                                             \
+  LC_END((pt)->lc);                                                            \
+  PT_YIELD_FLAG = 0;                                                           \
+  PT_INIT(pt);                                                                 \
+  return PT_ENDED;                                                             \
+  }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)                                           \
+  do {                                                                         \
+    LC_SET((pt)->lc);                                                          \
+    if (!(condition)) {                                                        \
+      return PT_WAITING;                                                       \
+    }                                                                          \
+  } while (0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)                                            \
+  do {                                                                         \
+    PT_INIT((child));                                                          \
+    PT_WAIT_THREAD((pt), (thread));                                            \
+  } while (0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)                                                         \
+  do {                                                                         \
+    PT_INIT(pt);                                                               \
+    return PT_WAITING;                                                         \
+  } while (0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)                                                            \
+  do {                                                                         \
+    PT_INIT(pt);                                                               \
+    return PT_EXITED;                                                          \
+  } while (0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function schedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)                                                           \
+  do {                                                                         \
+    PT_YIELD_FLAG = 0;                                                         \
+    LC_SET((pt)->lc);                                                          \
+    if (PT_YIELD_FLAG == 0) {                                                  \
+      return PT_YIELDED;                                                       \
+    }                                                                          \
+  } while (0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)                                               \
+  do {                                                                         \
+    PT_YIELD_FLAG = 0;                                                         \
+    LC_SET((pt)->lc);                                                          \
+    if ((PT_YIELD_FLAG == 0) || !(cond)) {                                     \
+      return PT_YIELDED;                                                       \
+    }                                                                          \
+  } while (0)
+
+/** @} */
+
+#endif /* PT_H_ */
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/assert_p.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/assert_p.h b/libs/tinycbor/include/tinycbor/assert_p.h
new file mode 100644
index 0000000..994be06
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/assert_p.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include <assert.h>
+#ifdef NDEBUG
+#  undef assert
+#  define assert(cond)      do { if (!(cond)) unreachable(); } while (0)
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/cbor.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/cbor.h b/libs/tinycbor/include/tinycbor/cbor.h
new file mode 100644
index 0000000..f78e4af
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/cbor.h
@@ -0,0 +1,479 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef CBOR_H
+#define CBOR_H
+
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#else
+#include <stdbool.h>
+#endif
+
+#ifndef SIZE_MAX
+/* Some systems fail to define SIZE_MAX in <stdint.h>, even though C99 requires it...
+ * Conversion from signed to unsigned is defined in 6.3.1.3 (Signed and unsigned integers) p2,
+ * which says: "the value is converted by repeatedly adding or subtracting one more than the
+ * maximum value that can be represented in the new type until the value is in the range of the
+ * new type."
+ * So -1 gets converted to size_t by adding SIZE_MAX + 1, which results in SIZE_MAX.
+ */
+#  define SIZE_MAX ((size_t)-1)
+#endif
+
+#ifndef CBOR_API
+#  define CBOR_API
+#endif
+#ifndef CBOR_PRIVATE_API
+#  define CBOR_PRIVATE_API
+#endif
+#ifndef CBOR_INLINE_API
+#  if defined(__cplusplus)
+#    define CBOR_INLINE inline
+#    define CBOR_INLINE_API inline
+#  else
+#    define CBOR_INLINE_API static CBOR_INLINE
+#    if defined(_MSC_VER)
+#      define CBOR_INLINE __inline
+#    elif defined(__GNUC__)
+#      define CBOR_INLINE __inline__
+#    elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#      define CBOR_INLINE inline
+#    else
+#      define CBOR_INLINE
+#    endif
+#  endif
+#endif
+
+typedef enum CborType {
+    CborIntegerType     = 0x00,
+    CborByteStringType  = 0x40,
+    CborTextStringType  = 0x60,
+    CborArrayType       = 0x80,
+    CborMapType         = 0xa0,
+    CborTagType         = 0xc0,
+    CborSimpleType      = 0xe0,
+    CborBooleanType     = 0xf5,
+    CborNullType        = 0xf6,
+    CborUndefinedType   = 0xf7,
+    CborHalfFloatType   = 0xf9,
+    CborFloatType       = 0xfa,
+    CborDoubleType      = 0xfb,
+
+    CborInvalidType     = 0xff              /* equivalent to the break byte, so it will never be used */
+} CborType;
+
+typedef uint64_t CborTag;
+typedef enum CborKnownTags {
+    CborDateTimeStringTag          = 0,        /* RFC 3339 format: YYYY-MM-DD hh:mm:ss+zzzz */
+    CborUnixTime_tTag              = 1,
+    CborPositiveBignumTag          = 2,
+    CborNegativeBignumTag          = 3,
+    CborDecimalTag                 = 4,
+    CborBigfloatTag                = 5,
+    CborExpectedBase64urlTag       = 21,
+    CborExpectedBase64Tag          = 22,
+    CborExpectedBase16Tag          = 23,
+    CborUriTag                     = 32,
+    CborBase64urlTag               = 33,
+    CborBase64Tag                  = 34,
+    CborRegularExpressionTag       = 35,
+    CborMimeMessageTag             = 36,       /* RFC 2045-2047 */
+    CborSignatureTag               = 55799
+} CborKnownTags;
+
+/* Error API */
+
+typedef enum CborError {
+    CborNoError = 0,
+
+    /* errors in all modes */
+    CborUnknownError,
+    CborErrorUnknownLength,         /* request for length in array, map, or string with indeterminate length */
+    CborErrorAdvancePastEOF,
+    CborErrorIO,
+
+    /* parser errors streaming errors */
+    CborErrorGarbageAtEnd = 256,
+    CborErrorUnexpectedEOF,
+    CborErrorUnexpectedBreak,
+    CborErrorUnknownType,           /* can only heppen in major type 7 */
+    CborErrorIllegalType,           /* type not allowed here */
+    CborErrorIllegalNumber,
+    CborErrorIllegalSimpleType,     /* types of value less than 32 encoded in two bytes */
+
+    /* parser errors in strict mode parsing only */
+    CborErrorUnknownSimpleType = 512,
+    CborErrorUnknownTag,
+    CborErrorInappropriateTagForType,
+    CborErrorDuplicateObjectKeys,
+    CborErrorInvalidUtf8TextString,
+
+    /* encoder errors */
+    CborErrorTooManyItems = 768,
+    CborErrorTooFewItems,
+
+    /* internal implementation errors */
+    CborErrorDataTooLarge = 1024,
+    CborErrorNestingTooDeep,
+    CborErrorUnsupportedType,
+
+    /* errors in converting to JSON */
+    CborErrorJsonObjectKeyIsAggregate,
+    CborErrorJsonObjectKeyNotString,
+    CborErrorJsonNotImplemented,
+
+    CborErrorOutOfMemory = ~0U / 2 + 1,
+    CborErrorInternalError = ~0U
+} CborError;
+
+CBOR_API const char *cbor_error_string(CborError error);
+
+/* Encoder API */
+struct CborEncoder
+{
+    union {
+        uint8_t *ptr;
+        ptrdiff_t bytes_needed;
+    };
+    const uint8_t *end;
+    size_t added;
+    int flags;
+};
+typedef struct CborEncoder CborEncoder;
+
+static const size_t CborIndefiniteLength = SIZE_MAX;
+
+CBOR_API void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags);
+CBOR_API CborError cbor_encode_uint(CborEncoder *encoder, uint64_t value);
+CBOR_API CborError cbor_encode_int(CborEncoder *encoder, int64_t value);
+CBOR_API CborError cbor_encode_negative_int(CborEncoder *encoder, uint64_t absolute_value);
+CBOR_API CborError cbor_encode_simple_value(CborEncoder *encoder, uint8_t value);
+CBOR_API CborError cbor_encode_tag(CborEncoder *encoder, CborTag tag);
+CBOR_API CborError cbor_encode_text_string(CborEncoder *encoder, const char *string, size_t length);
+CBOR_INLINE_API CborError cbor_encode_text_stringz(CborEncoder *encoder, const char *string)
+{ return cbor_encode_text_string(encoder, string, strlen(string)); }
+CBOR_API CborError cbor_encode_byte_string(CborEncoder *encoder, const uint8_t *string, size_t length);
+CBOR_API CborError cbor_encode_floating_point(CborEncoder *encoder, CborType fpType, const void *value);
+
+CBOR_INLINE_API CborError cbor_encode_boolean(CborEncoder *encoder, bool value)
+{ return cbor_encode_simple_value(encoder, (int)value - 1 + (CborBooleanType & 0x1f)); }
+CBOR_INLINE_API CborError cbor_encode_null(CborEncoder *encoder)
+{ return cbor_encode_simple_value(encoder, CborNullType & 0x1f); }
+CBOR_INLINE_API CborError cbor_encode_undefined(CborEncoder *encoder)
+{ return cbor_encode_simple_value(encoder, CborUndefinedType & 0x1f); }
+
+CBOR_INLINE_API CborError cbor_encode_half_float(CborEncoder *encoder, const void *value)
+{ return cbor_encode_floating_point(encoder, CborHalfFloatType, value); }
+CBOR_INLINE_API CborError cbor_encode_float(CborEncoder *encoder, float value)
+{ return cbor_encode_floating_point(encoder, CborFloatType, &value); }
+CBOR_INLINE_API CborError cbor_encode_double(CborEncoder *encoder, double value)
+{ return cbor_encode_floating_point(encoder, CborDoubleType, &value); }
+
+CBOR_API CborError cbor_encoder_create_array(CborEncoder *encoder, CborEncoder *arrayEncoder, size_t length);
+CBOR_API CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder, size_t length);
+CBOR_API CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder);
+CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder);
+
+CBOR_INLINE_API size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
+{
+    return (size_t)(encoder->ptr - buffer);
+}
+
+CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
+{
+    return encoder->end ? 0 : (size_t)encoder->bytes_needed;
+}
+
+/* Parser API */
+
+enum CborParserIteratorFlags
+{
+    CborIteratorFlag_IntegerValueTooLarge   = 0x01,
+    CborIteratorFlag_NegativeInteger        = 0x02,
+    CborIteratorFlag_UnknownLength          = 0x04,
+    CborIteratorFlag_ContainerIsMap         = 0x20
+};
+
+struct CborParser
+{
+    const uint8_t *end;
+    int flags;
+};
+typedef struct CborParser CborParser;
+
+struct CborValue
+{
+    const CborParser *parser;
+    const uint8_t *ptr;
+    uint32_t remaining;
+    uint16_t extra;
+    uint8_t type;
+    uint8_t flags;
+};
+typedef struct CborValue CborValue;
+
+CBOR_API CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it);
+
+CBOR_INLINE_API bool cbor_value_at_end(const CborValue *it)
+{ return it->remaining == 0; }
+CBOR_INLINE_API const uint8_t *cbor_value_get_next_byte(const CborValue *it)
+{ return it->ptr; }
+CBOR_API CborError cbor_value_advance_fixed(CborValue *it);
+CBOR_API CborError cbor_value_advance(CborValue *it);
+CBOR_INLINE_API bool cbor_value_is_container(const CborValue *it)
+{ return it->type == CborArrayType || it->type == CborMapType; }
+CBOR_API CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed);
+CBOR_API CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed);
+
+CBOR_PRIVATE_API uint64_t _cbor_value_decode_int64_internal(const CborValue *value);
+CBOR_INLINE_API uint64_t _cbor_value_extract_int64_helper(const CborValue *value)
+{
+    return value->flags & CborIteratorFlag_IntegerValueTooLarge ?
+                _cbor_value_decode_int64_internal(value) : value->extra;
+}
+
+CBOR_INLINE_API bool cbor_value_is_valid(const CborValue *value)
+{ return value && value->type != CborInvalidType; }
+CBOR_INLINE_API CborType cbor_value_get_type(const CborValue *value)
+{ return (CborType)value->type; }
+
+/* Null & undefined type */
+CBOR_INLINE_API bool cbor_value_is_null(const CborValue *value)
+{ return value->type == CborNullType; }
+CBOR_INLINE_API bool cbor_value_is_undefined(const CborValue *value)
+{ return value->type == CborUndefinedType; }
+
+/* Booleans */
+CBOR_INLINE_API bool cbor_value_is_boolean(const CborValue *value)
+{ return value->type == CborBooleanType; }
+CBOR_INLINE_API CborError cbor_value_get_boolean(const CborValue *value, bool *result)
+{
+    assert(cbor_value_is_boolean(value));
+    *result = !!value->extra;
+    return CborNoError;
+}
+
+/* Simple types */
+CBOR_INLINE_API bool cbor_value_is_simple_type(const CborValue *value)
+{ return value->type == CborSimpleType; }
+CBOR_INLINE_API CborError cbor_value_get_simple_type(const CborValue *value, uint8_t *result)
+{
+    assert(cbor_value_is_simple_type(value));
+    *result = (uint8_t)value->extra;
+    return CborNoError;
+}
+
+/* Integers */
+CBOR_INLINE_API bool cbor_value_is_integer(const CborValue *value)
+{ return value->type == CborIntegerType; }
+CBOR_INLINE_API bool cbor_value_is_unsigned_integer(const CborValue *value)
+{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger) == 0; }
+CBOR_INLINE_API bool cbor_value_is_negative_integer(const CborValue *value)
+{ return cbor_value_is_integer(value) && (value->flags & CborIteratorFlag_NegativeInteger); }
+
+CBOR_INLINE_API CborError cbor_value_get_raw_integer(const CborValue *value, uint64_t *result)
+{
+    assert(cbor_value_is_integer(value));
+    *result = _cbor_value_extract_int64_helper(value);
+    return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_uint64(const CborValue *value, uint64_t *result)
+{
+    assert(cbor_value_is_unsigned_integer(value));
+    *result = _cbor_value_extract_int64_helper(value);
+    return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_int64(const CborValue *value, int64_t *result)
+{
+    assert(cbor_value_is_integer(value));
+    *result = (int64_t) _cbor_value_extract_int64_helper(value);
+    if (value->flags & CborIteratorFlag_NegativeInteger)
+        *result = -*result - 1;
+    return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_int(const CborValue *value, int *result)
+{
+    assert(cbor_value_is_integer(value));
+    *result = (int) _cbor_value_extract_int64_helper(value);
+    if (value->flags & CborIteratorFlag_NegativeInteger)
+        *result = -*result - 1;
+    return CborNoError;
+}
+
+CBOR_API CborError cbor_value_get_int64_checked(const CborValue *value, int64_t *result);
+CBOR_API CborError cbor_value_get_int_checked(const CborValue *value, int *result);
+
+CBOR_INLINE_API bool cbor_value_is_length_known(const CborValue *value)
+{ return (value->flags & CborIteratorFlag_UnknownLength) == 0; }
+
+/* Tags */
+CBOR_INLINE_API bool cbor_value_is_tag(const CborValue *value)
+{ return value->type == CborTagType; }
+CBOR_INLINE_API CborError cbor_value_get_tag(const CborValue *value, CborTag *result)
+{
+    assert(cbor_value_is_tag(value));
+    *result = _cbor_value_extract_int64_helper(value);
+    return CborNoError;
+}
+CBOR_API CborError cbor_value_skip_tag(CborValue *it);
+
+/* Strings */
+CBOR_INLINE_API bool cbor_value_is_byte_string(const CborValue *value)
+{ return value->type == CborByteStringType; }
+CBOR_INLINE_API bool cbor_value_is_text_string(const CborValue *value)
+{ return value->type == CborTextStringType; }
+
+CBOR_INLINE_API CborError cbor_value_get_string_length(const CborValue *value, size_t *length)
+{
+    assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value));
+    if (!cbor_value_is_length_known(value))
+        return CborErrorUnknownLength;
+    uint64_t v = _cbor_value_extract_int64_helper(value);
+    *length = v;
+    if (*length != v)
+        return CborErrorDataTooLarge;
+    return CborNoError;
+}
+
+CBOR_PRIVATE_API CborError _cbor_value_copy_string(const CborValue *value, void *buffer,
+                                                   size_t *buflen, CborValue *next);
+CBOR_PRIVATE_API CborError _cbor_value_dup_string(const CborValue *value, void **buffer,
+                                                  size_t *buflen, CborValue *next);
+
+CBOR_API CborError cbor_value_calculate_string_length(const CborValue *value, size_t *length);
+
+CBOR_INLINE_API CborError cbor_value_copy_text_string(const CborValue *value, char *buffer,
+                                                      size_t *buflen, CborValue *next)
+{
+    assert(cbor_value_is_text_string(value));
+    return _cbor_value_copy_string(value, buffer, buflen, next);
+}
+CBOR_INLINE_API CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer,
+                                                      size_t *buflen, CborValue *next)
+{
+    assert(cbor_value_is_byte_string(value));
+    return _cbor_value_copy_string(value, buffer, buflen, next);
+}
+
+CBOR_INLINE_API CborError cbor_value_dup_text_string(const CborValue *value, char **buffer,
+                                                     size_t *buflen, CborValue *next)
+{
+    assert(cbor_value_is_text_string(value));
+    return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
+}
+CBOR_INLINE_API CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer,
+                                                     size_t *buflen, CborValue *next)
+{
+    assert(cbor_value_is_byte_string(value));
+    return _cbor_value_dup_string(value, (void **)buffer, buflen, next);
+}
+
+/* ### TBD: partial reading API */
+
+CBOR_API CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result);
+
+/* Maps and arrays */
+CBOR_INLINE_API bool cbor_value_is_array(const CborValue *value)
+{ return value->type == CborArrayType; }
+CBOR_INLINE_API bool cbor_value_is_map(const CborValue *value)
+{ return value->type == CborMapType; }
+
+CBOR_INLINE_API CborError cbor_value_get_array_length(const CborValue *value, size_t *length)
+{
+    assert(cbor_value_is_array(value));
+    if (!cbor_value_is_length_known(value))
+        return CborErrorUnknownLength;
+    uint64_t v = _cbor_value_extract_int64_helper(value);
+    *length = v;
+    if (*length != v)
+        return CborErrorDataTooLarge;
+    return CborNoError;
+}
+
+CBOR_INLINE_API CborError cbor_value_get_map_length(const CborValue *value, size_t *length)
+{
+    assert(cbor_value_is_map(value));
+    if (!cbor_value_is_length_known(value))
+        return CborErrorUnknownLength;
+    uint64_t v = _cbor_value_extract_int64_helper(value);
+    *length = v;
+    if (*length != v)
+        return CborErrorDataTooLarge;
+    return CborNoError;
+}
+
+CBOR_API CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element);
+
+/* Floating point */
+CBOR_INLINE_API bool cbor_value_is_half_float(const CborValue *value)
+{ return value->type == CborHalfFloatType; }
+CBOR_API CborError cbor_value_get_half_float(const CborValue *value, void *result);
+
+CBOR_INLINE_API bool cbor_value_is_float(const CborValue *value)
+{ return value->type == CborFloatType; }
+CBOR_INLINE_API CborError cbor_value_get_float(const CborValue *value, float *result)
+{
+    assert(cbor_value_is_float(value));
+    assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
+    uint32_t data = (uint32_t)_cbor_value_decode_int64_internal(value);
+    memcpy(result, &data, sizeof(*result));
+    return CborNoError;
+}
+
+CBOR_INLINE_API bool cbor_value_is_double(const CborValue *value)
+{ return value->type == CborDoubleType; }
+CBOR_INLINE_API CborError cbor_value_get_double(const CborValue *value, double *result)
+{
+    assert(cbor_value_is_double(value));
+    assert(value->flags & CborIteratorFlag_IntegerValueTooLarge);
+    uint64_t data = _cbor_value_decode_int64_internal(value);
+    memcpy(result, &data, sizeof(*result));
+    return CborNoError;
+}
+
+/* Human-readable (dump) API */
+CBOR_API CborError cbor_value_to_pretty_advance(FILE *out, CborValue *value);
+CBOR_INLINE_API CborError cbor_value_to_pretty(FILE *out, const CborValue *value)
+{
+    CborValue copy = *value;
+    return cbor_value_to_pretty_advance(out, &copy);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CBOR_H */
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/cborconstants_p.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/cborconstants_p.h b/libs/tinycbor/include/tinycbor/cborconstants_p.h
new file mode 100644
index 0000000..d5808c3
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/cborconstants_p.h
@@ -0,0 +1,52 @@
+#ifndef CBORCONSTANTS_P_H
+#define CBORCONSTANTS_P_H
+
+/*
+ * CBOR Major types
+ * Encoded in the high 3 bits of the descriptor byte
+ * See http://tools.ietf.org/html/rfc7049#section-2.1
+ */
+typedef enum CborMajorTypes {
+    UnsignedIntegerType = 0U,
+    NegativeIntegerType = 1U,
+    ByteStringType = 2U,
+    TextStringType = 3U,
+    ArrayType = 4U,
+    MapType = 5U,           /* a.k.a. object */
+    TagType = 6U,
+    SimpleTypesType = 7U
+} CborMajorTypes;
+
+/*
+ * CBOR simple and floating point types
+ * Encoded in the low 8 bits of the descriptor byte when the
+ * Major Type is 7.
+ */
+typedef enum CborSimpleTypes {
+    FalseValue              = 20,
+    TrueValue               = 21,
+    NullValue               = 22,
+    UndefinedValue          = 23,
+    SimpleTypeInNextByte    = 24,   /* not really a simple type */
+    HalfPrecisionFloat      = 25,   /* ditto */
+    SinglePrecisionFloat    = 26,   /* ditto */
+    DoublePrecisionFloat    = 27,   /* ditto */
+    Break                   = 31
+} CborSimpleTypes;
+
+enum {
+    SmallValueBitLength     = 5U,
+    SmallValueMask          = (1U << SmallValueBitLength) - 1,      /* 31 */
+    Value8Bit               = 24U,
+    Value16Bit              = 25U,
+    Value32Bit              = 26U,
+    Value64Bit              = 27U,
+    IndefiniteLength        = 31U,
+
+    MajorTypeShift          = SmallValueBitLength,
+    MajorTypeMask           = ~0U << MajorTypeShift,
+
+    BreakByte               = (unsigned)Break | (SimpleTypesType << MajorTypeShift)
+};
+
+#endif /* CBORCONSTANTS_P_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/cborjson.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/cborjson.h b/libs/tinycbor/include/tinycbor/cborjson.h
new file mode 100644
index 0000000..8ff27b9
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/cborjson.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef CBORJSON_H
+#define CBORJSON_H
+
+#include "cbor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Conversion to JSON */
+enum CborToJsonFlags
+{
+    CborConvertAddMetadata = 1,
+    CborConvertTagsToObjects = 2,
+    CborConvertIgnoreTags = 0,
+
+    CborConvertObeyByteStringTags = 0,
+    CborConvertByteStringsToBase64Url = 4,
+
+    CborConvertRequireMapStringKeys = 0,
+    CborConvertStringifyMapKeys = 8,
+
+    CborConvertDefaultFlags = 0
+};
+
+CBOR_API CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags);
+CBOR_INLINE_API CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
+{
+    CborValue copy = *value;
+    return cbor_value_to_json_advance(out, &copy, flags);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CBORJSON_H */
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/tinycbor/include/tinycbor/compilersupport_p.h
----------------------------------------------------------------------
diff --git a/libs/tinycbor/include/tinycbor/compilersupport_p.h b/libs/tinycbor/include/tinycbor/compilersupport_p.h
new file mode 100644
index 0000000..4e0dbe3
--- /dev/null
+++ b/libs/tinycbor/include/tinycbor/compilersupport_p.h
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Intel Corporation
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef COMPILERSUPPORT_H
+#define COMPILERSUPPORT_H
+
+#include "cbor.h"
+
+#ifndef _BSD_SOURCE
+#  define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+#  define _DEFAULT_SOURCE
+#endif
+#include <assert.h>
+#include <float.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifndef __cplusplus
+#  include <stdbool.h>
+#endif
+
+#ifdef __F16C__
+#  include <immintrin.h>
+#endif
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || __cpp_static_assert >= 200410
+#  define cbor_static_assert(x)         _Static_assert(x, #x)
+#elif !defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
+#  define cbor_static_assert(x)         _Static_assert(x, #x)
+#else
+#  define cbor_static_assert(x)         ((void)sizeof(char[2*!!(x) - 1]))
+#endif
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+/* inline is a keyword */
+#else
+/* use the definition from cbor.h */
+#  define inline    CBOR_INLINE
+#endif
+
+#define STRINGIFY(x)            STRINGIFY2(x)
+#define STRINGIFY2(x)           #x
+
+#if !defined(UINT32_MAX) || !defined(INT64_MAX)
+/* C89? We can define UINT32_MAX portably, but not INT64_MAX */
+#  error "Your system has stdint.h but that doesn't define UINT32_MAX or INT64_MAX"
+#endif
+
+#ifndef DBL_DECIMAL_DIG
+/* DBL_DECIMAL_DIG is C11 */
+#  define DBL_DECIMAL_DIG       17
+#endif
+#define DBL_DECIMAL_DIG_STR     STRINGIFY(DBL_DECIMAL_DIG)
+
+#ifndef __has_builtin
+#  define __has_builtin(x)  0
+#endif
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) || \
+    (__has_builtin(__builtin_bswap64) && __has_builtin(__builtin_bswap32))
+#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#    define cbor_ntohll     __builtin_bswap64
+#    define cbor_htonll     __builtin_bswap64
+#    define cbor_ntohl      __builtin_bswap32
+#    define cbor_htonl      __builtin_bswap32
+#    ifdef __INTEL_COMPILER
+#      define cbor_ntohs    _bswap16
+#      define cbor_htons    _bswap16
+#    elif (__GNUC__ * 100 + __GNUC_MINOR__ >= 608) || __has_builtin(__builtin_bswap16)
+#      define cbor_ntohs    __builtin_bswap16
+#      define cbor_htons    __builtin_bswap16
+#    else
+#      define cbor_ntohs(x) (((uint16_t)x >> 8) | ((uint16_t)x << 8))
+#      define cbor_htons    cbor_ntohs
+#    endif
+#  else
+#    define cbor_ntohll
+#    define cbor_htonll
+#    define cbor_ntohl
+#    define cbor_htonl
+#    define cbor_ntohs
+#    define cbor_htons
+#  endif
+#elif defined(__sun)
+#  include <sys/byteorder.h>
+#elif defined(_MSC_VER)
+/* MSVC, which implies Windows, which implies little-endian and sizeof(long) == 4 */
+#  define cbor_ntohll       _byteswap_uint64
+#  define cbor_htonll       _byteswap_uint64
+#  define cbor_ntohl        _byteswap_ulong
+#  define cbor_htonl        _byteswap_ulong
+#  define cbor_ntohs        _byteswap_ushort
+#  define cbor_htons        _byteswap_ushort
+#endif
+#ifndef cbor_ntohs
+#  include <arpa/inet.h>
+#  define cbor_ntohs        ntohs
+#  define cbor_htons        htons
+#endif
+#ifndef cbor_ntohl
+#  include <arpa/inet.h>
+#  define cbor_ntohl        ntohl
+#  define cbor_htonl        htonl
+#endif
+#ifndef cbor_ntohll
+#  define cbor_ntohll       ntohll
+#  define cbor_htonll       htonll
+/* ntohll isn't usually defined */
+#  ifndef ntohll
+#    if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#      define ntohll
+#      define htonll
+#    elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#      define ntohll(x)       ((ntohl((uint32_t)(x)) * UINT64_C(0x100000000)) + (ntohl((x) >> 32)))
+#      define htonll          ntohll
+#    else
+#      error "Unable to determine byte order!"
+#    endif
+#  endif
+#endif
+
+
+#ifdef __cplusplus
+#  define CONST_CAST(t, v)  const_cast<t>(v)
+#else
+/* C-style const_cast without triggering a warning with -Wcast-qual */
+#  define CONST_CAST(t, v)  (t)(uintptr_t)(v)
+#endif
+
+#ifdef __GNUC__
+#  define likely(x)     __builtin_expect(!!(x), 1)
+#  define unlikely(x)   __builtin_expect(!!(x), 0)
+#  define unreachable() __builtin_unreachable()
+#elif defined(_MSC_VER)
+#  define likely(x)     (x)
+#  define unlikely(x)   (x)
+#  define unreachable() __assume(0)
+#else
+#  define likely(x)     (x)
+#  define unlikely(x)   (x)
+#  define unreachable() do {} while (0)
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && \
+    (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+#  pragma GCC optimize("-ffunction-sections")
+#endif
+
+static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r)
+{
+#if ((defined(__GNUC__) && (__GNUC__ >= 5)) && !defined(__INTEL_COMPILER)) || __has_builtin(__builtin_add_overflow)
+    return __builtin_add_overflow(v1, v2, r);
+#else
+    /* unsigned additions are well-defined */
+    *r = v1 + v2;
+    return v1 > v1 + v2;
+#endif
+}
+
+static inline unsigned short encode_half(double val)
+{
+#ifdef __F16C__
+    return _cvtss_sh(val, 3);
+#else
+    uint64_t v;
+    memcpy(&v, &val, sizeof(v));
+    int sign = v >> 63 << 15;
+    int exp = (v >> 52) & 0x7ff;
+    int mant = v << 12 >> 12 >> (53-11);    /* keep only the 11 most significant bits of the mantissa */
+    exp -= 1023;
+    if (exp == 1024) {
+        /* infinity or NaN */
+        exp = 16;
+        mant >>= 1;
+    } else if (exp >= 16) {
+        /* overflow, as largest number */
+        exp = 15;
+        mant = 1023;
+    } else if (exp >= -14) {
+        /* regular normal */
+    } else if (exp >= -24) {
+        /* subnormal */
+        mant |= 1024;
+        mant >>= -(exp + 14);
+        exp = -15;
+    } else {
+        /* underflow, make zero */
+        return 0;
+    }
+    return sign | ((exp + 15) << 10) | mant;
+#endif
+}
+
+#endif /* COMPILERSUPPORT_H */
+



[08/10] incubator-mynewt-core git commit: Add tinycbor and iotivity constrained to the repo.

Posted by pa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/coap.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/coap.c b/libs/iotivity/src/messaging/coap/coap.c
new file mode 100644
index 0000000..e8d8608
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/coap.c
@@ -0,0 +1,1186 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "coap.h"
+#include "transactions.h"
+
+#ifdef OC_SECURITY
+#include "security/oc_dtls.h"
+#endif
+
+/*---------------------------------------------------------------------------*/
+/*- Variables ---------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+static uint16_t current_mid = 0;
+
+coap_status_t erbium_status_code = NO_ERROR;
+char *coap_error_message = "";
+/*---------------------------------------------------------------------------*/
+/*- Local helper functions --------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+static uint16_t
+coap_log_2(uint16_t value)
+{
+  uint16_t result = 0;
+
+  do {
+    value = value >> 1;
+    result++;
+  } while (value);
+
+  return (result - 1);
+}
+/*---------------------------------------------------------------------------*/
+static uint32_t
+coap_parse_int_option(uint8_t *bytes, size_t length)
+{
+  uint32_t var = 0;
+  int i = 0;
+
+  while (i < length) {
+    var <<= 8;
+    var |= bytes[i++];
+  }
+  return var;
+}
+/*---------------------------------------------------------------------------*/
+static uint8_t
+coap_option_nibble(unsigned int value)
+{
+  if (value < 13) {
+    return value;
+  } else if (value <= 0xFF + 13) {
+    return 13;
+  } else {
+    return 14;
+  }
+}
+/*---------------------------------------------------------------------------*/
+static size_t
+coap_set_option_header(unsigned int delta, size_t length, uint8_t *buffer)
+{
+  size_t written = 0;
+
+  buffer[0] = coap_option_nibble(delta) << 4 | coap_option_nibble(length);
+
+  if (delta > 268) {
+    buffer[++written] = ((delta - 269) >> 8) & 0xff;
+    buffer[++written] = (delta - 269) & 0xff;
+  } else if (delta > 12) {
+    buffer[++written] = (delta - 13);
+  }
+
+  if (length > 268) {
+    buffer[++written] = ((length - 269) >> 8) & 0xff;
+    buffer[++written] = (length - 269) & 0xff;
+  } else if (length > 12) {
+    buffer[++written] = (length - 13);
+  }
+
+  LOG("WRITTEN %zu B opt header\n", 1 + written);
+
+  return ++written;
+}
+/*---------------------------------------------------------------------------*/
+static size_t
+coap_serialize_int_option(unsigned int number, unsigned int current_number,
+                          uint8_t *buffer, uint32_t value)
+{
+  size_t i = 0;
+
+  if (0xFF000000 & value) {
+    ++i;
+  }
+  if (0xFFFF0000 & value) {
+    ++i;
+  }
+  if (0xFFFFFF00 & value) {
+    ++i;
+  }
+  if (0xFFFFFFFF & value) {
+    ++i;
+  }
+  LOG("OPTION %u (delta %u, len %zu)\n", number, number - current_number, i);
+
+  i = coap_set_option_header(number - current_number, i, buffer);
+
+  if (0xFF000000 & value) {
+    buffer[i++] = (uint8_t)(value >> 24);
+  }
+  if (0xFFFF0000 & value) {
+    buffer[i++] = (uint8_t)(value >> 16);
+  }
+  if (0xFFFFFF00 & value) {
+    buffer[i++] = (uint8_t)(value >> 8);
+  }
+  if (0xFFFFFFFF & value) {
+    buffer[i++] = (uint8_t)(value);
+  }
+  return i;
+}
+/*---------------------------------------------------------------------------*/
+static size_t
+coap_serialize_array_option(unsigned int number, unsigned int current_number,
+                            uint8_t *buffer, uint8_t *array, size_t length,
+                            char split_char)
+{
+  size_t i = 0;
+
+  LOG("ARRAY type %u, len %zu, full [%.*s]\n", number, length, (int)length,
+      array);
+
+  if (split_char != '\0') {
+    int j;
+    uint8_t *part_start = array;
+    uint8_t *part_end = NULL;
+    size_t temp_length;
+
+    for (j = 0; j <= length + 1; ++j) {
+      LOG("STEP %u/%zu (%c)\n", j, length, array[j]);
+      if (array[j] == split_char || j == length) {
+        part_end = array + j;
+        temp_length = part_end - part_start;
+
+        i += coap_set_option_header(number - current_number, temp_length,
+                                    &buffer[i]);
+        memcpy(&buffer[i], part_start, temp_length);
+        i += temp_length;
+
+        LOG("OPTION type %u, delta %u, len %zu, part [%.*s]\n", number,
+            number - current_number, i, (int)temp_length, part_start);
+
+        ++j; /* skip the splitter */
+        current_number = number;
+        part_start = array + j;
+      }
+    } /* for */
+  } else {
+    i += coap_set_option_header(number - current_number, length, &buffer[i]);
+    memcpy(&buffer[i], array, length);
+    i += length;
+
+    LOG("OPTION type %u, delta %u, len %zu\n", number, number - current_number,
+        length);
+  }
+
+  return i;
+}
+/*---------------------------------------------------------------------------*/
+static void
+coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option,
+                        size_t option_len, char separator)
+{
+  /* merge multiple options */
+  if (*dst_len > 0) {
+    /* dst already contains an option: concatenate */
+    (*dst)[*dst_len] = separator;
+    *dst_len += 1;
+
+    /* memmove handles 2-byte option headers */
+    memmove((*dst) + (*dst_len), option, option_len);
+
+    *dst_len += option_len;
+  } else {
+    /* dst is empty: set to option */
+    *dst = (char *)option;
+    *dst_len = option_len;
+  }
+}
+/*---------------------------------------------------------------------------*/
+#if 0
+static int
+coap_get_variable(const char *buffer, size_t length, const char *name,
+		  const char **output)
+{
+  const char *start = NULL;
+  const char *end = NULL;
+  const char *value_end = NULL;
+  size_t name_len = 0;
+
+  /*initialize the output buffer first */
+  *output = 0;
+
+  name_len = strlen(name);
+  end = buffer + length;
+
+  for(start = buffer; start + name_len < end; ++start) {
+    if((start == buffer || start[-1] == '&') && start[name_len] == '='
+       && strncmp(name, start, name_len) == 0) {
+
+      /* Point start to variable value */
+      start += name_len + 1;
+
+      /* Point end to the end of the value */
+      value_end = (const char *)memchr(start, '&', end - start);
+      if(value_end == NULL) {
+	value_end = end;
+      }
+      *output = start;
+
+      return value_end - start;
+    }
+  }
+  return 0;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+/*- Internal API ------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+void
+coap_init_connection()
+{
+  /* initialize transaction ID */
+  current_mid = oc_random_rand();
+}
+/*---------------------------------------------------------------------------*/
+uint16_t
+coap_get_mid()
+{
+  return ++current_mid;
+}
+/*---------------------------------------------------------------------------*/
+void
+coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
+                  uint16_t mid)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  /* Important thing */
+  memset(coap_pkt, 0, sizeof(coap_packet_t));
+
+  coap_pkt->type = type;
+  coap_pkt->code = code;
+  coap_pkt->mid = mid;
+}
+/*---------------------------------------------------------------------------*/
+size_t
+coap_serialize_message(void *packet, uint8_t *buffer)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+  uint8_t *option;
+  unsigned int current_number = 0;
+
+  /* Initialize */
+  coap_pkt->buffer = buffer;
+  coap_pkt->version = 1;
+
+  LOG("-Serializing MID %u to %p, ", coap_pkt->mid, coap_pkt->buffer);
+
+  /* set header fields */
+  coap_pkt->buffer[0] = 0x00;
+  coap_pkt->buffer[0] |= COAP_HEADER_VERSION_MASK &
+                         (coap_pkt->version) << COAP_HEADER_VERSION_POSITION;
+  coap_pkt->buffer[0] |=
+    COAP_HEADER_TYPE_MASK & (coap_pkt->type) << COAP_HEADER_TYPE_POSITION;
+  coap_pkt->buffer[0] |= COAP_HEADER_TOKEN_LEN_MASK &
+                         (coap_pkt->token_len)
+                           << COAP_HEADER_TOKEN_LEN_POSITION;
+  coap_pkt->buffer[1] = coap_pkt->code;
+  coap_pkt->buffer[2] = (uint8_t)((coap_pkt->mid) >> 8);
+  coap_pkt->buffer[3] = (uint8_t)(coap_pkt->mid);
+
+  /* empty packet, dont need to do more stuff */
+  if (!coap_pkt->code) {
+    LOG("-Done serializing empty message at %p-\n", coap_pkt->buffer);
+    return 4;
+  }
+
+  /* set Token */
+  LOG("Token (len %u)", coap_pkt->token_len);
+  option = coap_pkt->buffer + COAP_HEADER_LEN;
+  for (current_number = 0; current_number < coap_pkt->token_len;
+       ++current_number) {
+    LOG(" %02X", coap_pkt->token[current_number]);
+    *option = coap_pkt->token[current_number];
+    ++option;
+  }
+  LOG("-\n");
+
+  /* Serialize options */
+  current_number = 0;
+
+  LOG("-Serializing options at %p-\n", option);
+#if 0
+  /* The options must be serialized in the order of their number */
+  COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match");
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0',
+			       "Uri-Host");
+  COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag");
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
+			    content_format - coap_pkt-> content_format /* hack to get a zero field */,
+			    "If-None-Match");
+#endif
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe");
+#if 0
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path,
+			       '/', "Location-Path");
+#endif
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, '/', "Uri-Path");
+  LOG("Serialize content format: %d\n", coap_pkt->content_format);
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
+                            "Content-Format");
+#if 0
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age");
+#endif
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&',
+                               "Uri-Query");
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept");
+#if 0
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
+			       '&', "Location-Query");
+#endif
+  COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2");
+  COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1");
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2");
+#if 0
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0',
+			       "Proxy-Uri");
+  COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme,
+			       '\0', "Proxy-Scheme");
+#endif
+  COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1");
+
+  LOG("-Done serializing at %p----\n", option);
+
+  /* Pack payload */
+  if ((option - coap_pkt->buffer) <= COAP_MAX_HEADER_SIZE) {
+    /* Payload marker */
+    if (coap_pkt->payload_len) {
+      *option = 0xFF;
+      ++option;
+    }
+    memmove(option, coap_pkt->payload, coap_pkt->payload_len);
+  } else {
+    /* an error occurred: caller must check for !=0 */
+    coap_pkt->buffer = NULL;
+    coap_error_message = "Serialized header exceeds COAP_MAX_HEADER_SIZE";
+    return 0;
+  }
+
+  LOG("-Done %u B (header len %u, payload len %u)-\n",
+      (unsigned int)(coap_pkt->payload_len + option - buffer),
+      (unsigned int)(option - buffer), (unsigned int)coap_pkt->payload_len);
+
+  LOG("Dump [0x%02X %02X %02X %02X  %02X %02X %02X %02X]\n",
+      coap_pkt->buffer[0], coap_pkt->buffer[1], coap_pkt->buffer[2],
+      coap_pkt->buffer[3], coap_pkt->buffer[4], coap_pkt->buffer[5],
+      coap_pkt->buffer[6], coap_pkt->buffer[7]);
+  return (option - buffer) + coap_pkt->payload_len; /* packet length */
+}
+/*---------------------------------------------------------------------------*/
+void
+coap_send_message(oc_message_t *message)
+{
+  LOG("-sending OCF message (%lu)-\n", message->length);
+
+  oc_send_message(message);
+}
+/*---------------------------------------------------------------------------*/
+coap_status_t
+coap_parse_message(void *packet, uint8_t *data, uint16_t data_len)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+  /* initialize packet */
+  memset(coap_pkt, 0, sizeof(coap_packet_t));
+  /* pointer to packet bytes */
+  coap_pkt->buffer = data;
+  /* parse header fields */
+  coap_pkt->version = (COAP_HEADER_VERSION_MASK & coap_pkt->buffer[0]) >>
+                      COAP_HEADER_VERSION_POSITION;
+  coap_pkt->type =
+    (COAP_HEADER_TYPE_MASK & coap_pkt->buffer[0]) >> COAP_HEADER_TYPE_POSITION;
+  coap_pkt->token_len = (COAP_HEADER_TOKEN_LEN_MASK & coap_pkt->buffer[0]) >>
+                        COAP_HEADER_TOKEN_LEN_POSITION;
+  coap_pkt->code = coap_pkt->buffer[1];
+  coap_pkt->mid = coap_pkt->buffer[2] << 8 | coap_pkt->buffer[3];
+
+  if (coap_pkt->version != 1) {
+    coap_error_message = "CoAP version must be 1";
+    return BAD_REQUEST_4_00;
+  }
+
+  if (coap_pkt->token_len > COAP_TOKEN_LEN) {
+    coap_error_message = "Token Length must not be more than 8";
+    return BAD_REQUEST_4_00;
+  }
+
+  uint8_t *current_option = data + COAP_HEADER_LEN;
+
+  memcpy(coap_pkt->token, current_option, coap_pkt->token_len);
+  LOG("Token (len %u) [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
+      coap_pkt->token_len, coap_pkt->token[0], coap_pkt->token[1],
+      coap_pkt->token[2], coap_pkt->token[3], coap_pkt->token[4],
+      coap_pkt->token[5], coap_pkt->token[6],
+      coap_pkt->token[7]); /*FIXME always prints 8 bytes */
+
+  /* parse options */
+  memset(coap_pkt->options, 0, sizeof(coap_pkt->options));
+  current_option += coap_pkt->token_len;
+
+  unsigned int option_number = 0;
+  unsigned int option_delta = 0;
+  size_t option_length = 0;
+
+  while (current_option < data + data_len) {
+    /* payload marker 0xFF, currently only checking for 0xF* because rest is
+     * reserved */
+    if ((current_option[0] & 0xF0) == 0xF0) {
+      coap_pkt->payload = ++current_option;
+      coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
+
+      /* also for receiving, the Erbium upper bound is MAX_PAYLOAD_SIZE */
+      if (coap_pkt->payload_len > MAX_PAYLOAD_SIZE) {
+        coap_pkt->payload_len = MAX_PAYLOAD_SIZE;
+        /* null-terminate payload */
+      }
+      coap_pkt->payload[coap_pkt->payload_len] = '\0';
+
+      break;
+    }
+
+    option_delta = current_option[0] >> 4;
+    option_length = current_option[0] & 0x0F;
+    ++current_option;
+
+    if (option_delta == 13) {
+      option_delta += current_option[0];
+      ++current_option;
+    } else if (option_delta == 14) {
+      option_delta += 255;
+      option_delta += current_option[0] << 8;
+      ++current_option;
+      option_delta += current_option[0];
+      ++current_option;
+    }
+
+    if (option_length == 13) {
+      option_length += current_option[0];
+      ++current_option;
+    } else if (option_length == 14) {
+      option_length += 255;
+      option_length += current_option[0] << 8;
+      ++current_option;
+      option_length += current_option[0];
+      ++current_option;
+    }
+
+    option_number += option_delta;
+
+    if (option_number < COAP_OPTION_SIZE1) {
+      LOG("OPTION %u (delta %u, len %zu): ", option_number, option_delta,
+          option_length);
+      SET_OPTION(coap_pkt, option_number);
+    }
+
+    switch (option_number) {
+    case COAP_OPTION_CONTENT_FORMAT:
+      coap_pkt->content_format =
+        coap_parse_int_option(current_option, option_length);
+      LOG("Content-Format [%u]\n", coap_pkt->content_format);
+      break;
+    case COAP_OPTION_MAX_AGE:
+      coap_pkt->max_age = coap_parse_int_option(current_option, option_length);
+      LOG("Max-Age [%lu]\n", (unsigned long)coap_pkt->max_age);
+      break;
+#if 0
+    case COAP_OPTION_ETAG:
+      coap_pkt->etag_len = MIN(COAP_ETAG_LEN,
+			       option_length);
+      memcpy(coap_pkt->etag, current_option,
+	     coap_pkt->etag_len);
+      LOG("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
+	  coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
+	  coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
+	  coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
+	 ); /*FIXME always prints 8 bytes */
+      break;
+#endif
+    case COAP_OPTION_ACCEPT:
+      coap_pkt->accept = coap_parse_int_option(current_option, option_length);
+      LOG("Accept [%u]\n", coap_pkt->accept);
+      break;
+#if 0
+    case COAP_OPTION_IF_MATCH:
+      /* TODO support multiple ETags */
+      coap_pkt->if_match_len = MIN(COAP_ETAG_LEN,
+				   option_length);
+      memcpy(coap_pkt->if_match, current_option,
+	     coap_pkt->if_match_len);
+      LOG("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
+	  coap_pkt->if_match_len, coap_pkt->if_match[0],
+	  coap_pkt->if_match[1], coap_pkt->if_match[2],
+	  coap_pkt->if_match[3], coap_pkt->if_match[4],
+	  coap_pkt->if_match[5], coap_pkt->if_match[6],
+	  coap_pkt->if_match[7]
+	 ); /* FIXME always prints 8 bytes */
+      break;
+    case COAP_OPTION_IF_NONE_MATCH:
+      coap_pkt->if_none_match = 1;
+      LOG("If-None-Match\n");
+      break;
+
+    case COAP_OPTION_PROXY_URI:
+#if COAP_PROXY_OPTION_PROCESSING
+      coap_pkt->proxy_uri = (char *)current_option;
+      coap_pkt->proxy_uri_len = option_length;
+#endif
+      LOG("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", (int)coap_pkt->proxy_uri_len,
+	  coap_pkt->proxy_uri);
+      coap_error_message =
+	"This is a constrained server (Contiki)";
+      return PROXYING_NOT_SUPPORTED_5_05;
+      break;
+    case COAP_OPTION_PROXY_SCHEME:
+#if COAP_PROXY_OPTION_PROCESSING
+      coap_pkt->proxy_scheme = (char *)current_option;
+      coap_pkt->proxy_scheme_len = option_length;
+#endif
+      LOG("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
+	  (int)coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
+      coap_error_message =
+	"This is a constrained server (Contiki)";
+      return PROXYING_NOT_SUPPORTED_5_05;
+      break;
+
+    case COAP_OPTION_URI_HOST:
+      coap_pkt->uri_host = (char *)current_option;
+      coap_pkt->uri_host_len = option_length;
+      LOG("Uri-Host [%.*s]\n", (int)coap_pkt->uri_host_len,
+	  coap_pkt->uri_host);
+      break;
+    case COAP_OPTION_URI_PORT:
+      coap_pkt->uri_port = coap_parse_int_option(
+	current_option, option_length);
+      LOG("Uri-Port [%u]\n", coap_pkt->uri_port);
+      break;
+#endif
+    case COAP_OPTION_URI_PATH:
+      /* coap_merge_multi_option() operates in-place on the IPBUF, but final
+       * packet field should be const string -> cast to string */
+      coap_merge_multi_option((char **)&(coap_pkt->uri_path),
+                              &(coap_pkt->uri_path_len), current_option,
+                              option_length, '/');
+      LOG("Uri-Path [%.*s]\n", (int)coap_pkt->uri_path_len, coap_pkt->uri_path);
+      break;
+    case COAP_OPTION_URI_QUERY:
+      /* coap_merge_multi_option() operates in-place on the IPBUF, but final
+       * packet field should be const string -> cast to string */
+      coap_merge_multi_option((char **)&(coap_pkt->uri_query),
+                              &(coap_pkt->uri_query_len), current_option,
+                              option_length, '&');
+      LOG("Uri-Query [%.*s]\n", (int)coap_pkt->uri_query_len,
+          coap_pkt->uri_query);
+      break;
+#if 0
+    case COAP_OPTION_LOCATION_PATH:
+      /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
+      coap_merge_multi_option(
+	(char **)&(coap_pkt->location_path),
+	&(coap_pkt->location_path_len),
+	current_option, option_length,
+	'/');
+      LOG("Location-Path [%.*s]\n", (int)coap_pkt->location_path_len,
+	  coap_pkt->location_path);
+      break;
+    case COAP_OPTION_LOCATION_QUERY:
+      /* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
+      coap_merge_multi_option(
+	(char **)&(coap_pkt->location_query),
+	&(coap_pkt->location_query_len),
+	current_option, option_length,
+	'&');
+      LOG("Location-Query [%.*s]\n", (int)coap_pkt->location_query_len,
+	  coap_pkt->location_query);
+      break;
+#endif
+    case COAP_OPTION_OBSERVE:
+      coap_pkt->observe = coap_parse_int_option(current_option, option_length);
+      LOG("Observe [%lu]\n", (unsigned long)coap_pkt->observe);
+      break;
+    case COAP_OPTION_BLOCK2:
+      coap_pkt->block2_num =
+        coap_parse_int_option(current_option, option_length);
+      coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
+      coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
+      coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
+                                << (coap_pkt->block2_num & 0x07);
+      coap_pkt->block2_num >>= 4;
+      LOG("Block2 [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->block2_num,
+          coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
+      break;
+    case COAP_OPTION_BLOCK1:
+      coap_pkt->block1_num =
+        coap_parse_int_option(current_option, option_length);
+      coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
+      coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
+      coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
+                                << (coap_pkt->block1_num & 0x07);
+      coap_pkt->block1_num >>= 4;
+      LOG("Block1 [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->block1_num,
+          coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
+      break;
+    case COAP_OPTION_SIZE2:
+      coap_pkt->size2 = coap_parse_int_option(current_option, option_length);
+      LOG("Size2 [%lu]\n", (unsigned long)coap_pkt->size2);
+      break;
+    case COAP_OPTION_SIZE1:
+      coap_pkt->size1 = coap_parse_int_option(current_option, option_length);
+      LOG("Size1 [%lu]\n", (unsigned long)coap_pkt->size1);
+      break;
+    default:
+      LOG("unknown (%u)\n", option_number);
+      /* check if critical (odd) */
+      if (option_number & 1) {
+        coap_error_message = "Unsupported critical option";
+        return BAD_OPTION_4_02;
+      }
+    }
+    current_option += option_length;
+  } /* for */
+  LOG("-Done parsing-------\n");
+
+  return NO_ERROR;
+}
+#if 0
+int
+coap_get_query_variable(void *packet, const char *name, const char **output)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if(IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
+    return coap_get_variable(coap_pkt->uri_query, coap_pkt->uri_query_len,
+			     name, output);
+  }
+  return 0;
+}
+int
+coap_get_post_variable(void *packet, const char *name, const char **output)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if(coap_pkt->payload_len) {
+    return coap_get_variable((const char *)coap_pkt->payload,
+			     coap_pkt->payload_len, name, output);
+  }
+  return 0;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+int
+coap_set_status_code(void *packet, unsigned int code)
+{
+  if (code <= 0xFF) {
+    ((coap_packet_t *)packet)->code = (uint8_t)code;
+    return 1;
+  } else {
+    return 0;
+  }
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_set_token(void *packet, const uint8_t *token, size_t token_len)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->token_len = MIN(COAP_TOKEN_LEN, token_len);
+  memcpy(coap_pkt->token, token, coap_pkt->token_len);
+
+  return coap_pkt->token_len;
+}
+#ifdef OC_CLIENT
+int
+coap_get_header_content_format(void *packet, unsigned int *format)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT)) {
+    return 0;
+  }
+  *format = coap_pkt->content_format;
+  return 1;
+}
+#endif
+int
+coap_set_header_content_format(void *packet, unsigned int format)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->content_format = format;
+  SET_OPTION(coap_pkt, COAP_OPTION_CONTENT_FORMAT);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+#if 0
+int coap_get_header_accept(void *packet, unsigned int *accept)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_ACCEPT)) {
+    return 0;
+  }
+  *accept = coap_pkt->accept;
+  return 1;
+}
+#endif
+#ifdef OC_CLIENT
+int
+coap_set_header_accept(void *packet, unsigned int accept)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->accept = accept;
+  SET_OPTION(coap_pkt, COAP_OPTION_ACCEPT);
+  return 1;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+#if 0
+int coap_get_header_max_age(void *packet, uint32_t *age)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_MAX_AGE)) {
+    *age = COAP_DEFAULT_MAX_AGE;
+  } else {
+    *age = coap_pkt->max_age;
+  }
+  return 1;
+}
+#endif
+int
+coap_set_header_max_age(void *packet, uint32_t age)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->max_age = age;
+  SET_OPTION(coap_pkt, COAP_OPTION_MAX_AGE);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+#if 0
+int coap_get_header_etag(void *packet, const uint8_t **etag)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_ETAG)) {
+    return 0;
+  }
+  *etag = coap_pkt->etag;
+  return coap_pkt->etag_len;
+}
+int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->etag_len = MIN(COAP_ETAG_LEN, etag_len);
+  memcpy(coap_pkt->etag, etag, coap_pkt->etag_len);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_ETAG);
+  return coap_pkt->etag_len;
+}
+/*---------------------------------------------------------------------------*/
+/*FIXME support multiple ETags */
+int coap_get_header_if_match(void *packet, const uint8_t **etag)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_IF_MATCH)) {
+    return 0;
+  }
+  *etag = coap_pkt->if_match;
+  return coap_pkt->if_match_len;
+}
+int coap_set_header_if_match(void *packet, const uint8_t *etag, size_t etag_len)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, etag_len);
+  memcpy(coap_pkt->if_match, etag, coap_pkt->if_match_len);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_IF_MATCH);
+  return coap_pkt->if_match_len;
+}
+/*---------------------------------------------------------------------------*/
+int coap_get_header_if_none_match(void *packet)
+{
+  return IS_OPTION((coap_packet_t *)packet,
+		   COAP_OPTION_IF_NONE_MATCH) ? 1 : 0;
+}
+int coap_set_header_if_none_match(void *packet)
+{
+  SET_OPTION((coap_packet_t * )packet, COAP_OPTION_IF_NONE_MATCH);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+int coap_get_header_proxy_uri(void *packet, const char **uri)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_PROXY_URI)) {
+    return 0;
+  }
+  *uri = coap_pkt->proxy_uri;
+  return coap_pkt->proxy_uri_len;
+}
+int coap_set_header_proxy_uri(void *packet, const char *uri)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  /*TODO Provide alternative that sets Proxy-Scheme and Uri-* options and provide er-coap-conf define */
+
+  coap_pkt->proxy_uri = uri;
+  coap_pkt->proxy_uri_len = strlen(uri);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_PROXY_URI);
+  return coap_pkt->proxy_uri_len;
+}
+/*---------------------------------------------------------------------------*/
+int coap_get_header_uri_host(void *packet, const char **host)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_URI_HOST)) {
+    return 0;
+  }
+  *host = coap_pkt->uri_host;
+  return coap_pkt->uri_host_len;
+}
+int coap_set_header_uri_host(void *packet, const char *host)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->uri_host = host;
+  coap_pkt->uri_host_len = strlen(host);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_URI_HOST);
+  return coap_pkt->uri_host_len;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+int
+coap_get_header_uri_path(void *packet, const char **path)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_PATH)) {
+    return 0;
+  }
+  *path = coap_pkt->uri_path;
+  return coap_pkt->uri_path_len;
+}
+#ifdef OC_CLIENT
+int
+coap_set_header_uri_path(void *packet, const char *path)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  while (path[0] == '/')
+    ++path;
+
+  coap_pkt->uri_path = path;
+  coap_pkt->uri_path_len = strlen(path);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_URI_PATH);
+  return coap_pkt->uri_path_len;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+int
+coap_get_header_uri_query(void *packet, const char **query)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_URI_QUERY)) {
+    return 0;
+  }
+  *query = coap_pkt->uri_query;
+  return coap_pkt->uri_query_len;
+}
+#ifdef OC_CLIENT
+int
+coap_set_header_uri_query(void *packet, const char *query)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  while (query[0] == '?')
+    ++query;
+
+  coap_pkt->uri_query = query;
+  coap_pkt->uri_query_len = strlen(query);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+  return coap_pkt->uri_query_len;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+#if 0
+int coap_get_header_location_path(void *packet, const char **path)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH)) {
+    return 0;
+  }
+  *path = coap_pkt->location_path;
+  return coap_pkt->location_path_len;
+}
+int coap_set_header_location_path(void *packet, const char *path)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  char *query;
+
+  while(path[0] == '/')
+    ++path;
+
+  if((query = strchr(path, '?'))) {
+    coap_set_header_location_query(packet, query + 1);
+    coap_pkt->location_path_len = query - path;
+  } else {
+    coap_pkt->location_path_len = strlen(path);
+  }
+  coap_pkt->location_path = path;
+
+  if(coap_pkt->location_path_len > 0) {
+    SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_PATH);
+  }
+  return coap_pkt->location_path_len;
+}
+/*---------------------------------------------------------------------------*/
+int coap_get_header_location_query(void *packet, const char **query)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY)) {
+    return 0;
+  }
+  *query = coap_pkt->location_query;
+  return coap_pkt->location_query_len;
+}
+#endif
+int
+coap_set_header_location_query(void *packet, const char *query)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  while (query[0] == '?')
+    ++query;
+
+  coap_pkt->location_query = query;
+  coap_pkt->location_query_len = strlen(query);
+
+  SET_OPTION(coap_pkt, COAP_OPTION_LOCATION_QUERY);
+  return coap_pkt->location_query_len;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_get_header_observe(void *packet, uint32_t *observe)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_OBSERVE)) {
+    return 0;
+  }
+  *observe = coap_pkt->observe;
+  return 1;
+}
+int
+coap_set_header_observe(void *packet, uint32_t observe)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->observe = observe;
+  SET_OPTION(coap_pkt, COAP_OPTION_OBSERVE);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
+                       uint16_t *size, uint32_t *offset)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK2)) {
+    return 0;
+  }
+  /* pointers may be NULL to get only specific block parameters */
+  if (num != NULL) {
+    *num = coap_pkt->block2_num;
+  }
+  if (more != NULL) {
+    *more = coap_pkt->block2_more;
+  }
+  if (size != NULL) {
+    *size = coap_pkt->block2_size;
+  }
+  if (offset != NULL) {
+    *offset = coap_pkt->block2_offset;
+  }
+  return 1;
+}
+int
+coap_set_header_block2(void *packet, uint32_t num, uint8_t more, uint16_t size)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (size < 16) {
+    return 0;
+  }
+  if (size > 2048) {
+    return 0;
+  }
+  if (num > 0x0FFFFF) {
+    return 0;
+  }
+  coap_pkt->block2_num = num;
+  coap_pkt->block2_more = more ? 1 : 0;
+  coap_pkt->block2_size = size;
+
+  SET_OPTION(coap_pkt, COAP_OPTION_BLOCK2);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+int
+coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
+                       uint16_t *size, uint32_t *offset)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (!IS_OPTION(coap_pkt, COAP_OPTION_BLOCK1)) {
+    return 0;
+  }
+  /* pointers may be NULL to get only specific block parameters */
+  if (num != NULL) {
+    *num = coap_pkt->block1_num;
+  }
+  if (more != NULL) {
+    *more = coap_pkt->block1_more;
+  }
+  if (size != NULL) {
+    *size = coap_pkt->block1_size;
+  }
+  if (offset != NULL) {
+    *offset = coap_pkt->block1_offset;
+  }
+  return 1;
+}
+int
+coap_set_header_block1(void *packet, uint32_t num, uint8_t more, uint16_t size)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (size < 16) {
+    return 0;
+  }
+  if (size > 2048) {
+    return 0;
+  }
+  if (num > 0x0FFFFF) {
+    return 0;
+  }
+  coap_pkt->block1_num = num;
+  coap_pkt->block1_more = more;
+  coap_pkt->block1_size = size;
+
+  SET_OPTION(coap_pkt, COAP_OPTION_BLOCK1);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+#if 0
+int coap_get_header_size2(void *packet, uint32_t *size)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE2)) {
+    return 0;
+  }
+  *size = coap_pkt->size2;
+  return 1;
+}
+int coap_set_header_size2(void *packet, uint32_t size)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->size2 = size;
+  SET_OPTION(coap_pkt, COAP_OPTION_SIZE2);
+  return 1;
+}
+/*---------------------------------------------------------------------------*/
+int coap_get_header_size1(void *packet, uint32_t *size)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  if(!IS_OPTION(coap_pkt, COAP_OPTION_SIZE1)) {
+    return 0;
+  }
+  *size = coap_pkt->size1;
+  return 1;
+}
+int coap_set_header_size1(void *packet, uint32_t size)
+{
+  coap_packet_t * const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->size1 = size;
+  SET_OPTION(coap_pkt, COAP_OPTION_SIZE1);
+  return 1;
+}
+#endif
+/*---------------------------------------------------------------------------*/
+int
+coap_get_payload(void *packet, const uint8_t **payload)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  if (coap_pkt->payload) {
+    *payload = coap_pkt->payload;
+    return coap_pkt->payload_len;
+  } else {
+    *payload = NULL;
+    return 0;
+  }
+}
+int
+coap_set_payload(void *packet, const void *payload, size_t length)
+{
+  coap_packet_t *const coap_pkt = (coap_packet_t *)packet;
+
+  coap_pkt->payload = (uint8_t *)payload;
+  coap_pkt->payload_len = MIN(MAX_PAYLOAD_SIZE, length);
+
+  return coap_pkt->payload_len;
+}
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/coap.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/coap.h b/libs/iotivity/src/messaging/coap/coap.h
new file mode 100644
index 0000000..b61b759
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/coap.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef COAP_H
+#define COAP_H
+
+#include "conf.h"
+#include "constants.h"
+#include <stddef.h> /* for size_t */
+#include <stdint.h>
+
+/* OIC stack headers */
+#include "config.h"
+#include "oc_buffer.h"
+#include "port/oc_connectivity.h"
+#include "port/oc_log.h"
+#include "port/oc_random.h"
+
+#ifndef MAX
+#define MAX(n, m) (((n) < (m)) ? (m) : (n))
+#endif
+
+#ifndef MIN
+#define MIN(n, m) (((n) < (m)) ? (n) : (m))
+#endif
+
+#ifndef ABS
+#define ABS(n) (((n) < 0) ? -(n) : (n))
+#endif
+
+#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + MAX_PAYLOAD_SIZE)
+
+/* MAX_PAYLOAD_SIZE can be different from 2^x so we need to get next lower 2^x
+ * for COAP_MAX_BLOCK_SIZE */
+#ifndef COAP_MAX_BLOCK_SIZE
+#define COAP_MAX_BLOCK_SIZE                                                    \
+  (MAX_PAYLOAD_SIZE < 32                                                       \
+     ? 16                                                                      \
+     : (MAX_PAYLOAD_SIZE < 64                                                  \
+          ? 32                                                                 \
+          : (MAX_PAYLOAD_SIZE < 128                                            \
+               ? 64                                                            \
+               : (MAX_PAYLOAD_SIZE < 256                                       \
+                    ? 128                                                      \
+                    : (MAX_PAYLOAD_SIZE < 512                                  \
+                         ? 256                                                 \
+                         : (MAX_PAYLOAD_SIZE < 1024                            \
+                              ? 512                                            \
+                              : (MAX_PAYLOAD_SIZE < 2048 ? 1024 : 2048)))))))
+#endif /* COAP_MAX_BLOCK_SIZE */
+
+/* bitmap for set options */
+enum
+{
+  OPTION_MAP_SIZE = sizeof(uint8_t) * 8
+};
+
+#define SET_OPTION(packet, opt)                                                \
+  ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))
+#define IS_OPTION(packet, opt)                                                 \
+  ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
+
+/* parsed message struct */
+typedef struct
+{
+  uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory
+                      to serialize packet */
+
+  uint8_t version;
+  coap_message_type_t type;
+  uint8_t code;
+  uint16_t mid;
+
+  uint8_t token_len;
+  uint8_t token[COAP_TOKEN_LEN];
+
+  uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE +
+                  1]; /* bitmap to check if option is set */
+
+  uint16_t content_format; /* parse options once and store; allows setting
+                              options in random order  */
+  uint32_t max_age;
+  uint8_t etag_len;
+  uint8_t etag[COAP_ETAG_LEN];
+  size_t proxy_uri_len;
+  const char *proxy_uri;
+  size_t proxy_scheme_len;
+  const char *proxy_scheme;
+  size_t uri_host_len;
+  const char *uri_host;
+  size_t location_path_len;
+  const char *location_path;
+  uint16_t uri_port;
+  size_t location_query_len;
+  const char *location_query;
+  size_t uri_path_len;
+  const char *uri_path;
+  int32_t observe;
+  uint16_t accept;
+  uint8_t if_match_len;
+  uint8_t if_match[COAP_ETAG_LEN];
+  uint32_t block2_num;
+  uint8_t block2_more;
+  uint16_t block2_size;
+  uint32_t block2_offset;
+  uint32_t block1_num;
+  uint8_t block1_more;
+  uint16_t block1_size;
+  uint32_t block1_offset;
+  uint32_t size2;
+  uint32_t size1;
+  size_t uri_query_len;
+  const char *uri_query;
+  uint8_t if_none_match;
+
+  uint16_t payload_len;
+  uint8_t *payload;
+} coap_packet_t;
+
+/* option format serialization */
+#define COAP_SERIALIZE_INT_OPTION(number, field, text)                         \
+  if (IS_OPTION(coap_pkt, number)) {                                           \
+    LOG(text " [%u]\n", (unsigned int)coap_pkt->field);                        \
+    option += coap_serialize_int_option(number, current_number, option,        \
+                                        coap_pkt->field);                      \
+    current_number = number;                                                   \
+  }
+#define COAP_SERIALIZE_BYTE_OPTION(number, field, text)                        \
+  if (IS_OPTION(coap_pkt, number)) {                                           \
+    LOG(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",                     \
+        (unsigned int)coap_pkt->field##_len, coap_pkt->field[0],               \
+        coap_pkt->field[1], coap_pkt->field[2], coap_pkt->field[3],            \
+        coap_pkt->field[4], coap_pkt->field[5], coap_pkt->field[6],            \
+        coap_pkt->field[7]); /* FIXME always prints 8 bytes */                 \
+    option += coap_serialize_array_option(number, current_number, option,      \
+                                          coap_pkt->field,                     \
+                                          coap_pkt->field##_len, '\0');        \
+    current_number = number;                                                   \
+  }
+#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text)            \
+  if (IS_OPTION(coap_pkt, number)) {                                           \
+    LOG(text " [%.*s]\n", (int)coap_pkt->field##_len, coap_pkt->field);        \
+    option += coap_serialize_array_option(number, current_number, option,      \
+                                          (uint8_t *)coap_pkt->field,          \
+                                          coap_pkt->field##_len, splitter);    \
+    current_number = number;                                                   \
+  }
+#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text)                       \
+  if (IS_OPTION(coap_pkt, number)) {                                           \
+    LOG(text " [%lu%s (%u B/blk)]\n", (unsigned long)coap_pkt->field##_num,    \
+        coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size);            \
+    uint32_t block = coap_pkt->field##_num << 4;                               \
+    if (coap_pkt->field##_more) {                                              \
+      block |= 0x8;                                                            \
+    }                                                                          \
+    block |= 0xF & coap_log_2(coap_pkt->field##_size / 16);                    \
+    LOG(text " encoded: 0x%lX\n", (unsigned long)block);                       \
+    option +=                                                                  \
+      coap_serialize_int_option(number, current_number, option, block);        \
+    current_number = number;                                                   \
+  }
+
+/* to store error code and human-readable payload */
+extern coap_status_t erbium_status_code;
+extern char *coap_error_message;
+
+void coap_init_connection(void);
+uint16_t coap_get_mid(void);
+
+void coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
+                       uint16_t mid);
+size_t coap_serialize_message(void *packet, uint8_t *buffer);
+void coap_send_message(oc_message_t *message);
+coap_status_t coap_parse_message(void *request, uint8_t *data,
+                                 uint16_t data_len);
+
+int coap_get_query_variable(void *packet, const char *name,
+                            const char **output);
+int coap_get_post_variable(void *packet, const char *name, const char **output);
+
+/*---------------------------------------------------------------------------*/
+
+int coap_set_status_code(void *packet, unsigned int code);
+
+int coap_set_token(void *packet, const uint8_t *token, size_t token_len);
+
+int coap_get_header_content_format(void *packet, unsigned int *format);
+int coap_set_header_content_format(void *packet, unsigned int format);
+
+int coap_get_header_accept(void *packet, unsigned int *accept);
+int coap_set_header_accept(void *packet, unsigned int accept);
+
+int coap_get_header_max_age(void *packet, uint32_t *age);
+int coap_set_header_max_age(void *packet, uint32_t age);
+
+int coap_get_header_etag(void *packet, const uint8_t **etag);
+int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len);
+
+int coap_get_header_if_match(void *packet, const uint8_t **etag);
+int coap_set_header_if_match(void *packet, const uint8_t *etag,
+                             size_t etag_len);
+
+int coap_get_header_if_none_match(void *packet);
+int coap_set_header_if_none_match(void *packet);
+
+int coap_get_header_proxy_uri(
+  void *packet,
+  const char **uri); /* in-place string might not be 0-terminated. */
+int coap_set_header_proxy_uri(void *packet, const char *uri);
+
+int coap_get_header_proxy_scheme(
+  void *packet,
+  const char **scheme); /* in-place string might not be 0-terminated. */
+int coap_set_header_proxy_scheme(void *packet, const char *scheme);
+
+int coap_get_header_uri_host(
+  void *packet,
+  const char **host); /* in-place string might not be 0-terminated. */
+int coap_set_header_uri_host(void *packet, const char *host);
+
+int coap_get_header_uri_path(
+  void *packet,
+  const char **path); /* in-place string might not be 0-terminated. */
+int coap_set_header_uri_path(void *packet, const char *path);
+
+int coap_get_header_uri_query(
+  void *packet,
+  const char **query); /* in-place string might not be 0-terminated. */
+int coap_set_header_uri_query(void *packet, const char *query);
+
+int coap_get_header_location_path(
+  void *packet,
+  const char **path); /* in-place string might not be 0-terminated. */
+int coap_set_header_location_path(void *packet,
+                                  const char *path); /* also splits optional
+                                                        query into
+                                                        Location-Query option.
+                                                        */
+
+int coap_get_header_location_query(
+  void *packet,
+  const char **query); /* in-place string might not be 0-terminated. */
+int coap_set_header_location_query(void *packet, const char *query);
+
+int coap_get_header_observe(void *packet, uint32_t *observe);
+int coap_set_header_observe(void *packet, uint32_t observe);
+
+int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
+                           uint16_t *size, uint32_t *offset);
+int coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
+                           uint16_t size);
+
+int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
+                           uint16_t *size, uint32_t *offset);
+int coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
+                           uint16_t size);
+
+int coap_get_header_size2(void *packet, uint32_t *size);
+int coap_set_header_size2(void *packet, uint32_t size);
+
+int coap_get_header_size1(void *packet, uint32_t *size);
+int coap_set_header_size1(void *packet, uint32_t size);
+
+int coap_get_payload(void *packet, const uint8_t **payload);
+int coap_set_payload(void *packet, const void *payload, size_t length);
+
+#endif /* COAP_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/conf.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/conf.h b/libs/iotivity/src/messaging/coap/conf.h
new file mode 100644
index 0000000..4e2c878
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/conf.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef CONF_H
+#define CONF_H
+
+#include "config.h"
+
+/* Features that can be disabled to achieve smaller memory footprint */
+#define COAP_LINK_FORMAT_FILTERING 0
+#define COAP_PROXY_OPTION_PROCESSING 0
+
+/* The number of concurrent messages that can be stored for retransmission in
+ * the transaction layer. */
+#ifndef COAP_MAX_OPEN_TRANSACTIONS
+#define COAP_MAX_OPEN_TRANSACTIONS (MAX_NUM_CONCURRENT_REQUESTS)
+#endif /* COAP_MAX_OPEN_TRANSACTIONS */
+
+/* Maximum number of failed request attempts before action */
+#ifndef COAP_MAX_ATTEMPTS
+#define COAP_MAX_ATTEMPTS 2
+#endif /* COAP_MAX_ATTEMPTS */
+
+/* Conservative size limit, as not all options have to be set at the same time.
+ * Check when Proxy-Uri option is used */
+#ifndef COAP_MAX_HEADER_SIZE /*     Hdr                  CoF  If-Match         \
+                                Obs Blo strings   */
+#define COAP_MAX_HEADER_SIZE                                                   \
+  (4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
+#endif /* COAP_MAX_HEADER_SIZE */
+
+/* Number of observer slots (each takes abot xxx bytes) */
+#ifndef COAP_MAX_OBSERVERS
+#define COAP_MAX_OBSERVERS (MAX_APP_RESOURCES + MAX_NUM_CONCURRENT_REQUESTS)
+#endif /* COAP_MAX_OBSERVERS */
+
+/* Interval in notifies in which NON notifies are changed to CON notifies to
+ * check client. */
+#define COAP_OBSERVE_REFRESH_INTERVAL 20
+
+#endif /* CONF_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/constants.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/constants.h b/libs/iotivity/src/messaging/coap/constants.h
new file mode 100644
index 0000000..9e9f3b3
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/constants.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#define COAP_DEFAULT_PORT 5683
+
+#define COAP_DEFAULT_MAX_AGE 60
+#define COAP_RESPONSE_TIMEOUT 2
+#define COAP_RESPONSE_RANDOM_FACTOR 1.5
+#define COAP_MAX_RETRANSMIT 4
+
+#define COAP_HEADER_LEN                                                        \
+  4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
+#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
+#define COAP_ETAG_LEN 8  /* The maximum number of bytes for the ETag */
+
+#define COAP_HEADER_VERSION_MASK 0xC0
+#define COAP_HEADER_VERSION_POSITION 6
+#define COAP_HEADER_TYPE_MASK 0x30
+#define COAP_HEADER_TYPE_POSITION 4
+#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
+#define COAP_HEADER_TOKEN_LEN_POSITION 0
+
+#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
+#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
+
+/* CoAP message types */
+typedef enum {
+  COAP_TYPE_CON, /* confirmables */
+  COAP_TYPE_NON, /* non-confirmables */
+  COAP_TYPE_ACK, /* acknowledgements */
+  COAP_TYPE_RST  /* reset */
+} coap_message_type_t;
+
+/* CoAP request method codes */
+typedef enum { COAP_GET = 1, COAP_POST, COAP_PUT, COAP_DELETE } coap_method_t;
+
+/* CoAP response codes */
+typedef enum {
+  NO_ERROR = 0,
+
+  CREATED_2_01 = 65,  /* CREATED */
+  DELETED_2_02 = 66,  /* DELETED */
+  VALID_2_03 = 67,    /* NOT_MODIFIED */
+  CHANGED_2_04 = 68,  /* CHANGED */
+  CONTENT_2_05 = 69,  /* OK */
+  CONTINUE_2_31 = 95, /* CONTINUE */
+
+  BAD_REQUEST_4_00 = 128,              /* BAD_REQUEST */
+  UNAUTHORIZED_4_01 = 129,             /* UNAUTHORIZED */
+  BAD_OPTION_4_02 = 130,               /* BAD_OPTION */
+  FORBIDDEN_4_03 = 131,                /* FORBIDDEN */
+  NOT_FOUND_4_04 = 132,                /* NOT_FOUND */
+  METHOD_NOT_ALLOWED_4_05 = 133,       /* METHOD_NOT_ALLOWED */
+  NOT_ACCEPTABLE_4_06 = 134,           /* NOT_ACCEPTABLE */
+  PRECONDITION_FAILED_4_12 = 140,      /* BAD_REQUEST */
+  REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
+  UNSUPPORTED_MEDIA_TYPE_4_15 = 143,   /* UNSUPPORTED_MEDIA_TYPE */
+
+  INTERNAL_SERVER_ERROR_5_00 = 160,  /* INTERNAL_SERVER_ERROR */
+  NOT_IMPLEMENTED_5_01 = 161,        /* NOT_IMPLEMENTED */
+  BAD_GATEWAY_5_02 = 162,            /* BAD_GATEWAY */
+  SERVICE_UNAVAILABLE_5_03 = 163,    /* SERVICE_UNAVAILABLE */
+  GATEWAY_TIMEOUT_5_04 = 164,        /* GATEWAY_TIMEOUT */
+  PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
+
+  /* Erbium errors */
+  MEMORY_ALLOCATION_ERROR = 192,
+  PACKET_SERIALIZATION_ERROR,
+
+  /* Erbium hooks */
+  CLEAR_TRANSACTION,
+  EMPTY_ACK_RESPONSE
+} coap_status_t;
+
+/* CoAP header option numbers */
+typedef enum {
+  COAP_OPTION_IF_MATCH = 1,        /* 0-8 B */
+  COAP_OPTION_URI_HOST = 3,        /* 1-255 B */
+  COAP_OPTION_ETAG = 4,            /* 1-8 B */
+  COAP_OPTION_IF_NONE_MATCH = 5,   /* 0 B */
+  COAP_OPTION_OBSERVE = 6,         /* 0-3 B */
+  COAP_OPTION_URI_PORT = 7,        /* 0-2 B */
+  COAP_OPTION_LOCATION_PATH = 8,   /* 0-255 B */
+  COAP_OPTION_URI_PATH = 11,       /* 0-255 B */
+  COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
+  COAP_OPTION_MAX_AGE = 14,        /* 0-4 B */
+  COAP_OPTION_URI_QUERY = 15,      /* 0-255 B */
+  COAP_OPTION_ACCEPT = 17,         /* 0-2 B */
+  COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
+  COAP_OPTION_BLOCK2 = 23,         /* 1-3 B */
+  COAP_OPTION_BLOCK1 = 27,         /* 1-3 B */
+  COAP_OPTION_SIZE2 = 28,          /* 0-4 B */
+  COAP_OPTION_PROXY_URI = 35,      /* 1-1034 B */
+  COAP_OPTION_PROXY_SCHEME = 39,   /* 1-255 B */
+  COAP_OPTION_SIZE1 = 60,          /* 0-4 B */
+} coap_option_t;
+
+/* CoAP Content-Formats */
+typedef enum {
+  TEXT_PLAIN = 0,
+  TEXT_XML = 1,
+  TEXT_CSV = 2,
+  TEXT_HTML = 3,
+  IMAGE_GIF = 21,
+  IMAGE_JPEG = 22,
+  IMAGE_PNG = 23,
+  IMAGE_TIFF = 24,
+  AUDIO_RAW = 25,
+  VIDEO_RAW = 26,
+  APPLICATION_LINK_FORMAT = 40,
+  APPLICATION_XML = 41,
+  APPLICATION_OCTET_STREAM = 42,
+  APPLICATION_RDF_XML = 43,
+  APPLICATION_SOAP_XML = 44,
+  APPLICATION_ATOM_XML = 45,
+  APPLICATION_XMPP_XML = 46,
+  APPLICATION_EXI = 47,
+  APPLICATION_FASTINFOSET = 48,
+  APPLICATION_SOAP_FASTINFOSET = 49,
+  APPLICATION_JSON = 50,
+  APPLICATION_X_OBIX_BINARY = 51,
+  APPLICATION_CBOR = 60
+} coap_content_format_t;
+
+#endif /* CONSTANTS_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/engine.c
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/engine.c b/libs/iotivity/src/messaging/coap/engine.c
new file mode 100644
index 0000000..638541e
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/engine.c
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#include "engine.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* OIC Stack headers */
+#include "api/oc_events.h"
+#include "oc_buffer.h"
+#include "oc_ri.h"
+
+#ifdef OC_CLIENT
+#include "oc_client_state.h"
+#endif
+
+OC_PROCESS(coap_engine, "CoAP Engine");
+
+extern bool oc_ri_invoke_coap_entity_handler(void *request, void *response,
+                                             uint8_t *buffer,
+                                             uint16_t buffer_size,
+                                             int32_t *offset,
+                                             oc_endpoint_t *endpoint);
+
+/*---------------------------------------------------------------------------*/
+/*- Internal API ------------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+int
+coap_receive(oc_message_t *msg)
+{
+  erbium_status_code = NO_ERROR;
+
+  LOG("\n\nCoAP Engine: received datalen=%lu \n", msg->length);
+
+  /* static declaration reduces stack peaks and program code size */
+  static coap_packet_t
+    message[1]; /* this way the packet can be treated as pointer as usual */
+  static coap_packet_t response[1];
+  static coap_transaction_t *transaction = NULL;
+
+  erbium_status_code = coap_parse_message(message, msg->data, msg->length);
+
+  if (erbium_status_code == NO_ERROR) {
+
+/*TODO duplicates suppression, if required by application */
+
+#if DEBUG
+    LOG("  Parsed: CoAP version: %u, token: 0x%02X%02X, mid: %u\n",
+        message->version, message->token[0], message->token[1], message->mid);
+    switch (message->type) {
+    case COAP_TYPE_CON:
+      LOG("  type: CON\n");
+      break;
+    case COAP_TYPE_NON:
+      LOG("  type: NON\n");
+      break;
+    case COAP_TYPE_ACK:
+      LOG("  type: ACK\n");
+      break;
+    case COAP_TYPE_RST:
+      LOG("  type: RST\n");
+      break;
+    default:
+      break;
+    }
+#endif
+
+    /* handle requests */
+    if (message->code >= COAP_GET && message->code <= COAP_DELETE) {
+
+#if DEBUG
+      switch (message->code) {
+      case COAP_GET:
+        LOG("  method: GET\n");
+        break;
+      case COAP_PUT:
+        LOG("  method: PUT\n");
+        break;
+      case COAP_POST:
+        LOG("  method: POST\n");
+        break;
+      case COAP_DELETE:
+        LOG("  method: DELETE\n");
+        break;
+      }
+      LOG("  URL: %.*s\n", (int) message->uri_path_len, message->uri_path);
+      LOG("  Payload: %.*s\n", (int) message->payload_len, message->payload);
+#endif
+      /* use transaction buffer for response to confirmable request */
+      if ((transaction = coap_new_transaction(message->mid, &msg->endpoint))) {
+        uint32_t block_num = 0;
+        uint16_t block_size = COAP_MAX_BLOCK_SIZE;
+        uint32_t block_offset = 0;
+        int32_t new_offset = 0;
+
+        /* prepare response */
+        if (message->type == COAP_TYPE_CON) {
+          /* reliable CON requests are answered with an ACK */
+          coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05,
+                            message->mid);
+        } else {
+          /* unreliable NON requests are answered with a NON as well */
+          coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
+                            coap_get_mid());
+          /* mirror token */
+        }
+        if (message->token_len) {
+          coap_set_token(response, message->token, message->token_len);
+          /* get offset for blockwise transfers */
+        }
+        if (coap_get_header_block2(message, &block_num, NULL, &block_size,
+                                   &block_offset)) {
+          LOG("\tBlockwise: block request %u (%u/%u) @ %u bytes\n", block_num,
+              block_size, COAP_MAX_BLOCK_SIZE, block_offset);
+          block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
+          new_offset = block_offset;
+        }
+
+        /* invoke resource handler in RI layer */
+        if (oc_ri_invoke_coap_entity_handler(
+              message, response,
+              transaction->message->data + COAP_MAX_HEADER_SIZE, block_size,
+              &new_offset, &msg->endpoint)) {
+
+          if (erbium_status_code == NO_ERROR) {
+
+            /* TODO coap_handle_blockwise(request, response, start_offset,
+             * end_offset); */
+
+            /* resource is unaware of Block1 */
+            if (IS_OPTION(message, COAP_OPTION_BLOCK1) &&
+                response->code < BAD_REQUEST_4_00 &&
+                !IS_OPTION(response, COAP_OPTION_BLOCK1)) {
+              LOG("\tBlock1 option NOT IMPLEMENTED\n");
+
+              erbium_status_code = NOT_IMPLEMENTED_5_01;
+              coap_error_message = "NoBlock1Support";
+
+              /* client requested Block2 transfer */
+            } else if (IS_OPTION(message, COAP_OPTION_BLOCK2)) {
+
+              /* unchanged new_offset indicates that resource is unaware of
+               * blockwise transfer */
+              if (new_offset == block_offset) {
+                LOG("\tBlockwise: unaware resource with payload length %u/%u\n",
+                    response->payload_len, block_size);
+                if (block_offset >= response->payload_len) {
+                  LOG("\t\t: block_offset >= response->payload_len\n");
+
+                  response->code = BAD_OPTION_4_02;
+                  coap_set_payload(response, "BlockOutOfScope",
+                                   15); /* a const char str[] and sizeof(str)
+                                           produces larger code size */
+                } else {
+                  coap_set_header_block2(response, block_num,
+                                         response->payload_len - block_offset >
+                                           block_size,
+                                         block_size);
+                  coap_set_payload(
+                    response, response->payload + block_offset,
+                    MIN(response->payload_len - block_offset, block_size));
+                } /* if(valid offset) */
+
+                /* resource provides chunk-wise data */
+              } else {
+                LOG("\tBlockwise: blockwise resource, new offset %d\n",
+                    new_offset);
+                coap_set_header_block2(response, block_num,
+                                       new_offset != -1 ||
+                                         response->payload_len > block_size,
+                                       block_size);
+
+                if (response->payload_len > block_size) {
+                  coap_set_payload(response, response->payload, block_size);
+                }
+              } /* if(resource aware of blockwise) */
+
+              /* Resource requested Block2 transfer */
+            } else if (new_offset != 0) {
+              LOG("\tBlockwise: no block option for blockwise resource, using "
+                  "block size %u\n",
+                  COAP_MAX_BLOCK_SIZE);
+
+              coap_set_header_block2(response, 0, new_offset != -1,
+                                     COAP_MAX_BLOCK_SIZE);
+              coap_set_payload(response, response->payload,
+                               MIN(response->payload_len, COAP_MAX_BLOCK_SIZE));
+            } /* blockwise transfer handling */
+          }   /* no errors/hooks */
+          /* successful service callback */
+          /* serialize response */
+        }
+        if (erbium_status_code == NO_ERROR) {
+          if ((transaction->message->length = coap_serialize_message(
+                 response, transaction->message->data)) == 0) {
+            erbium_status_code = PACKET_SERIALIZATION_ERROR;
+          }
+        }
+      } else {
+        erbium_status_code = SERVICE_UNAVAILABLE_5_03;
+        coap_error_message = "NoFreeTraBuffer";
+      } /* if(transaction buffer) */
+
+      /* handle responses */
+    } else { // Fix this
+      if (message->type == COAP_TYPE_CON) {
+        erbium_status_code = EMPTY_ACK_RESPONSE;
+      } else if (message->type == COAP_TYPE_ACK) {
+        /* transactions are closed through lookup below */
+      } else if (message->type == COAP_TYPE_RST) {
+#ifdef OC_SERVER
+        /* cancel possible subscriptions */
+        coap_remove_observer_by_mid(&msg->endpoint, message->mid);
+#endif
+      }
+
+      /* Open transaction now cleared for ACK since mid matches */
+      if ((transaction = coap_get_transaction_by_mid(message->mid))) {
+        coap_clear_transaction(transaction);
+      }
+      /* if(ACKed transaction) */
+      transaction = NULL;
+
+#ifdef OC_CLIENT // ACKs and RSTs sent to oc_ri.. RSTs cleared, ACKs sent to
+                 // client
+      oc_ri_invoke_client_cb(message, &msg->endpoint);
+#endif
+
+    } /* request or response */
+  }   /* parsed correctly */
+
+  /* if(parsed correctly) */
+  if (erbium_status_code == NO_ERROR) {
+    if (transaction) { // Server transactions sent from here
+      coap_send_transaction(transaction);
+    }
+  } else if (erbium_status_code == CLEAR_TRANSACTION) {
+    LOG("Clearing transaction for manual response");
+    coap_clear_transaction(transaction); // used in server for separate response
+  }
+#ifdef OC_CLIENT
+  else if (erbium_status_code == EMPTY_ACK_RESPONSE) {
+    coap_init_message(message, COAP_TYPE_ACK, 0, message->mid);
+    oc_message_t *response = oc_allocate_message();
+    if (response) {
+      memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
+      response->length = coap_serialize_message(message, response->data);
+      coap_send_message(response);
+    }
+  }
+#endif /* OC_CLIENT */
+#ifdef OC_SERVER
+  else { // framework errors handled here
+    coap_message_type_t reply_type = COAP_TYPE_RST;
+
+    coap_clear_transaction(transaction);
+
+    coap_init_message(message, reply_type, SERVICE_UNAVAILABLE_5_03,
+                      message->mid);
+
+    oc_message_t *response = oc_allocate_message();
+    if (response) {
+      memcpy(&response->endpoint, &msg->endpoint, sizeof(msg->endpoint));
+      response->length = coap_serialize_message(message, response->data);
+      coap_send_message(response);
+    }
+  }
+#endif /* OC_SERVER */
+
+  /* if(new data) */
+  return erbium_status_code;
+}
+/*---------------------------------------------------------------------------*/
+void
+coap_init_engine(void)
+{
+  coap_register_as_transaction_handler();
+}
+/*---------------------------------------------------------------------------*/
+OC_PROCESS_THREAD(coap_engine, ev, data)
+{
+  OC_PROCESS_BEGIN();
+
+  coap_register_as_transaction_handler();
+  coap_init_connection();
+
+  while (1) {
+    OC_PROCESS_YIELD();
+
+    if (ev == oc_events[INBOUND_RI_EVENT]) {
+      coap_receive(data);
+
+      oc_message_unref(data);
+    } else if (ev == OC_PROCESS_EVENT_TIMER) {
+      coap_check_transactions();
+    }
+  }
+
+  OC_PROCESS_END();
+}
+
+/*---------------------------------------------------------------------------*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/ece29bb3/libs/iotivity/src/messaging/coap/engine.h
----------------------------------------------------------------------
diff --git a/libs/iotivity/src/messaging/coap/engine.h b/libs/iotivity/src/messaging/coap/engine.h
new file mode 100644
index 0000000..73b6114
--- /dev/null
+++ b/libs/iotivity/src/messaging/coap/engine.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ */
+
+#ifndef ENGINE_H
+#define ENGINE_H
+
+#include "coap.h"
+#include "observe.h"
+#include "separate.h"
+#include "transactions.h"
+
+OC_PROCESS_NAME(coap_engine);
+
+void coap_init_engine(void);
+/*---------------------------------------------------------------------------*/
+int coap_receive(oc_message_t *message);
+
+#endif /* ENGINE_H */