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(©);
+ if (err)
+ return err;
+ if (!cbor_value_is_text_string(©)) {
+ *result = false;
+ return CborNoError;
+ }
+
+ size_t len = strlen(string);
+ return iterate_string_chunks(©, 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, ©);
+}
+
+#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, ©, 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 */