Commit e21a3ec3 authored by Kishen Maloor's avatar Kishen Maloor

Merge branch 'origin/fargo' into gaborone

Signed-off-by: Kishen Maloor's avatarKishen Maloor <kishen.maloor@intel.com>
parents 74ffc6e3 bc41ba8e
Pipeline #445 failed with stage
in 6 minutes and 11 seconds
......@@ -72,6 +72,7 @@ port/openthread/output
*.gcno
.clang-format
_clang-format
whitespace_commit_checker.sh
port/linux/platformtest
port/linux/storage_test
port/linux/apitest
......
---
image: gcc
build:
Linux_Secured_Test:
stage: build
before_script:
- apt update && apt -y install make autoconf
- set -o pipefail
- export VERBOSE=false
- export CCACHE_DISABLE=false
script:
- cd port/linux
- make
- make DYNAMIC=1 IPV4=1 TCP=1 SECURE=1 test
Linux_Unsecured_Test:
stage: build
before_script:
- apt update && apt -y install make autoconf
- set -o pipefail
- export VERBOSE=false
- export CCACHE_DISABLE=false
script:
- cd port/linux
- make DYNAMIC=1 IPV4=1 TCP=1 SECURE=0 test
Android_build:
stage: build
image: openjdk:8-jdk
before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 make autoconf swig
- wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
- unzip -d android-sdk-linux android-sdk.zip
- echo y | android-sdk-linux/tools/bin/sdkmanager "ndk-bundle" >/dev/null
- echo y | android-sdk-linux/tools/bin/sdkmanager "platforms;android-28" >/dev/null
- echo y | android-sdk-linux/tools/bin/sdkmanager "platform-tools" >/dev/null
- echo y | android-sdk-linux/tools/bin/sdkmanager "build-tools;28.0.2" >/dev/null
- export ANDROID_HOME=$PWD/android-sdk-linux
- export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/
# temporarily disable checking for EPIPE error and use yes to accept all licenses
- set +o pipefail
- yes | android-sdk-linux/tools/bin/sdkmanager --licenses
- set -o pipefail
- ./android-sdk-linux/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 23 --install-dir ~/android-arm-23
script:
- cd port/android
- make DYNAMIC=1 TCP=1 IPV4=1 SECURE=1 PKI=1 CLOUD=1 JAVA=1 DEBUG=0
whitespace_and_doxygen:
stage: build
before_script:
- apt update && apt -y install make autoconf doxygen clang-format
script:
- clang-format --version
- doxygen --version
- cp tools/_clang-format _clang-format
- cp tools/whitespace_commit_checker.sh whitespace_commit_checker.sh
- ./whitespace_commit_checker.sh
- cd tools
- ./build_doc.sh
......@@ -655,7 +655,7 @@ oc_handle_collection_request(oc_method_t method, oc_request_t *request,
* interface through which this request arrived. This is achieved
* by checking if the interface index matches.
*/
if ((link->resource->properties & OC_SECURE &&
if (((link->resource->properties & OC_SECURE) &&
!(eps->flags & SECURED)) ||
(request->origin && request->origin->interface_index != -1 &&
request->origin->interface_index != eps->interface_index)) {
......@@ -757,7 +757,7 @@ oc_handle_collection_request(oc_method_t method, oc_request_t *request,
* interface through which this request arrived. This is achieved by
* checking if the interface index matches.
*/
if ((link->resource->properties & OC_SECURE &&
if (((link->resource->properties & OC_SECURE) &&
!(eps->flags & SECURED)) ||
(request->origin && request->origin->interface_index != -1 &&
request->origin->interface_index != eps->interface_index)) {
......
......@@ -347,7 +347,7 @@ oc_ri_add_resource(oc_resource_t *resource)
!resource->post_handler.cb && !resource->delete_handler.cb)
valid = false;
if (resource->properties & OC_PERIODIC &&
if ((resource->properties & OC_PERIODIC) &&
resource->observe_period_seconds == 0)
valid = false;
......@@ -974,7 +974,7 @@ oc_ri_invoke_coap_entity_handler(void *request, void *response, uint8_t *buffer,
#ifdef OC_SECURITY
while (links) {
if (links->resource &&
links->resource->properties & OC_OBSERVABLE) {
(links->resource->properties & OC_OBSERVABLE)) {
if (!oc_sec_check_acl(OC_GET, links->resource, endpoint)) {
set_observe_option = false;
break;
......@@ -988,7 +988,7 @@ oc_ri_invoke_coap_entity_handler(void *request, void *response, uint8_t *buffer,
links = (oc_link_t *)oc_list_head(collection->links);
while (links) {
if (links->resource &&
links->resource->properties & OC_PERIODIC) {
(links->resource->properties & OC_PERIODIC)) {
add_periodic_observe_callback(links->resource);
}
links = links->next;
......
......@@ -150,6 +150,10 @@ oc_handle_session(oc_endpoint_t *endpoint, oc_session_state_t state)
oc_tls_remove_peer(endpoint);
}
#endif /* OC_SECURITY */
#ifdef OC_SERVER
/* remove all observations for the endpoint */
coap_remove_observer_by_client(endpoint);
#endif /* OC_SERVER */
}
#ifdef OC_SESSION_EVENTS
handle_session_event_callback(endpoint, state);
......
......@@ -40,16 +40,12 @@ class TestCoreResource: public testing::Test
virtual void SetUp()
{
oc_core_init();
#ifndef OC_SECURITY
oc_random_init();
#endif /* !OC_SECURITY */
}
virtual void TearDown()
{
oc_core_shutdown();
#ifndef OC_SECURITY
oc_random_destroy();
#endif /* !OC_SECURITY */
}
};
......
......@@ -646,6 +646,7 @@ main(void)
break;
case 8:
handle_signal(0);
break;
default:
break;
}
......
/*
// Copyright (c) 2016 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#include "oc_api.h"
#include "port/oc_clock.h"
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
pthread_mutex_t mutex;
pthread_cond_t cv;
struct timespec ts;
int quit = 0;
static int
app_init(void)
{
int ret = oc_init_platform("Apple", NULL, NULL);
printf("\tPlatform initialized.\n");
ret |= oc_add_device("/oic/d", "oic.d.phone", "Kishen's IPhone", "ocf.1.0.0",
"ocf.res.1.0.0", NULL, NULL);
printf("\tDevice initialized.\n");
return ret;
}
#define MAX_URI_LENGTH (128)
static char wk_introspection_uri[MAX_URI_LENGTH];
static char introspection_data_uri[MAX_URI_LENGTH];
static oc_endpoint_t wk_introspection_server;
static oc_endpoint_t introspection_data_server;
void
print_rep(oc_rep_t *rep, bool pretty_print)
{
char *json;
size_t json_size;
json_size = oc_rep_to_json(rep, NULL, 0, pretty_print);
json = (char *)malloc(json_size + 1);
oc_rep_to_json(rep, json, json_size + 1, pretty_print);
printf("%s\n", json);
free(json);
}
static void
get_introspection_data(oc_client_response_t *data)
{
printf("\nInside the get_introspection_data handler:\n");
if (data->code == OC_STATUS_OK) {
oc_rep_t *rep = data->payload;
print_rep(rep, true);
} else {
switch (data->code) {
case OC_STATUS_UNAUTHORIZED:
printf("\tERROR Unauthorized access check permissions.\n");
break;
case OC_STATUS_INTERNAL_SERVER_ERROR:
printf("\tERROR Internal Server Error\n"
"\t\tcheck the max app data size of the server.\n");
break;
default:
printf("\tERROR status: %d\n", data->code);
}
}
}
static void
get_wk_introspection(oc_client_response_t *data)
{
printf("\nInside the get_wk_introspection handler:\n");
oc_rep_t *rep = data->payload;
while (rep != NULL) {
print_rep(rep, true);
switch (rep->type) {
case OC_REP_OBJECT_ARRAY: {
oc_rep_t *rep_array = rep->value.object_array;
while (rep_array != NULL) {
oc_rep_t *rep_item = rep_array->value.object;
while (rep_item != NULL) {
char *url_str = oc_string(rep_item->name);
size_t url_str_len = oc_string_len(rep_item->name);
if (strncmp("url", url_str, url_str_len) == 0) {
oc_string_t path;
// convert the url to an endpoint.
oc_string_to_endpoint(&rep_item->value.string,
&introspection_data_server, &path);
strncpy(introspection_data_uri, oc_string(path), MAX_URI_LENGTH);
introspection_data_uri[MAX_URI_LENGTH - 1] = '\0';
printf("Calling GET on %s\n", introspection_data_uri);
oc_do_get(introspection_data_uri, &introspection_data_server, NULL,
&get_introspection_data, LOW_QOS, NULL);
}
rep_item = rep_item->next;
}
rep_array = rep_array->next;
}
break;
}
default:
break;
}
rep = rep->next;
}
}
static oc_discovery_flags_t
discovery(const char *anchor, const char *uri, oc_string_array_t types,
oc_interface_mask_t iface_mask, oc_endpoint_t *endpoint,
oc_resource_properties_t bm, void *user_data)
{
(void)anchor;
(void)user_data;
(void)iface_mask;
(void)bm;
int i;
int uri_len = strlen(uri);
uri_len = (uri_len >= MAX_URI_LENGTH) ? MAX_URI_LENGTH - 1 : uri_len;
for (i = 0; i < (int)oc_string_array_get_allocated_size(types); i++) {
char *t = oc_string_array_get_item(types, i);
if (strlen(t) == 20 && strncmp(t, "oic.wk.introspection", 20) == 0) {
printf("Found oic.wk.introspection resource.\n");
oc_endpoint_copy(&wk_introspection_server, endpoint);
strncpy(wk_introspection_uri, uri, uri_len);
wk_introspection_uri[uri_len] = '\0';
printf("Resource %s hosted at endpoints:\n", wk_introspection_uri);
oc_endpoint_t *ep = endpoint;
while (ep != NULL) {
printf("\t");
PRINTipaddr(*ep);
printf("\n");
ep = ep->next;
}
printf("Calling GET on oic.wk.introspection %s\n", wk_introspection_uri);
oc_do_get(wk_introspection_uri, &wk_introspection_server, NULL,
&get_wk_introspection, LOW_QOS, NULL);
return OC_STOP_DISCOVERY;
}
}
return OC_CONTINUE_DISCOVERY;
}
static void
issue_requests(void)
{
printf(
"Making ip discovery request for OCF 'oic.wk.introspection' resource.\n");
oc_do_ip_discovery("oic.wk.introspection", &discovery, NULL);
}
static void
signal_event_loop(void)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
void
handle_signal(int signal)
{
(void)signal;
signal_event_loop();
quit = 1;
}
int
main(void)
{
int init;
struct sigaction sa;
sigfillset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = handle_signal;
sigaction(SIGINT, &sa, NULL);
static const oc_handler_t handler = { .init = app_init,
.signal_event_loop = signal_event_loop,
.requests_entry = issue_requests };
oc_clock_time_t next_event;
// set at 18K may need to be increased if server contains a large IDD.
oc_set_max_app_data_size(18432);
#ifdef OC_STORAGE
oc_storage_config("./introspectionclient_creds");
#endif /* OC_STORAGE */
printf("Initilizing the introspection client...\n");
init = oc_main_init(&handler);
if (init < 0)
return init;
while (quit != 1) {
next_event = oc_main_poll();
pthread_mutex_lock(&mutex);
if (next_event == 0) {
pthread_cond_wait(&cv, &mutex);
} else {
ts.tv_sec = (next_event / OC_CLOCK_SECOND);
ts.tv_nsec = (next_event % OC_CLOCK_SECOND) * 1.e09 / OC_CLOCK_SECOND;
pthread_cond_timedwait(&cv, &mutex, &ts);
}
pthread_mutex_unlock(&mutex);
}
oc_main_shutdown();
return 0;
}
......@@ -21,6 +21,10 @@
#include <signal.h>
#include <stdio.h>
#if defined(OC_IDD_API)
#include "oc_introspection.h"
#endif
static pthread_mutex_t mutex;
static pthread_cond_t cv;
static struct timespec ts;
......@@ -67,6 +71,35 @@ app_init(void)
err |= oc_add_device("/oic/d", "oic.d.switch", "Temp_sensor", "ocf.2.5.0",
"ocf.res.1.3.0,ocf.sh.1.3.0", NULL, NULL);
PRINT("\tSwitch device added.\n");
#if defined(OC_IDD_API)
FILE *fp;
uint8_t *buffer;
size_t buffer_size;
const char introspection_error[] =
"\tERROR Could not read smart_home_server_linux_IDD.cbor\n"
"\tIntrospection data not set for device.\n";
fp = fopen("./smart_home_server_linux_IDD.cbor", "rb");
if (fp) {
fseek(fp, 0, SEEK_END);
buffer_size = ftell(fp);
rewind(fp);
buffer = (uint8_t *)malloc(buffer_size * sizeof(uint8_t));
size_t fread_ret = fread(buffer, buffer_size, 1, fp);
fclose(fp);
if (fread_ret == 1) {
oc_set_introspection_data(0, buffer, buffer_size);
PRINT("\tIntrospection data set for device.\n");
} else {
PRINT("%s", introspection_error);
}
free(buffer);
} else {
PRINT("%s", introspection_error);
}
#endif
if (err >= 0) {
oc_uuid_t my_uuid;
......@@ -512,7 +545,7 @@ register_resources(void)
oc_resource_tag_func_desc(temp_resource, OC_ENUM_HEATING);
oc_resource_tag_pos_desc(temp_resource, OC_POS_CENTRE);
oc_add_resource(temp_resource);
PRINT("\tTemperature resource added.\n");
bswitch = oc_new_resource(NULL, "/switch", 1, 0);
oc_resource_bind_resource_type(bswitch, "oic.r.switch.binary");
oc_resource_bind_resource_interface(bswitch, OC_IF_A);
......@@ -525,7 +558,7 @@ register_resources(void)
oc_resource_tag_pos_rel(bswitch, 0.34, 0.5, 0.8);
oc_resource_tag_pos_desc(bswitch, OC_POS_TOP);
oc_add_resource(bswitch);
PRINT("\tSwitch resource added.\n");
#ifdef OC_COLLECTIONS
col = oc_new_collection(NULL, "/platform", 1, 0);
oc_resource_bind_resource_type(col, "oic.wk.col");
......@@ -549,6 +582,7 @@ register_resources(void)
oc_resource_set_properties_cbs(col, get_platform_properties, NULL,
set_platform_properties, NULL);
oc_add_collection(col);
PRINT("\tResources added to collection.\n");
#endif /* OC_COLLECTIONS */
}
......@@ -694,7 +728,8 @@ main(void)
oc_clock_time_t next_event;
oc_set_con_res_announced(false);
oc_set_max_app_data_size(16384);
// max app data size set to 13k large enough to hold full IDD
oc_set_max_app_data_size(13312);
#ifdef OC_STORAGE
oc_storage_config("./smart_home_server_linux_creds");
......@@ -710,10 +745,12 @@ main(void)
return -1;
}
PRINT("Initializing Smart Home Server.\n");
init = oc_main_init(&handler);
if (init < 0)
return init;
PRINT("Waiting for Client...\n");
PRINT("Hit 'Enter' at any time to toggle switch resource\n");
while (quit != 1) {
next_event = oc_main_poll();
pthread_mutex_lock(&mutex);
......
......@@ -22,7 +22,7 @@
/**
\mainpage IoTivity-Lite API
The file \link oc_api.h\endlink is the main entry for all
The file \link oc_api.h \endlink is the main entry for all
server and client related OCF functions.
*/
......@@ -560,20 +560,159 @@ void oc_reset();
*/
void oc_reset_device(size_t device);
/** Server side */
/* Server side */
/**
@defgroup doc_module_tag_server_side Server side
Optional group of functions OCF server support.
@{
*/
/**
* Allocate and populate a new oc_resource_t.
*
* Resources are the primary interface between code and real world devices.
*
* Each resource has a Uniform Resource Identifier (URI) that identifies it.
* All resources **must** specify one or more Resource Types to be considered a
* valid resource. The number of Resource Types is specified by the
* `num_resource_types` the actual Resource Types are added later using the
* oc_resource_bind_resource_type() function.
*
* The resource is populated with a default interface OC_IF_BASELINE.
*
* Many properties associated with a resource are set or modified after the
* new resource has been created.
*
* The resource is not added to the device till oc_add_resource() is called.
*
* Example:
* ```
* static void register_resources(void)
* {
* oc_resource_t *bswitch = oc_new_resource("light switch", "/switch", 1, 0);
* oc_resource_bind_resource_type(bswitch, "oic.r.switch.binary");
* oc_resource_bind_resource_interface(bswitch, OC_IF_A);
* oc_resource_set_default_interface(bswitch, OC_IF_A);
* oc_resource_set_observable(bswitch, true);
* oc_resource_set_discoverable(bswitch, true);
* oc_resource_set_request_handler(bswitch, OC_GET, get_switch, NULL);
* oc_resource_set_request_handler(bswitch, OC_POST, post_switch, NULL);
* oc_resource_set_request_handler(bswitch, OC_PUT, put_switch, NULL);
* oc_add_resource(bswitch);
* }
* ```
*
* @param[in] name the name of the new resource this will set the property `n`
* @param[in] uri the Uniform Resource Identifier for the resource
* @param[in] num_resource_types the number of Resource Types that will be
* added/bound to the resource
* @param[in] device index of the logical device the resource will be added to
*
* @see oc_resource_bind_resource_interface
* @see oc_resource_set_default_interface
* @see oc_resource_bind_resource_type
* @see oc_process_baseline_interface
* @see oc_resource_set_discoverable
* @see oc_resource_set_periodic_observable
* @see oc_resource_set_request_handler
*/
oc_resource_t *oc_new_resource(const char *name, const char *uri,
uint8_t num_resource_types, size_t device);
/**
* Add the supported interface(s) to the resource.
*
* Resource interfaces specify how the code is able to interact with the
* resource
*
* The `iface_mask` is bitwise OR of the following interfaces:
* - `OC_IF_BASELINE` ("oic.if.baseline") baseline interface allow GET,
* PUT/POST, and notify/observe operations.
* - `OC_IF_LL` ("oic.if.ll") The links list interface is a specifically
* designed to provide a list of links pointing to other
* resources. Links list interfaces allow GET, and notify/observe operations.
* - `OC_IF_B` ("oic.if.b") batch interface. The batch interface is used to
* interact with a collection of resources at the same time.
* - `OC_IF_R` ("oic.if.r") a read-only interface. A read-only interface
* allows GET, and notify/observe operations.
* - `OC_IF_RW` ("oir.if.rw") a read-write interface. A read-write interface
* allows GET, PUT/POST, and notify/observe operations.
* - `OC_IF_A` ("oic.if.a") an actuator interface. An actuator interface allows
* GET, PUT/POST, and notify/observe operations.
* - `OC_IF_S` ("oic.if.s") a sensor interface. A sensor interface allows GET,
* and notify/observe operations.
* - `OC_IC_CREATE` ("oic.if.create") used to create new resources in a
* collection.
*
* The read-write and actuator interfaces are very similar and sometimes hard to
* differentiate when one should be used over another. In general an actuator
* interface is used when it modifies the real world value. e.g. turn on light,
* increase temperature, open vent.
*
* The read-only and sensor are also very similar in general a sensor value is
* read directly or indirectly from a real world sensor.
*
* @param[in] resource the resource that the interface(s) will be added to
* @param[in] iface_mask a bitwise ORed list of all interfaces supported by the
* resource.
* @see oc_interface_mask_t
* @see oc_resource_set_default_interface
*/
void oc_resource_bind_resource_interface(oc_resource_t *resource,
oc_interface_mask_t iface_mask);
/**
* Select the default interface.
*
* The default interface must be one of the resources specified in the
* oc_resource_bind_resource_interface() function.
*
* If a request to the resource comes in and the interface is not specified
* then the default interface will be used to service the request.
*
* If the default interface is not set then the OC_IF_BASELINE will be used
* by the stack.
*
* @param[in] resource the resource that the default interface will be set on
* @param[in] iface_mask a single interface that will will be used as the
* default interface
*/
void oc_resource_set_default_interface(oc_resource_t *resource,
oc_interface_mask_t iface_mask);
/**
* Add a Resource Type "rt" property to the resource.
*
* All resources require at least one Resource Type. The number of Resource
* Types the resource contains is declared when the resource it created using
* oc_new_resource() function.
*
* Resource Types use a dot "." naming scheme e.g. `oic.r.switch.binary`.
* Resource Types starting with `oic` are reserved for a OCF defined Resource
* Types. Developers are strongly encouraged to try and use an OCF defined
* Resource Type vs. creating their own. A repository of OCR defined resources
* can be found on oneiota.org.
*
* Multi-value "rt" Resource means a resource with multiple Resource Types. i.e.
* oc_resource_bind_resource_type is called multiple times for a single
* resource. When using a Mulit-value Resource the different resources
* properties must not conflict.
*
* @param[in] resource the resource that the Resource Type will be set on
* @param[in] type the Resource Type to add to the Resource Type "rt" property
*
* @see oc_new_resource
* @see oc_device_bind_resource_type
*/
void oc_resource_bind_resource_type(oc_resource_t *resource, const char *type);
/**
* Add a Resource Type "rt" property to the an /oic/d resource.
*
* This function can be used to bind a new Resource Type to a logical device's
* /oic/d resource.
*
* @param[in] device index of a logical device
* @param[in] type the Resource type to add to the Resource Type "rt" property
*/
void oc_device_bind_resource_type(size_t device, const char *type);
void oc_resource_tag_pos_desc(oc_resource_t *resource,