Commit e3d587e5 authored by George Nash's avatar George Nash

Merge remote-tracking branch 'origin/master' into swig

parents b7d9fc26 544ada95
Pipeline #786 passed with stage
in 7 minutes and 29 seconds
---
image: gcc
image: gcc:9.3.0
Linux_Secured_Test:
variables:
GIT_SUBMODULE_STRATEGY: normal
stage: build
before_script:
- apt update && apt -y install make autoconf
......@@ -13,6 +15,8 @@ Linux_Secured_Test:
- make DYNAMIC=1 IPV4=1 TCP=1 SECURE=1 test
Linux_Unsecured_Test:
variables:
GIT_SUBMODULE_STRATEGY: normal
stage: build
before_script:
- apt update && apt -y install make autoconf
......@@ -24,29 +28,33 @@ Linux_Unsecured_Test:
- 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
variables:
GIT_SUBMODULE_STRATEGY: normal
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 patch
- 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:
variables:
GIT_SUBMODULE_STRATEGY: none
stage: build
before_script:
- apt update && apt -y install make autoconf doxygen clang-format
......
......@@ -113,7 +113,7 @@ cloud_deregister_on_reset_internal(oc_cloud_context_t *ctx,
cloud_store_initialize(&ctx->store);
cloud_manager_stop(ctx);
ctx->last_error = 0;
ctx->cps = 0;
ctx->store.cps = 0;
}
#endif /* OC_SECURITY */
......@@ -137,7 +137,7 @@ oc_cloud_reset_context(size_t device)
cloud_store_initialize(&ctx->store);
cloud_manager_stop(ctx);
ctx->last_error = 0;
ctx->cps = 0;
ctx->store.cps = 0;
return 0;
}
......@@ -168,7 +168,7 @@ oc_cloud_provision_conf_resource(oc_cloud_context_t *ctx, const char *server,
}
ctx->store.status = OC_CLOUD_INITIALIZED;
ctx->cps = OC_CPS_READYTOREGISTER;
ctx->store.cps = OC_CPS_READYTOREGISTER;
cloud_store_dump_async(&ctx->store);
......@@ -204,7 +204,7 @@ cloud_update_by_resource(oc_cloud_context_t *ctx,
cloud_set_string(&ctx->store.sid, data->sid, data->sid_len);
}
ctx->store.status = OC_CLOUD_INITIALIZED;
ctx->cps = OC_CPS_READYTOREGISTER;
ctx->store.cps = OC_CPS_READYTOREGISTER;
if (ctx->cloud_manager) {
cloud_reconnect(ctx);
}
......
......@@ -70,12 +70,16 @@ free_api_param(cloud_api_param_t *p)
int
conv_cloud_endpoint(oc_cloud_context_t *ctx)
{
int ret = 0;
oc_endpoint_t ep;
memset(&ep, 0, sizeof(oc_endpoint_t));
if (memcmp(&ep, ctx->cloud_ep, sizeof(oc_endpoint_t)) == 0) {
return oc_string_to_endpoint(&ctx->store.ci_server, ctx->cloud_ep, NULL);
ret = oc_string_to_endpoint(&ctx->store.ci_server, ctx->cloud_ep, NULL);
#ifdef OC_DNS_CACHE
oc_dns_clear_cache();
#endif /* OC_DNS_CACHE */
}
return 0;
return ret;
}
int
......@@ -105,7 +109,7 @@ oc_cloud_register(oc_cloud_context_t *ctx, oc_cloud_cb_t cb, void *data)
oc_string(ctx->store.uid), oc_string(ctx->store.access_token),
ctx->device, oc_cloud_register_handler, p)) {
cannotConnect = false;
ctx->cps = OC_CPS_REGISTERING;
ctx->store.cps = OC_CPS_REGISTERING;
}
if (cannotConnect) {
cloud_set_last_error(ctx, CLOUD_ERROR_CONNECT);
......@@ -227,17 +231,15 @@ cloud_deregistered_internal(oc_client_response_t *data)
{
cloud_api_param_t *p = (cloud_api_param_t *)data->user_data;
oc_cloud_context_t *ctx = p->ctx;
if (data->code >= OC_STATUS_SERVICE_UNAVAILABLE) {
cloud_set_last_error(ctx, CLOUD_ERROR_CONNECT);
ctx->store.status |= OC_CLOUD_FAILURE;
if (data->code < OC_STATUS_BAD_REQUEST ||
data->code >= OC_STATUS_SERVICE_UNAVAILABLE) {
ctx->store.status = OC_CLOUD_DEREGISTERED;
} else if (data->code >= OC_STATUS_BAD_REQUEST) {
cloud_set_last_error(ctx, CLOUD_ERROR_RESPONSE);
ctx->store.status |= OC_CLOUD_FAILURE;
} else {
ctx->store.status = OC_CLOUD_DEREGISTERED;
}
ctx->cps = OC_CPS_READYTOREGISTER;
ctx->store.cps = OC_CPS_READYTOREGISTER;
if (p->cb) {
p->cb(ctx, ctx->store.status, p->data);
......@@ -245,6 +247,8 @@ cloud_deregistered_internal(oc_client_response_t *data)
free_api_param(p);
ctx->store.status &= ~(OC_CLOUD_FAILURE | OC_CLOUD_DEREGISTERED);
cloud_store_dump_async(&ctx->store);
}
int
......@@ -318,6 +322,25 @@ oc_cloud_refresh_token(oc_cloud_context_t *ctx, oc_cloud_cb_t cb, void *data)
return -1;
}
int
oc_cloud_discover_resources(oc_cloud_context_t *ctx,
oc_discovery_all_handler_t handler, void *user_data)
{
if (!ctx) {
return -1;
}
if (!(ctx->store.status & OC_CLOUD_LOGGED_IN)) {
return -1;
}
if (oc_do_ip_discovery_all_at_endpoint(handler, ctx->cloud_ep, user_data)) {
return 0;
}
return -1;
}
/* Internal APIs for accessing the OCF Cloud */
bool
cloud_access_register(oc_endpoint_t *endpoint, const char *auth_provider,
......@@ -339,7 +362,9 @@ cloud_access_register(oc_endpoint_t *endpoint, const char *auth_provider,
}
#ifdef OC_SECURITY
oc_tls_select_cloud_ciphersuite();
if (!oc_tls_connected(endpoint)) {
oc_tls_select_cloud_ciphersuite();
}
#endif /* OC_SECURITY */
if (oc_init_post(OC_RSRVD_ACCOUNT_URI, endpoint, NULL, handler, LOW_QOS,
......@@ -384,23 +409,32 @@ cloud_access_deregister(oc_endpoint_t *endpoint, const char *uid,
OC_ERR("Error of input parameters");
return false;
}
oc_string_t d;
(void)device;
oc_string_t at_uid;
oc_string_t at;
oc_concat_strings(&at, "accesstoken=", access_token);
oc_string_t u_id;
oc_concat_strings(&u_id, "&uid=", uid);
oc_concat_strings(&d, oc_string(at), oc_string(u_id));
oc_concat_strings(&at_uid, oc_string(at), oc_string(u_id));
char uuid[OC_UUID_LEN] = { 0 };
oc_uuid_to_str(oc_core_get_device_id(device), uuid, OC_UUID_LEN);
oc_string_t di;
oc_concat_strings(&di, "&di=", uuid);
oc_string_t at_uid_di;
oc_concat_strings(&at_uid_di, oc_string(at_uid), oc_string(di));
#ifdef OC_SECURITY
oc_tls_select_cloud_ciphersuite();
if (!oc_tls_connected(endpoint)) {
oc_tls_select_cloud_ciphersuite();
}
#endif /* OC_SECURITY */
bool s = oc_do_delete(OC_RSRVD_ACCOUNT_URI, endpoint, oc_string(d), handler,
HIGH_QOS, user_data);
oc_free_string(&d);
bool s = oc_do_delete(OC_RSRVD_ACCOUNT_URI, endpoint, oc_string(at_uid_di),
handler, HIGH_QOS, user_data);
oc_free_string(&at_uid);
oc_free_string(&at);
oc_free_string(&u_id);
oc_free_string(&di);
oc_free_string(&at_uid_di);
return s;
}
......@@ -422,7 +456,9 @@ cloud_access_login_out(oc_endpoint_t *endpoint, const char *uid,
}
#ifdef OC_SECURITY
oc_tls_select_cloud_ciphersuite();
if (!oc_tls_connected(endpoint)) {
oc_tls_select_cloud_ciphersuite();
}
#endif /* OC_SECURITY */
if (oc_init_post(OC_RSRVD_ACCOUNT_SESSION_URI, endpoint, NULL, handler,
......@@ -481,7 +517,9 @@ cloud_access_refresh_access_token(oc_endpoint_t *endpoint, const char *uid,
}
#ifdef OC_SECURITY
oc_tls_select_cloud_ciphersuite();
if (!oc_tls_connected(endpoint)) {
oc_tls_select_cloud_ciphersuite();
}
#endif /* OC_SECURITY */
if (oc_init_post(OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI, endpoint, NULL, handler,
......
......@@ -146,8 +146,6 @@ _register_handler(oc_cloud_context_t *ctx, oc_client_response_t *data)
oc_rep_t *payload = data->payload;
ctx->store.status = 0;
char *value = NULL;
size_t size = 0;
......@@ -195,12 +193,14 @@ _register_handler(oc_cloud_context_t *ctx, oc_client_response_t *data)
cloud_set_last_error(ctx, CLOUD_OK);
ctx->store.status |= OC_CLOUD_REGISTERED;
ctx->cps = OC_CPS_REGISTERED;
ctx->store.cps = OC_CPS_REGISTERED;
oc_notify_observers(ctx->cloud_conf);
return 0;
error:
ctx->cps = OC_CPS_FAILED;
ctx->store.cps = OC_CPS_FAILED;
ctx->store.status |= OC_CLOUD_FAILURE;
if (ctx->last_error == 0) {
cloud_set_last_error(ctx, CLOUD_ERROR_RESPONSE);
......@@ -259,7 +259,7 @@ cloud_register(void *data)
oc_string(ctx->store.uid), oc_string(ctx->store.access_token),
ctx->device, cloud_register_handler, data)) {
cannotConnect = false;
ctx->cps = OC_CPS_REGISTERING;
ctx->store.cps = OC_CPS_REGISTERING;
}
if (cannotConnect) {
cloud_set_last_error(ctx, CLOUD_ERROR_CONNECT);
......@@ -297,7 +297,7 @@ _login_handler(oc_cloud_context_t *ctx, oc_client_response_t *data)
return 0;
error:
ctx->cps = OC_CPS_FAILED;
ctx->store.cps = OC_CPS_FAILED;
ctx->store.status |= OC_CLOUD_FAILURE;
if (ctx->last_error == 0) {
cloud_set_last_error(ctx, CLOUD_ERROR_RESPONSE);
......@@ -430,7 +430,7 @@ error:
if (ctx->last_error == 0) {
cloud_set_last_error(ctx, CLOUD_ERROR_REFRESH_ACCESS_TOKEN);
}
ctx->cps = OC_CPS_FAILED;
ctx->store.cps = OC_CPS_FAILED;
ctx->store.status |= OC_CLOUD_FAILURE;
return -1;
}
......
......@@ -66,7 +66,7 @@ cloud_response(oc_cloud_context_t *ctx)
root, sid, (oc_string(ctx->store.sid) ? oc_string(ctx->store.sid) : ""));
oc_rep_set_int(root, clec, (int)ctx->last_error);
const char *cps = cps_to_str(ctx->cps);
const char *cps = cps_to_str(ctx->store.cps);
if (cps) {
oc_rep_set_text_string(root, cps, cps);
}
......@@ -145,7 +145,7 @@ post_cloud(oc_request_t *request, oc_interface_mask_t interface,
OC_DBG("POST request received");
(void)interface;
switch (ctx->cps) {
switch (ctx->store.cps) {
case OC_CPS_UNINITIALIZED:
case OC_CPS_READYTOREGISTER:
case OC_CPS_FAILED:
......
......@@ -64,10 +64,12 @@ encode_cloud_with_map(CborEncoder *object_map, const oc_cloud_store_t *store)
oc_rep_set_text_string(*object, auth_provider,
oc_string(store->auth_provider));
oc_rep_set_text_string(*object, uid, oc_string(store->uid));
oc_rep_set_text_string(*object, sid, oc_string(store->sid));
oc_rep_set_text_string(*object, access_token, oc_string(store->access_token));
oc_rep_set_text_string(*object, refresh_token,
oc_string(store->refresh_token));
oc_rep_set_int(*object, status, store->status);
oc_rep_set_int(*object, cps, store->cps);
}
static void
......@@ -145,6 +147,9 @@ cloud_store_decode(oc_rep_t *rep, oc_cloud_store_t *store)
if (len == 9 && memcmp(oc_string(t->name), "ci_server", 9) == 0) {
cloud_set_string(&store->ci_server, oc_string(t->value.string),
oc_string_len(t->value.string));
} else if (len == 3 && memcmp(oc_string(t->name), "sid", 3) == 0) {
cloud_set_string(&store->sid, oc_string(t->value.string),
oc_string_len(t->value.string));
} else if (len == 13 &&
memcmp(oc_string(t->name), "auth_provider", 13) == 0) {
cloud_set_string(&store->auth_provider, oc_string(t->value.string),
......@@ -168,6 +173,8 @@ cloud_store_decode(oc_rep_t *rep, oc_cloud_store_t *store)
case OC_REP_INT:
if (len == 6 && memcmp(oc_string(t->name), "status", 6) == 0) {
store->status = (uint8_t)t->value.integer;
} else if (len == 3 && memcmp(oc_string(t->name), "cps", 3) == 0) {
store->cps = (uint8_t)t->value.integer;
} else {
OC_ERR("[CLOUD_STORE] Unknown property %s", oc_string(t->name));
return -1;
......
......@@ -586,33 +586,12 @@ oc_ri_process_discovery_payload(uint8_t *payload, int len,
rep = rep->next;
}
oc_rep_t *link = links->value.object;
while (link != NULL) {
switch (link->type) {
case OC_REP_STRING: {
if (oc_string_len(link->name) == 6 &&
memcmp(oc_string(link->name), "anchor", 6) == 0) {
anchor = &link->value.string;
}
} break;
default:
break;
}
if (anchor) {
break;
}
link = link->next;
}
oc_uuid_t di;
oc_str_to_uuid(oc_string(*anchor) + 6, &di);
while (links != NULL) {
/* Reset bm in every round as this can be omitted if 0. */
oc_uuid_t di;
oc_resource_properties_t bm = 0;
oc_endpoint_t *eps_list = NULL;
link = links->value.object;
oc_rep_t *link = links->value.object;
while (link != NULL) {
switch (link->type) {
......@@ -620,6 +599,7 @@ oc_ri_process_discovery_payload(uint8_t *payload, int len,
if (oc_string_len(link->name) == 6 &&
memcmp(oc_string(link->name), "anchor", 6) == 0) {
anchor = &link->value.string;
oc_str_to_uuid(oc_string(*anchor) + 6, &di);
} else if (oc_string_len(link->name) == 4 &&
memcmp(oc_string(link->name), "href", 4) == 0) {
uri = &link->value.string;
......@@ -653,8 +633,9 @@ oc_ri_process_discovery_payload(uint8_t *payload, int len,
memcmp(oc_string(ep->name), "ep", 2) == 0) {
if (oc_string_to_endpoint(&ep->value.string, &temp_ep, NULL) ==
0) {
if (((endpoint->flags & IPV4) && (temp_ep.flags & IPV6)) ||
((endpoint->flags & IPV6) && (temp_ep.flags & IPV4))) {
if (!(temp_ep.flags & TCP) &&
(((endpoint->flags & IPV4) && (temp_ep.flags & IPV6)) ||
((endpoint->flags & IPV6) && (temp_ep.flags & IPV4)))) {
goto next_ep;
}
if (eps_cur) {
......@@ -721,6 +702,9 @@ oc_ri_process_discovery_payload(uint8_t *payload, int len,
done:
oc_free_rep(p);
#ifdef OC_DNS_CACHE
oc_dns_clear_cache();
#endif /* OC_DNS_CACHE */
return ret;
}
#endif /* OC_CLIENT */
......@@ -557,7 +557,7 @@ oc_ipv6_endpoint_is_link_local(oc_endpoint_t *endpoint)
}
int
oc_endpoint_compare_address(oc_endpoint_t *ep1, oc_endpoint_t *ep2)
oc_endpoint_compare_address(const oc_endpoint_t *ep1, const oc_endpoint_t *ep2)
{
if (!ep1 || !ep2)
return -1;
......
......@@ -42,7 +42,7 @@ gen_idd_tag(const char *name, size_t device_index, char *idd_tag)
snprintf(idd_tag, MAX_TAG_LENGTH, "%s_%zd", name, device_index);
idd_tag_len =
(idd_tag_len < MAX_TAG_LENGTH) ? idd_tag_len + 1 : MAX_TAG_LENGTH;
idd_tag[idd_tag_len] = '\0';
idd_tag[idd_tag_len - 1] = '\0';
}
void
......
/*
// Copyright (c) 2020 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 "oc_core_res.h"
#include "port/oc_clock.h"
#include "oc_pki.h"
#include "oc_introspection.h"
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static pthread_t event_thread;
static pthread_mutex_t app_sync_lock;
static pthread_mutex_t mutex;
static pthread_cond_t cv;
static struct timespec ts;
static int quit = 0;
typedef struct resource_t
{
struct resource_t *next;
oc_endpoint_t *endpoint;
char uri[64];
} resource_t;
OC_LIST(resources);
OC_MEMB(resources_m, resource_t, 100);
static void
free_resource(resource_t *res)
{
oc_free_server_endpoints(res->endpoint);
oc_memb_free(&resources_m, res);
}
static void
free_all_resources(void)
{
resource_t *l = (resource_t *)oc_list_pop(resources);
while (l != NULL) {
free_resource(l);
l = (resource_t *)oc_list_pop(resources);
}
}
static int
app_init(void)
{
int ret = oc_init_platform("OCF", NULL, NULL);
ret |= oc_add_device("/oic/d", "oic.wk.d", "OCFTestClient", "ocf.2.0.5",
"ocf.res.1.3.0,ocf.sh.1.3.0", NULL, NULL);
#if defined(OC_IDD_API)
FILE *fp;
uint8_t *buffer;
size_t buffer_size;
const char introspection_error[] =
"\tERROR Could not read client_certification_tests_IDD.cbor\n"
"\tIntrospection data not set for device.\n";
fp = fopen("./client_certification_tests_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
return ret;
}
#define SCANF(...) \
do { \
if (scanf(__VA_ARGS__) != 1) { \
PRINT("ERROR Invalid input\n"); \
} \
} while (0)
static void
display_menu(void)
{
PRINT("\n\n################################################\nClient "
"Certification Tests"
"\n################################################\n");
PRINT("[0] Display this menu\n");
PRINT("-----------------------------------------------\n");
PRINT("[1] Discover resources\n");
PRINT("-----------------------------------------------\n");
PRINT("[2] GET resource UDP\n");
PRINT("[3] GET resource TCP\n");
PRINT("[4] POST binary switch UDP\n");
PRINT("[5] POST binary switch TCP\n");
PRINT("[6] Start OBSERVE resource UDP\n");
PRINT("[7] Stop OBSERVE resource UDP\n");
PRINT("[8] Start OBSERVE resource TCP\n");
PRINT("[9] Stop OBSERVE resource TCP\n");
PRINT("-----------------------------------------------\n");
PRINT("[10] Exit\n");
PRINT("################################################\n");
PRINT("\nSelect option: \n");
}
static void
show_discovered_resources(resource_t **res)
{
PRINT("\nDiscovered resources:\n");
resource_t *l = (resource_t *)oc_list_head(resources);
int i = 0;
PRINT("\n\n");
while (l != NULL) {
if (res != NULL) {
res[i] = l;
}
PRINT("[%d]: %s", i, l->uri);
oc_endpoint_t *ep = l->endpoint;
while (ep != NULL) {
PRINT("\n\t\t");
PRINTipaddr(*ep);
ep = ep->next;
}
PRINT("\n\n");
i++;
l = l->next;
}
}
static void
signal_event_loop(void)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cv);
pthread_mutex_unlock(&mutex);
}
static void
handle_signal(int signal)
{
(void)signal;
signal_event_loop();
quit = 1;
}
static void *