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:55 UTC

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

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;
+}