Commit f2d1d940 authored by Kishen Maloor's avatar Kishen Maloor

Merge branch 'master' into fargo

parents 85f40f1e 29a8f14b
Pipeline #135 passed with stage
in 47 seconds
---
image: gcc
build:
stage: build
before_script:
- apt update && apt -y install make autoconf
script:
- cd port/linux
- make
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -32,7 +32,7 @@ Contents
IoTivity-Lite Architecture
---------------------------------
.. image:: IoTivityLite-Arch.png
.. image:: Architecture.png
:scale: 100%
:alt: IoTivity-Lite Architecture
:align: center
......
......@@ -109,6 +109,7 @@ cloud_deregister_on_reset_internal(oc_cloud_context_t *ctx,
(void)data;
cloud_close_endpoint(ctx->cloud_ep);
memset(ctx->cloud_ep, 0, sizeof(oc_endpoint_t));
ctx->cloud_ep_state = OC_SESSION_DISCONNECTED;
cloud_store_initialize(&ctx->store);
cloud_manager_stop(ctx);
ctx->last_error = 0;
......@@ -152,6 +153,7 @@ oc_cloud_provision_conf_resource(oc_cloud_context_t *ctx, const char *server,
cloud_close_endpoint(ctx->cloud_ep);
memset(ctx->cloud_ep, 0, sizeof(oc_endpoint_t));
ctx->cloud_ep_state = OC_SESSION_DISCONNECTED;
cloud_store_initialize(&ctx->store);
cloud_manager_stop(ctx);
......@@ -183,6 +185,7 @@ cloud_update_by_resource(oc_cloud_context_t *ctx,
{
cloud_close_endpoint(ctx->cloud_ep);
memset(ctx->cloud_ep, 0, sizeof(oc_endpoint_t));
ctx->cloud_ep_state = OC_SESSION_DISCONNECTED;
cloud_store_initialize(&ctx->store);
cloud_manager_stop(ctx);
if (data->auth_provider && data->auth_provider_len) {
......@@ -311,6 +314,7 @@ oc_cloud_manager_stop(oc_cloud_context_t *ctx)
cloud_store_initialize(&ctx->store);
cloud_close_endpoint(ctx->cloud_ep);
memset(ctx->cloud_ep, 0, sizeof(oc_endpoint_t));
ctx->cloud_ep_state = OC_SESSION_DISCONNECTED;
ctx->cloud_manager = false;
return 0;
}
......
......@@ -163,6 +163,7 @@ _register_handler(oc_cloud_context_t *ctx, oc_client_response_t *data)
strcmp(ci_server, value)) {
cloud_close_endpoint(ctx->cloud_ep);
memset(ctx->cloud_ep, 0, sizeof(oc_endpoint_t));
ctx->cloud_ep_state = OC_SESSION_DISCONNECTED;
}
cloud_set_string(&ctx->store.ci_server, value, size);
}
......
......@@ -130,6 +130,13 @@ oc_delete_link(oc_link_t *link)
}
}
static oc_event_callback_retval_t
links_list_notify_collection(void *data)
{
coap_notify_links_list(data);
return OC_EVENT_DONE;
}
void
oc_collection_add_link(oc_resource_t *collection, oc_link_t *link)
{
......@@ -138,6 +145,7 @@ oc_collection_add_link(oc_resource_t *collection, oc_link_t *link)
if (link->resource == collection) {
oc_string_array_add_item(link->rel, "self");
}
oc_set_delayed_callback(collection, links_list_notify_collection, 0);
}
void
......@@ -146,6 +154,7 @@ oc_collection_remove_link(oc_resource_t *collection, oc_link_t *link)
if (collection && link) {
oc_collection_t *c = (oc_collection_t *)collection;
oc_list_remove(c->links, link);
oc_set_delayed_callback(collection, links_list_notify_collection, 0);
}
}
......@@ -377,7 +386,7 @@ oc_get_next_collection_with_link(oc_resource_t *resource,
}
static oc_event_callback_retval_t
notify_collection_for_link(void *data)
batch_notify_collection_for_link(void *data)
{
coap_notify_observers(data, NULL, NULL);
return OC_EVENT_DONE;
......@@ -896,7 +905,7 @@ oc_handle_collection_request(oc_method_t method, oc_request_t *request,
response_buffer.code <
oc_status_code(OC_STATUS_BAD_REQUEST)) {
oc_set_delayed_callback(link->resource,
notify_collection_for_link, 0);
batch_notify_collection_for_link, 0);
}
if (response_buffer.code <
oc_status_code(OC_STATUS_BAD_REQUEST)) {
......
......@@ -597,12 +597,12 @@ oc_core_get_resource_by_uri(const char *uri, size_t device)
} else if (memcmp(uri + skip, "oic/sec/cred", 12) == 0) {
type = OCF_SEC_CRED;
}
}
#ifdef OC_PKI
else if ((strlen(uri) - skip) == 10 &&
} else if ((strlen(uri) - skip) == 10 &&
memcmp(uri + skip, "oic/sec/sp", 10) == 0) {
type = OCF_SEC_SP;
} else if ((strlen(uri) - skip) == 11 &&
}
#ifdef OC_PKI
else if ((strlen(uri) - skip) == 11 &&
memcmp(uri + skip, "oic/sec/csr", 11) == 0) {
type = OCF_SEC_CSR;
} else if ((strlen(uri) - skip) == 13 &&
......
......@@ -32,7 +32,7 @@
static bool
filter_resource(oc_resource_t *resource, oc_request_t *request,
const char *anchor, CborEncoder *links)
const char *anchor, CborEncoder *links, size_t device_index)
{
if (!oc_filter_resource_by_rt(resource, request)) {
return false;
......@@ -73,7 +73,7 @@ filter_resource(oc_resource_t *resource, oc_request_t *request,
// eps
oc_rep_set_array(link, eps);
oc_endpoint_t *eps = oc_connectivity_get_endpoints(resource->device);
oc_endpoint_t *eps = oc_connectivity_get_endpoints(device_index);
while (eps != NULL) {
/* If this resource has been explicitly tagged as SECURE on the
* application layer, skip all coap:// endpoints, and only include
......@@ -147,64 +147,64 @@ process_device_resources(CborEncoder *links, oc_request_t *request,
oc_concat_strings(&anchor, "ocf://", uuid);
if (filter_resource(oc_core_get_resource_by_index(OCF_P, 0), request,
oc_string(anchor), links))
oc_string(anchor), links, device_index))
matches++;
if (filter_resource(oc_core_get_resource_by_index(OCF_D, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
if (filter_resource(
oc_core_get_resource_by_index(OCF_INTROSPECTION_WK, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
if (oc_get_con_res_announced() &&
filter_resource(oc_core_get_resource_by_index(OCF_CON, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
#ifdef OC_MNT
if (filter_resource(oc_core_get_resource_by_index(OCF_MNT, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
#endif /* OC_MNT */
#ifdef OC_SOFTWARE_UPDATE
if (filter_resource(
oc_core_get_resource_by_index(OCF_SW_UPDATE, device_index), request,
oc_string(anchor), links))
oc_string(anchor), links, device_index))
matches++;
#endif /* OC_SOFTWARE_UPDATE */
#ifdef OC_SECURITY
if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_DOXM, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
if (filter_resource(
oc_core_get_resource_by_index(OCF_SEC_PSTAT, device_index), request,
oc_string(anchor), links))
oc_string(anchor), links, device_index))
matches++;
if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_ACL, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_CRED, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
#ifdef OC_PKI
if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_SP, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
#ifdef OC_PKI
if (filter_resource(oc_core_get_resource_by_index(OCF_SEC_CSR, device_index),
request, oc_string(anchor), links))
request, oc_string(anchor), links, device_index))
matches++;
if (filter_resource(
oc_core_get_resource_by_index(OCF_SEC_ROLES, device_index), request,
oc_string(anchor), links))
oc_string(anchor), links, device_index))
matches++;
#endif /* OC_PKI */
#endif /* OC_SECURITY */
......@@ -212,7 +212,7 @@ process_device_resources(CborEncoder *links, oc_request_t *request,
#if defined(OC_CLIENT) && defined(OC_SERVER) && defined(OC_CLOUD)
if (filter_resource(
oc_core_get_resource_by_index(OCF_COAPCLOUDCONF, device_index), request,
oc_string(anchor), links))
oc_string(anchor), links, device_index))
matches++;
#endif /* OC_CLIENT && OC_SERVER && OC_CLOUD */
......@@ -223,7 +223,8 @@ process_device_resources(CborEncoder *links, oc_request_t *request,
!(resource->properties & OC_DISCOVERABLE))
continue;
if (filter_resource(resource, request, oc_string(anchor), links))
if (filter_resource(resource, request, oc_string(anchor), links,
device_index))
matches++;
}
......@@ -235,7 +236,7 @@ process_device_resources(CborEncoder *links, oc_request_t *request,
continue;
if (filter_resource((oc_resource_t *)collection, request, oc_string(anchor),
links))
links, device_index))
matches++;
}
#endif /* OC_COLLECTIONS */
......@@ -417,11 +418,11 @@ process_oic_1_1_device_object(CborEncoder *device, oc_request_t *request,
oc_rep_array(links)))
matches++;
#ifdef OC_PKI
if (filter_oic_1_1_resource(
oc_core_get_resource_by_index(OCF_SEC_SP, device_num), request,
oc_rep_array(links)))
matches++;
#ifdef OC_PKI
if (filter_oic_1_1_resource(
oc_core_get_resource_by_index(OCF_SEC_CSR, device_num), request,
oc_rep_array(links)))
......
......@@ -383,8 +383,8 @@ oc_parse_endpoint_string(oc_string_t *endpoint_str, oc_endpoint_t *endpoint,
/* Extract a uri path if requested and available */
const char *u = NULL;
if (uri) {
u = memchr(address, '/', len);
if (uri) {
if (u) {
oc_new_string(uri, u, (len - (u - address)));
}
......
......@@ -42,9 +42,9 @@
#include "security/oc_store.h"
#include "security/oc_svr.h"
#include "security/oc_tls.h"
#include "security/oc_sp.h"
#ifdef OC_PKI
#include "security/oc_keypair.h"
#include "security/oc_sp.h"
#endif /* OC_PKI */
#endif /* OC_SECURITY */
......@@ -237,8 +237,8 @@ oc_main_init(const oc_handler_t *handler)
oc_sec_load_doxm(device);
oc_sec_load_cred(device);
oc_sec_load_acl(device);
#ifdef OC_PKI
oc_sec_load_sp(device);
#ifdef OC_PKI
oc_sec_load_ecdsa_keypair(device);
#endif /* OC_PKI */
}
......@@ -293,8 +293,8 @@ oc_main_shutdown(void)
oc_sec_cred_free();
oc_sec_doxm_free();
oc_sec_pstat_free();
#ifdef OC_PKI
oc_sec_sp_free();
#ifdef OC_PKI
oc_free_ecdsa_keypairs();
#endif /* OC_PKI */
oc_tls_shutdown();
......
......@@ -154,5 +154,21 @@ TEST(OCEndpoints, StringToEndpoint)
oc_free_string(&s);
oc_free_string(&uri);
}
// test dns lookup when uri is NULL
const char *spu3[4] = { "coap://10.211.55.3:56789/a/light",
"coaps+tcp://10.211.55.3/a/light",
"coap://openconnectivity.org/alpha",
"coaps://openconnectivity.org:3456/alpha" };
for (int i = 0; i < 4; i++) {
oc_string_t s;
oc_new_string(&s, spu3[i], strlen(spu[i]));
oc_endpoint_t ep;
memset(&ep, 0, sizeof(oc_endpoint_t));
int ret = oc_string_to_endpoint(&s, &ep, NULL);
EXPECT_EQ(ret, 0) << "spu3[" << i << "] " << spu3[i];
}
#endif
}
......@@ -150,6 +150,32 @@ typedef struct
} oc_handler_t;
typedef void (*oc_init_platform_cb_t)(void *data);
/**
* Callback invoked during oc_add_device(). The purpose is to add any additional
* device properties that are not supplied to oc_add_device() function call.
*
* Example:
* ```
* static void set_device_custom_property(void *data)
* {
* (void)data;
* oc_set_custom_device_property(purpose, "desk lamp");
* }
*
* static int app_init(void)
* {
* int ret = oc_init_platform("My Platform", NULL, NULL);
* ret |= oc_add_device("/oic/d", "oic.d.light", "My light", "ocf.1.0.0",
* "ocf.res.1.0.0", set_device_custom_property, NULL);
* return ret;
* }
* ```
*
* @param data context pointer that comes from the oc_add_device() function
*
* @see oc_add_device
* @see oc_set_custom_device_property
*/
typedef void (*oc_add_device_cb_t)(void *data);
/**
......@@ -183,11 +209,62 @@ typedef void (*oc_add_device_cb_t)(void *data);
*/
int oc_main_init(const oc_handler_t *handler);
oc_clock_time_t oc_main_poll(void);
/**
* Shutdown and free all stack related resources
*/
void oc_main_shutdown(void);
typedef void (*oc_factory_presets_cb_t)(size_t device, void *data);
void oc_set_factory_presets_cb(oc_factory_presets_cb_t cb, void *data);
/**
* Add an ocf device to the the stack.
*
* This function is typically called from as part of the stack initialization
* process inside the `init` callback handler.
*
* The `oc_add_device` function may be called as many times as needed.
* Each call will add a new device to the stack with its own port address.
* Each device is automatically assigned a number starting with zero and
* incremented by one each time the function is called. This number is not
* returned therefore it is important to know the order devices are added.
*
* Example:
* ```
* //app_init is an instance of the `init` callback handler.
* static int app_init(void)
* {
* int ret = oc_init_platform("Refrigerator", NULL, NULL);
* ret |= oc_add_device("/oic/d", "oic.d.refrigeration", "My fridge",
* "ocf.2.0.5", "ocf.res.1.0.0,ocf.sh.1.0.0",
* NULL, NULL);
* ret |= oc_add_device("/oic/d", "oic.d.thermostat", "My thermostat",
* "ocf.2.0.5", "ocf.res.1.0.0,ocf.sh.1.0.0",
* NULL, NULL);
* return ret;
* }
* ```
*
* @param uri the The device URI. The wellknown default URI "/oic/d" is hosted
* by every server. Used to device specific information.
* @param rt the resource type
* @param name the user readable name of the device
* @param spec_version The version of the OCF Server. This is the "icv" device
* property
* @param data_model_version Spec version of the resource and device
* specifications to which this device data model is implemtned. This is the
* "dmv" device property
* @param add_device_cb callback function that will be invoked once device has
* been added
* @param data context pointer that is passed to the oc_add_device_cb_t
*
* @return
* - `0` on success
* - `-1` on failure
*
* @see init
*/
int 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);
......
......@@ -109,8 +109,8 @@ typedef enum {
OCF_SEC_PSTAT,
OCF_SEC_ACL,
OCF_SEC_CRED,
#ifdef OC_PKI
OCF_SEC_SP,
#ifdef OC_PKI
OCF_SEC_CSR,
OCF_SEC_ROLES,
#endif /* OC_PKI */
......
......@@ -236,7 +236,8 @@ coap_receive(oc_message_t *msg)
OC_DBG(" QUERY: %.*s", (int)message->uri_query_len, message->uri_query);
OC_DBG(" Payload: %.*s", (int)message->payload_len, message->payload);
#endif
const char *href;
size_t href_len = coap_get_header_uri_path(message, &href);
#ifdef OC_TCP
if (msg->endpoint.flags & TCP) {
coap_tcp_init_message(response, CONTENT_2_05);
......@@ -253,18 +254,21 @@ coap_receive(oc_message_t *msg)
history[idx] = message->mid;
history_dev[idx] = (uint8_t)msg->endpoint.device;
idx = (idx + 1) % OC_REQUEST_HISTORY_SIZE;
if (href_len == 7 && memcmp(href, "oic/res", 7) == 0) {
coap_udp_init_message(response, COAP_TYPE_CON, CONTENT_2_05,
coap_get_mid());
} else {
coap_udp_init_message(response, COAP_TYPE_NON, CONTENT_2_05,
coap_get_mid());
}
}
}
/* create transaction for response */
transaction = coap_new_transaction(message->mid, &msg->endpoint);
transaction = coap_new_transaction(response->mid, &msg->endpoint);
if (transaction) {
#ifdef OC_BLOCK_WISE
const char *href;
size_t href_len = coap_get_header_uri_path(message, &href);
const uint8_t *incoming_block;
uint32_t incoming_block_len =
(uint32_t)coap_get_payload(message, &incoming_block);
......@@ -312,10 +316,13 @@ coap_receive(oc_message_t *msg)
goto send_message;
} else {
OC_DBG("received all blocks for payload");
coap_udp_init_message(response, COAP_TYPE_CON, CONTENT_2_05,
response->mid);
coap_set_header_block1(response, block1_num, block1_more,
block1_size);
request_buffer->payload_size =
request_buffer->next_block_offset;
request_buffer->ref_count = 0;
goto request_handler;
}
}
......@@ -351,12 +358,17 @@ coap_receive(oc_message_t *msg)
response_buffer->payload_size)
? 1
: 0;
if (more == 0) {
coap_udp_init_message(response, COAP_TYPE_CON, CONTENT_2_05,
response->mid);
}
coap_set_payload(response, payload, payload_size);
coap_set_header_block2(response, block2_num, more, block2_size);
oc_blockwise_response_state_t *response_state =
(oc_blockwise_response_state_t *)response_buffer;
coap_set_header_etag(response, response_state->etag,
COAP_ETAG_LEN);
response_buffer->ref_count = more;
goto send_message;
} else {
OC_ERR("could not dispatch block");
......@@ -438,9 +450,18 @@ coap_receive(oc_message_t *msg)
href, href_len, &msg->endpoint, message->code, message->uri_query,
message->uri_query_len, OC_BLOCKWISE_SERVER);
if (response_buffer) {
if (msg->endpoint.flags & MULTICAST &&
response_buffer->next_block_offset <
response_buffer->payload_size) {
OC_DBG("Dropping duplicate block-wise transfer request due to "
"repeated multicast");
coap_status_code = CLEAR_TRANSACTION;
goto send_message;
} else {
oc_blockwise_free_response_buffer(response_buffer);
response_buffer = NULL;
}
}
goto request_handler;
} else {
OC_ERR("incoming payload size exceeds block size");
......
......@@ -283,7 +283,7 @@ coap_notify_collection_observers(oc_resource_t *resource,
/* iterate over observers */
for (obs = (coap_observer_t *)oc_list_head(observers_list); obs;
obs = obs->next) {
if (obs->resource != resource && obs->iface_mask != iface_mask) {
if (obs->resource != resource || obs->iface_mask != iface_mask) {
continue;
}
......
#Set CONTIKI appropriately below to point to the root of your Contiki source.
CONTIKI = ${HOME}/contiki
ifeq ($(CLIENT),1)
CONTIKI_PROJECT = client_contiki
else
CONTIKI_PROJECT = server_contiki
SERVER=1
endif
all: $(CONTIKI_PROJECT)
PROJECTDIRS += ./ ../../include ../../ ../../api ../../messaging/coap ../../apps ../../deps/tinycbor/src ../../util
PROJECT_SOURCEFILES += oc_buffer.c oc_discovery.c oc_main.c oc_ri.c oc_client_api.c oc_network_events.c oc_server_api.c oc_core_res.c oc_helpers.c oc_rep.c oc_uuid.c cborencoder.c cborencoder_close_container_checked.c cborparser.c oc_etimer.c oc_memb.c oc_process.c oc_list.c oc_mmem.c oc_timer.c coap.c separate.c engine.c transactions.c observe.c ipadapter.c oc_clock.c oc_random.c abort.c storage.c oc_blockwise.c oc_base64.c oc_endpoint.c oc_introspection.c
CONTIKI_WITH_RPL = 1
CONTIKI_WITH_IPV6 = 1
include $(CONTIKI)/Makefile.include
CFLAGS += -std=gnu99 -fno-asynchronous-unwind-tables -fno-omit-frame-pointer -ffreestanding -Os -fno-stack-protector -ffunction-sections -fdata-sections -fno-reorder-functions -fno-defer-pop -fno-strict-overflow -Wl,--gc-sections
ifeq ($(CLIENT),1)
CFLAGS += -DOC_CLIENT
endif
ifeq ($(SERVER),1)
CFLAGS += -DOC_SERVER
endif
ifeq ($(DEBUG),1)
CFLAGS += -DOC_DEBUG -g
endif
1) Set CONTIKI path in the Makefile.
2) Perform the build:
make SERVER=1 <additional options you normally pass; eg. TARGET=...)
This selects the apps/server_contiki sample.
Specify CLIENT=1 instead to select the apps/client_contiki sample.
Add DEBUG=1 to include debug output from IoTivity-Lite.
#include "port/oc_assert.h"
// TODO:
void abort_impl() {}
/*
// 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 "contiki.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "net/rpl/rpl.h"
#include "oc_buffer.h"
#include "oc_endpoint.h"
#include "port/oc_connectivity.h"
#include "simple-udp.h"
#define OCF_MCAST_PORT_UNSECURED (5683)
#define OCF_SERVER_PORT_UNSECURED (56789)
static struct simple_udp_connection server, mcast;
PROCESS(ip_adapter_process, "IP Adapter");
static uip_ipaddr_t ipaddr, mcastaddr;
static oc_endpoint_t *eps;
static void
free_endpoints(void)
{
oc_endpoint_t *ep = eps, *next;
while (ep != NULL) {
next = ep->next;
oc_free_endpoint(ep);
ep = next;
}
}
void
handle_incoming_message(uint8_t *buffer, int size, uint8_t *addr, uint16_t port)
{
oc_message_t *message = oc_allocate_message();
if (message) {
size_t bytes_read = size;
bytes_read = (bytes_read < OC_PDU_SIZE) ? bytes_read : OC_PDU_SIZE;
memcpy(message->data, buffer, bytes_read);
message->length = bytes_read;
message->endpoint.flags = IPV6;
memcpy(message->endpoint.addr.ipv6.address, addr, 16);
message->endpoint.addr.ipv6.port = port;