/**************************************************************************** * * Copyright 2019 Jozef Kralik All Rights Reserved. * Copyright 2018 Samsung Electronics All Rights Reserved. * * 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 "cloud.h" #include "oc_api.h" #include "oc_core_res.h" #include "port/oc_clock.h" #include "rd_client.h" #include #include #include // define application specific values. static const char *spec_version = "ocf.1.0.0"; static const char *data_model_version = "ocf.res.1.0.0"; static const char *resource_rt = "core.light"; static const char *device_rt = "oic.d.cloudDevice"; static const char *device_name = "Cloud Device"; static const char *manufacturer = "ocfcloud.com"; pthread_mutex_t mutex; pthread_cond_t cv; oc_resource_t *res1; oc_resource_t *res2; int quit = 0; static void cloud_status_handler(cloud_status_t status, void *user_data) { (void)user_data; printf("cloud_status: %d\n", (int)status); } static int app_init(void) { int ret = oc_init_platform(manufacturer, NULL, NULL); ret |= oc_add_device("/oic/d", device_rt, device_name, spec_version, data_model_version, NULL, NULL); ret |= cloud_init(0, cloud_status_handler, NULL); return ret; } struct light_t { bool state; int power; }; struct light_t light1 = {0}; struct light_t light2 = {0}; static void get_handler(oc_request_t *request, oc_interface_mask_t interface, void *user_data) { struct light_t *light = (struct light_t *)user_data; printf("get_handler:\n"); oc_rep_start_root_object(); switch (interface) { case OC_IF_BASELINE: oc_process_baseline_interface(request->resource); /* fall through */ case OC_IF_RW: oc_rep_set_boolean(root, state, light->state); oc_rep_set_int(root, power, light->power); oc_rep_set_text_string(root, name, "Light"); break; default: break; } oc_rep_end_root_object(); oc_send_response(request, OC_STATUS_OK); } static void post_handler(oc_request_t *request, oc_interface_mask_t iface_mask, void *user_data) { struct light_t *light = (struct light_t *)user_data; (void)iface_mask; printf("post_handler:\n"); oc_rep_t *rep = request->request_payload; while (rep != NULL) { char *key = oc_string(rep->name); printf("key: %s ", key); if (key && !strcmp(key, "state")) { switch (rep->type) { case OC_REP_BOOL: light->state = rep->value.boolean; printf("value: %d\n", light->state); break; default: oc_send_response(request, OC_STATUS_BAD_REQUEST); return; } } else if (key && !strcmp(key, "power")) { switch (rep->type) { case OC_REP_INT: light->power = rep->value.integer; printf("value: %d\n", light->power); break; default: oc_send_response(request, OC_STATUS_BAD_REQUEST); return; } } rep = rep->next; } oc_send_response(request, OC_STATUS_CHANGED); oc_notify_observers(request->resource); } static void register_resources(void) { res1 = oc_new_resource(NULL, "/light/1", 1, 0); oc_resource_bind_resource_type(res1, resource_rt); oc_resource_bind_resource_interface(res1, OC_IF_RW); oc_resource_set_default_interface(res1, OC_IF_RW); oc_resource_set_discoverable(res1, true); oc_resource_set_observable(res1, true); oc_resource_set_request_handler(res1, OC_GET, get_handler, &light1); oc_resource_set_request_handler(res1, OC_POST, post_handler, &light1); cloud_rd_publish(res1); oc_add_resource(res1); res2 = oc_new_resource(NULL, "/light/2", 1, 0); oc_resource_bind_resource_type(res2, resource_rt); oc_resource_bind_resource_interface(res2, OC_IF_RW); oc_resource_set_default_interface(res2, OC_IF_RW); oc_resource_set_discoverable(res2, true); oc_resource_set_observable(res2, true); oc_resource_set_request_handler(res2, OC_GET, get_handler, &light2); oc_resource_set_request_handler(res2, OC_POST, post_handler, &light2); cloud_rd_publish(res2); oc_add_resource(res2); } 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, .register_resources = register_resources}; oc_storage_config("./cloud_linux_creds"); if (pthread_mutex_init(&mutex, NULL) < 0) { printf("pthread_mutex_init failed!\n"); return -1; } init = oc_main_init(&handler); if (init < 0) return init; while (quit != 1) { oc_clock_time_t next_event = oc_main_poll(); pthread_mutex_lock(&mutex); if (next_event == 0) { pthread_cond_wait(&cv, &mutex); } else { struct timespec ts; 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); } cloud_shutdown(0); oc_main_shutdown(); return 0; }