Commit ad93eded authored by George Nash's avatar George Nash Committed by Kishen Maloor

Add introspection data to smart_home_server_linux sample

In addition to adding the introspection data this makes
the OC_IDD_API a default option for the Linux build.

This change additionally adds a new introspection client that retrieves
the introspection data from servers and prints it out.
Signed-off-by: George Nash's avatarGeorge Nash <george.nash@intel.com>
parent acc7b653
Pipeline #478 passed with stage
in 6 minutes and 12 seconds
/*
// 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.0.5",
"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;
......@@ -510,7 +543,7 @@ register_resources(void)
oc_resource_set_request_handler(temp_resource, OC_GET, get_temp, NULL);
oc_resource_set_request_handler(temp_resource, OC_POST, post_temp, NULL);
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);
......@@ -520,7 +553,7 @@ register_resources(void)
oc_resource_set_request_handler(bswitch, OC_GET, get_switch, NULL);
oc_resource_set_request_handler(bswitch, OC_POST, post_switch, NULL);
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");
......@@ -544,6 +577,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 */
}
......@@ -689,7 +723,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");
......@@ -705,10 +740,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);
......
......@@ -12,6 +12,7 @@ VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
DYNAMIC ?= 1
export SECURE ?= 1
export PKI ?= 1
IDD ?= 1
DESTDIR ?= /usr/local
install_bin_dir?=${DESTDIR}/opt/iotivity-lite/bin/
prefix = $(DESTDIR)
......@@ -111,7 +112,7 @@ OBJ_CLIENT_SERVER=$(addprefix obj/client_server/,$(notdir $(SRC:.c=.o)))
VPATH=../../messaging/coap/:../../util/:../../api/:../../deps/tinycbor/src/:../../deps/mbedtls/library:../../api/c-timestamp:../../service/cloud/src/:../../service/resource-directory/client/src/:
LIBS?= -lm -pthread -lrt
SAMPLES = server client temp_sensor simpleserver simpleserver_pki simpleclient client_collections_linux \
SAMPLES = server client temp_sensor simpleserver simpleserver_pki simpleclient client_collections_linux introspectionclient\
server_collections_linux server_block_linux client_block_linux smart_home_server_linux multi_device_server multi_device_client smart_lock server_multithread_linux client_multithread_linux
ifeq ($(CREATE),1)
......@@ -259,6 +260,9 @@ copy_pki_certs:
@mkdir -p pki_certs
@cp ../../apps/pki_certs/*.pem pki_certs/
copy_idd_files:
@cp ../../apps/smart_home_server_linux_IDD.cbor .
${SRC} ${SRC_COMMON}: $(MBEDTLS_PATCH_FILE)
obj/%.o: %.c
......@@ -331,6 +335,10 @@ simpleclient: libiotivity-lite-client.a $(ROOT_DIR)/apps/simpleclient.c
@mkdir -p $@_creds
${CC} -o $@ ../../apps/simpleclient.c libiotivity-lite-client.a -DOC_CLIENT ${CFLAGS} ${LIBS}
introspectionclient: libiotivity-lite-client.a $(ROOT_DIR)/apps/introspectionclient.c
@mkdir -p $@_creds
${CC} -o $@ ../../apps/introspectionclient.c libiotivity-lite-client.a -DOC_CLIENT ${CFLAGS} ${LIBS}
client_collections_linux: libiotivity-lite-client.a $(ROOT_DIR)/apps/client_collections_linux.c
@mkdir -p $@_creds
${CC} -o $@ ../../apps/client_collections_linux.c libiotivity-lite-client.a -DOC_CLIENT ${CFLAGS} ${LIBS}
......@@ -345,7 +353,7 @@ client_block_linux: libiotivity-lite-client.a $(ROOT_DIR)/apps/client_block_linu
server_block_linux: libiotivity-lite-server.a $(ROOT_DIR)/apps/server_block_linux.c
${CC} -o $@ ../../apps/server_block_linux.c libiotivity-lite-server.a -DOC_SERVER ${CFLAGS} ${LIBS}
smart_home_server_linux: libiotivity-lite-server.a $(ROOT_DIR)/apps/smart_home_server_linux.c copy_pki_certs
smart_home_server_linux: libiotivity-lite-server.a $(ROOT_DIR)/apps/smart_home_server_linux.c copy_pki_certs copy_idd_files
@mkdir -p $@_creds
${CC} -o $@ ../../apps/smart_home_server_linux.c libiotivity-lite-server.a -DOC_SERVER ${CFLAGS} ${LIBS}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment