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 <a...@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_ */