From 3be0567f33dc085d160c9478ac5e8d394cb8804c Mon Sep 17 00:00:00 2001 From: Youngjae Shin Date: Mon, 8 Jun 2015 19:38:29 +0900 Subject: [PATCH] Initial Code Change-Id: Ia03df5531ee84ec2fc6b1aa34096224b6526c907 --- .gitignore | 3 + CMakeLists.txt | 18 + LICENSE.APLv2 | 204 +++++++++ NOTICE | 3 + daemon/CMakeLists.txt | 25 + lib/CMakeLists.txt | 23 + lib/ic-common.h | 26 ++ lib/ic-handler.c | 51 +++ lib/ic-handler.h | 25 + lib/ic-ioty-rep.cpp | 172 +++++++ lib/ic-ioty-rep.h | 27 ++ lib/ic-ioty.cpp | 1017 +++++++++++++++++++++++++++++++++++++++++ lib/ic-ioty.h | 98 ++++ lib/ic-log.h | 138 ++++++ lib/ic-rep-list.c | 445 ++++++++++++++++++ lib/ic-rep-list.h | 32 ++ lib/ic-rep-value.c | 326 +++++++++++++ lib/ic-rep-value.h | 51 +++ lib/ic-rep.c | 886 +++++++++++++++++++++++++++++++++++ lib/ic-rep.h | 40 ++ lib/ic-struct.h | 70 +++ lib/ic-utils.c | 49 ++ lib/ic-utils.h | 24 + lib/ic.c | 807 ++++++++++++++++++++++++++++++++ lib/include/iotcon-constant.h | 84 ++++ lib/include/iotcon-errors.h | 36 ++ lib/include/iotcon-struct.h | 111 +++++ lib/include/iotcon.h | 230 ++++++++++ lib/iotcon.pc.in | 11 + packaging/iotcon.manifest | 24 + packaging/iotcon.spec | 57 +++ test/CMakeLists.txt | 20 + test/crud-test-client.c | 195 ++++++++ test/crud-test-server.c | 115 +++++ test/test-log.h | 129 ++++++ 35 files changed, 5572 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100644 daemon/CMakeLists.txt create mode 100644 lib/CMakeLists.txt create mode 100644 lib/ic-common.h create mode 100644 lib/ic-handler.c create mode 100644 lib/ic-handler.h create mode 100644 lib/ic-ioty-rep.cpp create mode 100644 lib/ic-ioty-rep.h create mode 100644 lib/ic-ioty.cpp create mode 100644 lib/ic-ioty.h create mode 100644 lib/ic-log.h create mode 100644 lib/ic-rep-list.c create mode 100644 lib/ic-rep-list.h create mode 100644 lib/ic-rep-value.c create mode 100644 lib/ic-rep-value.h create mode 100644 lib/ic-rep.c create mode 100644 lib/ic-rep.h create mode 100644 lib/ic-struct.h create mode 100644 lib/ic-utils.c create mode 100644 lib/ic-utils.h create mode 100644 lib/ic.c create mode 100644 lib/include/iotcon-constant.h create mode 100644 lib/include/iotcon-errors.h create mode 100644 lib/include/iotcon-struct.h create mode 100644 lib/include/iotcon.h create mode 100644 lib/iotcon.pc.in create mode 100644 packaging/iotcon.manifest create mode 100644 packaging/iotcon.spec create mode 100644 test/CMakeLists.txt create mode 100644 test/crud-test-client.c create mode 100644 test/crud-test-server.c create mode 100644 test/test-log.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de565f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +cscope.out +*~ +*.sw* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7f299ba --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(iotcon) + +INCLUDE(FindPkgConfig) + +SET(EXTRA_CFLAGS "-Wall -Werror-implicit-function-declaration -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--hash-style=both") + +SET(CLIENT ${PROJECT_NAME}) +SET(DAEMON "${PROJECT_NAME}-daemon") +SET(DBUS_INTERFACE "org.tizen.${PROJECT_NAME}") + +ADD_SUBDIRECTORY(lib) +#ADD_SUBDIRECTORY(daemon) +ADD_SUBDIRECTORY(test) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..26b7de6 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..eff0219 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache license, version 2 terms and conditions. diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt new file mode 100644 index 0000000..08f7b67 --- /dev/null +++ b/daemon/CMakeLists.txt @@ -0,0 +1,25 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common/) + +SET(OCLIB "oc") +SET(OCLOGGER "oc_logger") +SET(OCLOGGER_CORE "oc_logger_core") +SET(COAP "coap") +SET(OCTBSTACK "octbstack") + +FILE(GLOB DAEMON_SRCS *.c *.cpp) + +pkg_check_modules(daemon_pkgs REQUIRED gio-2.0 dlog) +INCLUDE_DIRECTORIES(${daemon_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${daemon_pkgs_LIBRARY_DIRS}) + +ADD_DEFINITIONS("-DENOTICE_DBUS_INTERFACE=\"${DBUS_INTERFACE}\"") + +ADD_EXECUTABLE(${DAEMON} ${DAEMON_SRCS}) +TARGET_LINK_LIBRARIES(${DAEMON} ${daemon_pkgs_LIBRARIES} ${OCLIB} ${OCLOGGER} + ${OCLOGGER_CORE} ${COAP} ${OCTBSTACK}) + +INSTALL(TARGETS ${DAEMON} DESTINATION ${BIN_INSTALL_DIR}) + +SET(DBUS_SERVICE_FILE "org.tizen.${PROJECT_NAME}") +CONFIGURE_FILE(${DBUS_SERVICE_FILE}.service.in ${DBUS_SERVICE_FILE}.service @ONLY) +INSTALL(FILES ${DBUS_SERVICE_FILE}.service DESTINATION ${SHARE_INSTALL_PREFIX}/dbus-1/services) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..beaf170 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,23 @@ +INCLUDE_DIRECTORIES(include) + +FILE(GLOB CLIENT_SRCS *.c *.cpp) + +pkg_check_modules(client_pkgs REQUIRED glib-2.0 dlog json-glib-1.0) +INCLUDE_DIRECTORIES(${client_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${client_pkgs_LIBRARY_DIRS}) + +ADD_DEFINITIONS("-DENOTICE_DBUS_INTERFACE=\"${DBUS_INTERFACE}\"") + +ADD_LIBRARY(${CLIENT} SHARED ${CLIENT_SRCS}) +TARGET_LINK_LIBRARIES(${CLIENT} + ${client_pkgs_LIBRARIES} + oc octbstack coap oc_logger_core oc_logger pthread) +SET_TARGET_PROPERTIES(${CLIENT} PROPERTIES VERSION ${FULLVER} SOVERSION ${MAJORVER}) +INSTALL(TARGETS ${CLIENT} DESTINATION ${LIB_INSTALL_DIR}) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +CONFIGURE_FILE(${CLIENT}.pc.in ${CLIENT}.pc @ONLY) +INSTALL(FILES ${CLIENT}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +FILE(GLOB CLIENT_HEADER include/*.h) +INSTALL(FILES ${CLIENT_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/${CLIENT}) diff --git a/lib/ic-common.h b/lib/ic-common.h new file mode 100644 index 0000000..87711f4 --- /dev/null +++ b/lib/ic-common.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_COMMON_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_COMMON_H__ + +#include "ic-log.h" + +#ifdef API +#undef API +#endif +#define API __attribute__((visibility("default"))) + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_COMMON_H__ diff --git a/lib/ic-handler.c b/lib/ic-handler.c new file mode 100644 index 0000000..b9b21f1 --- /dev/null +++ b/lib/ic-handler.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 "iotcon.h" + +#include "ic-common.h" +#include "ic-ioty.h" +#include "ic-handler.h" + +static gboolean _find_valid_resource(gpointer key, gpointer value, gpointer user_data) +{ + return (key == user_data); +} + +resource_handler_s* ic_get_resource_handler_data(void *handle) +{ + resource_handler_s *handler; + ic_ctx_s *ic_ctx = ic_get_ctx(); + + handler = g_hash_table_find(ic_ctx->entity_cb_hash, _find_valid_resource, handle); + return handler; +} + +void ic_get_device_info_handler(iotcon_device_info_s *info) +{ + FN_CALL; + ic_ctx_s *ic_ctx = ic_get_ctx(); + iotcon_found_device_info_cb notify_cb = NULL; + + GList *node = g_list_first(ic_ctx->found_device_cb_lst); + while (node) { + notify_cb = node->data; + if (notify_cb) + notify_cb(info); + + node = node->next; + } +} diff --git a/lib/ic-handler.h b/lib/ic-handler.h new file mode 100644 index 0000000..729988e --- /dev/null +++ b/lib/ic-handler.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_HANDLER_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_HANDLER_H__ + +#include "ic-ioty.h" + +resource_handler_s* ic_get_resource_handler_data(void *handle); + +void ic_get_device_info_handler(iotcon_device_info_s *info); + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_HANDLER_H__ diff --git a/lib/ic-ioty-rep.cpp b/lib/ic-ioty-rep.cpp new file mode 100644 index 0000000..fe0a0c7 --- /dev/null +++ b/lib/ic-ioty-rep.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include + +#include "iotcon.h" +extern "C" { +#include "ic-common.h" +#include "ic-utils.h" +#include "ic-rep.h" +#include "ic-handler.h" +} +#include "ic-ioty-rep.h" + +using namespace OC; +using namespace std; + +static iotcon_repr_h _ic_ioty_repr_create_repr(const OCRepresentation& ocRep) +{ + FN_CALL; + // incoming json format example : {"href":"/a/address","rep":{"text":"Hello world"}} + string jsonStr = ocRep.getJSONRepresentation(); + iotcon_repr_h repr = ic_repr_parse_json(jsonStr.c_str()); + + string uriStr = ocRep.getUri(); + if (!uriStr.empty()) + iotcon_repr_set_uri(repr, uriStr.c_str()); + + return repr; +} + +static iotcon_repr_h _ic_ioty_repr_create_parent(const OCRepresentation& ocRep) +{ + FN_CALL; + return _ic_ioty_repr_create_repr(ocRep); +} + +static iotcon_repr_h _ic_ioty_repr_create_child(const OCRepresentation& ocRep) +{ + FN_CALL; + return _ic_ioty_repr_create_repr(ocRep); +} + +iotcon_repr_h ic_ioty_repr_generate_repr(const OCRepresentation& ocRep) +{ + FN_CALL; + unsigned int i = 0; + OCRepresentation ocChild; + + iotcon_repr_h repr_parent = _ic_ioty_repr_create_parent(ocRep); + + vector childList = ocRep.getChildren(); + + for (i = 0; i < childList.size(); i++) { + ocChild = childList.at(i); + iotcon_repr_h repr_child = _ic_ioty_repr_create_child(ocChild); + if (NULL == repr_child) { + ERR("_ic_ioty_repr_create_child() Fail"); + iotcon_repr_free(repr_parent); + return NULL; + } + + iotcon_repr_append_child(repr_parent, repr_child); + } + + return repr_parent; +} + +OCRepresentation ic_ioty_repr_parse(iotcon_repr_h repr) +{ + FN_CALL; + OCRepresentation ocRep; + MessageContainer info; + + // TODO: It's better that iotcon_repr_h is changed to + // OCRepresentation at once. + char *repr_json = ic_repr_generate_json(repr); + + try { + info.setJSONRepresentation(repr_json); + + const vector &reps = info.representations(); + if (0 < reps.size()) { + vector::const_iterator itr = reps.begin(); + vector::const_iterator back = reps.end(); + ocRep = *itr; + ++itr; + + for (; itr != back; ++itr) + ocRep.addChild(*itr); + } + else { + ERR("Invalid parameter(%s)", repr_json); + } + } catch (exception &e) { + ERR("setJSONRepresentation() Fail(%s)", e.what()); + } + + free(repr_json); + return ocRep; +} + +void ic_ioty_repr_found_device_cb(const OCRepresentation& ocRep) +{ + iotcon_device_info_s info = {0}; + string readbuf; + + if (ocRep.getValue("ct", readbuf)) + info.content_type = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mndt", readbuf)) + info.date_of_manufacture = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("dn", readbuf)) + info.device_name = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("di", readbuf)) + info.device_uuid = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnfv", readbuf)) + info.firmware_version = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("hn", readbuf)) + info.host_name = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnmn", readbuf)) + info.manufacturer_name = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnml", readbuf)) + info.manufacturer_url = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnmo", readbuf)) + info.model_number = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnpv", readbuf)) + info.platform_version = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("mnsl", readbuf)) + info.support_url = ic_utils_strdup(readbuf.c_str()); + + if (ocRep.getValue("icv", readbuf)) + info.version = ic_utils_strdup(readbuf.c_str()); + + ic_get_device_info_handler(&info); + + free(info.device_name); + free(info.host_name); + free(info.device_uuid); + free(info.content_type); + free(info.version); + free(info.manufacturer_name); + free(info.manufacturer_url); + free(info.model_number); + free(info.date_of_manufacture); + free(info.platform_version); + free(info.firmware_version); + free(info.support_url); +} + diff --git a/lib/ic-ioty-rep.h b/lib/ic-ioty-rep.h new file mode 100644 index 0000000..6e8a1eb --- /dev/null +++ b/lib/ic-ioty-rep.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_REPRESENTATION_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_REPRESENTATION_H__ + +#include +#include "iotcon-struct.h" + +void ic_ioty_repr_found_device_cb(const OC::OCRepresentation& ocRep); +iotcon_repr_h ic_ioty_repr_generate_repr(const OC::OCRepresentation& ocRep); +OC::OCRepresentation ic_ioty_repr_parse(iotcon_repr_h repr); + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_REPRESENTATION_H__ + diff --git a/lib/ic-ioty.cpp b/lib/ic-ioty.cpp new file mode 100644 index 0000000..0ecf9a5 --- /dev/null +++ b/lib/ic-ioty.cpp @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include +#include + +extern "C" { +#include "ic-common.h" +#include "ic-utils.h" +#include "ic-rep.h" +#include "ic-handler.h" +#include "ic-struct.h" +} +#include "ic-ioty-rep.h" +#include "ic-ioty.h" + +using namespace std; +using namespace OC; +using namespace OCPlatform; + +struct resource_handle { + OCResource::Ptr ocResource; +}; + +namespace icIotivityHandler { + + class presenceObject + { + private: + iotcon_presence_handle_cb presence_handler; + void *cb_data; + + public: + presenceObject(iotcon_presence_handle_cb user_cb, void *user_data) + { + presence_handler = user_cb; + cb_data = user_data; + } + + void presenceHandler(OCStackResult result, const unsigned int nonce, + const string& hostAddress) + { + iotcon_error_e ret; + + if (OC_STACK_OK != result) { + ERR("subscribePresence() result Fail(%d)", result); + ret = IOTCON_ERR_IOTIVITY; + } + else { + ret = IOTCON_ERR_NONE; + } + + if (presence_handler) + presence_handler(ret, nonce, hostAddress.c_str(), cb_data); + } + }; + + class findObject + { + private: + iotcon_found_resource_cb found_resource; + void *cb_data; + + public: + findObject(iotcon_found_resource_cb user_cb, void *user_data) + { + found_resource = user_cb; + cb_data = user_data; + } + + void foundResource(shared_ptr resource) + { + iotcon_resource_s resource_s = {0}; + + resource_s.resource_uri = ic_utils_strdup(resource->uri().c_str()); + resource_s.resource_host = ic_utils_strdup(resource->host().c_str()); + resource_s.is_observable = resource->isObservable(); + resource_s.resource_types = iotcon_new_resource_types(); + resource_s.resource_interfaces = iotcon_new_resource_interfaces(); + + vector resource_types = resource->getResourceTypes(); + for (string &resource_type : resource_types) + resource_s.resource_types + = iotcon_add_resource_types(resource_s.resource_types, + ic_utils_strdup(resource_type.c_str())); + + vector resource_interfaces = resource->getResourceInterfaces(); + for (string &resource_interface : resource_interfaces) + resource_s.resource_interfaces + = g_list_append(resource_s.resource_interfaces, + ic_utils_strdup(resource_interface.c_str())); + + if (found_resource) + found_resource(&resource_s, cb_data); + + free(resource_s.resource_uri); + free(resource_s.resource_host); + iotcon_delete_resource_types(resource_s.resource_types); + iotcon_delete_resource_interfaces(resource_s.resource_interfaces); + } + }; + + class getObject + { + private: + iotcon_on_get_cb on_get; + void *cb_data; + + public: + getObject(iotcon_on_get_cb user_cb, void *user_data) + { + on_get = user_cb; + cb_data = user_data; + } + + void onGet(const HeaderOptions& headerOptions, const OCRepresentation& ocRep, + const int eCode) + { + FN_CALL; + int res; + iotcon_header_options header_options; + iotcon_repr_h repr = NULL; + + if (OC_STACK_OK == eCode) + res = IOTCON_ERR_NONE; + else + res = IOTCON_ERR_IOTIVITY; + + header_options = iotcon_new_header_options(); + for (HeaderOption::OCHeaderOption option : headerOptions) { + iotcon_add_header_option(header_options, option.getOptionID(), + option.getOptionData().c_str()); + } + + repr = ic_ioty_repr_generate_repr(ocRep); + + if (on_get) + on_get(header_options, repr, res, cb_data); + + iotcon_delete_header_options(header_options); + } + }; + + class putObject + { + private: + iotcon_on_put_cb on_put; + void *cb_data; + + public: + putObject(iotcon_on_put_cb user_cb, void *user_data) + { + on_put = user_cb; + cb_data = user_data; + } + + void onPut(const HeaderOptions& headerOptions, const OCRepresentation& ocRep, + const int eCode) + { + FN_CALL; + int res; + iotcon_header_options header_options; + iotcon_repr_h repr = NULL; + + if (OC_STACK_OK == eCode) + res = IOTCON_ERR_NONE; + else + res = IOTCON_ERR_IOTIVITY; + + header_options = iotcon_new_header_options(); + for (HeaderOption::OCHeaderOption option : headerOptions) { + iotcon_add_header_option(header_options, option.getOptionID(), + option.getOptionData().c_str()); + } + + repr = ic_ioty_repr_generate_repr(ocRep); + + if (on_put) + on_put(header_options, repr, res, cb_data); + + iotcon_delete_header_options(header_options); + } + }; + + class postObject + { + private: + iotcon_on_post_cb on_post; + void *cb_data; + + public: + postObject(iotcon_on_post_cb user_cb, void *user_data) + { + on_post = user_cb; + cb_data = user_data; + } + + void onPost(const HeaderOptions& headerOptions, const OCRepresentation& ocRep, + const int eCode) + { + FN_CALL; + int res; + iotcon_header_options header_options; + iotcon_repr_h repr = NULL; + + if (OC_STACK_OK == eCode) + res = IOTCON_ERR_NONE; + else + res = IOTCON_ERR_IOTIVITY; + + header_options = iotcon_new_header_options(); + for (HeaderOption::OCHeaderOption option : headerOptions) { + iotcon_add_header_option(header_options, option.getOptionID(), + option.getOptionData().c_str()); + } + + repr = ic_ioty_repr_generate_repr(ocRep); + + if (on_post) + on_post(header_options, repr, res, cb_data); + + iotcon_delete_header_options(header_options); + } + }; + + class deleteObject + { + private: + iotcon_on_delete_cb on_delete; + void *cb_data; + + public: + deleteObject(iotcon_on_delete_cb user_cb, void *user_data) + { + on_delete = user_cb; + cb_data = user_data; + } + + void onDelete(const HeaderOptions& headerOptions, const int eCode) + { + int res; + iotcon_header_options header_options; + + if (OC_STACK_OK == eCode) + res = IOTCON_ERR_NONE; + else + res = IOTCON_ERR_IOTIVITY; + + header_options = iotcon_new_header_options(); + for (HeaderOption::OCHeaderOption option : headerOptions) { + iotcon_add_header_option(header_options, option.getOptionID(), + option.getOptionData().c_str()); + } + + if (on_delete) + on_delete(header_options, res, cb_data); + + iotcon_delete_header_options(header_options); + } + }; + + class observeObject + { + private: + iotcon_on_observe_cb on_observe; + void *cb_data; + + public: + observeObject(iotcon_on_observe_cb user_cb, void *user_data) + { + on_observe = user_cb; + cb_data = user_data; + } + + void onObserve(const HeaderOptions& headerOptions, const OCRepresentation& ocRep, + const int eCode, const int sequenceNumber) + { + FN_CALL; + int res; + iotcon_header_options header_options; + iotcon_repr_h repr = NULL; + + if (OC_STACK_OK == eCode) + res = IOTCON_ERR_NONE; + else + res = IOTCON_ERR_IOTIVITY; + + header_options = iotcon_new_header_options(); + for (HeaderOption::OCHeaderOption option : headerOptions) { + iotcon_add_header_option(header_options, option.getOptionID(), + option.getOptionData().c_str()); + } + + repr = ic_ioty_repr_generate_repr(ocRep); + + if (on_observe) + on_observe(header_options, repr, res, sequenceNumber, cb_data); + + iotcon_delete_header_options(header_options); + } + }; +} + +extern "C" void ic_iotivity_config(const char *addr, unsigned short port) +{ + PlatformConfig cfg { + ServiceType::InProc, + ModeType::Both, + string(addr), + port, + QualityOfService::HighQos + }; + Configure(cfg); + DBG("Created a platform"); +} + +static OCEntityHandlerResult _entity_handler(shared_ptr request) +{ + FN_CALL; + HeaderOptions headerOptions; + QueryParamsMap queryParams; + resource_handler_s *temp_res = NULL; + iotcon_request_s request_s = {0}; + + temp_res = ic_get_resource_handler_data(request->getResourceHandle()); + if (NULL == temp_res) { + ERR("No Resource Handler"); + return OC_EH_ERROR; + } + + request_s.query_params = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); + if (NULL == request_s.query_params) { + ERR("g_hash_table_new_full() Fail"); + return OC_EH_ERROR; + } + + map::iterator it; + queryParams = request->getQueryParameters(); + for (it = queryParams.begin(); it != queryParams.end(); ++it) { + DBG("key=%s value=%s", it->first.c_str(), it->second.c_str()); + g_hash_table_insert(request_s.query_params, ic_utils_strdup(it->first.c_str()), + ic_utils_strdup(it->second.c_str())); + } + + request_s.header_opts = iotcon_new_header_options(); + if (NULL == request_s.header_opts) { + ERR("iot_new_header_options() Fail"); + return OC_EH_ERROR; + } + + headerOptions = request->getHeaderOptions(); + if (0 < headerOptions.size()) { + for (auto it1 = headerOptions.begin(); it1 != headerOptions.end(); ++it1) { + DBG("OptionID=%d, OptionData=%s", + it1->getOptionID(), it1->getOptionData().c_str()); + iotcon_add_header_option(request_s.header_opts, + it1->getOptionID(), + it1->getOptionData().c_str()); + } + } + + OCRepresentation ocRep = request->getResourceRepresentation(); + if (0 < ocRep.numberOfAttributes()) { + DBG("numberOfAttributes : %d", ocRep.numberOfAttributes()); + request_s.repr = ic_ioty_repr_generate_repr(ocRep); + if (NULL == request_s.repr) { + ERR("request_s.repr is NULL"); + return OC_EH_ERROR; + } + } + + request_s.request_type = ic_utils_strdup(request->getRequestType().c_str()); + if (NULL == request_s.request_type) { + ERR("ic_utils_strdup() Fail"); + g_hash_table_destroy(request_s.header_opts); + g_hash_table_destroy(request_s.query_params); + return OC_EH_ERROR; + } + + request_s.res_uri = ic_utils_strdup(request->getResourceUri().c_str()); + if (NULL == request_s.request_type) { + ERR("ic_utils_strdup() Fail"); + free(request_s.request_type); + g_hash_table_destroy(request_s.header_opts); + g_hash_table_destroy(request_s.query_params); + return OC_EH_ERROR; + } + + request_s.request_handler_flag = request->getRequestHandlerFlag(); + request_s.request_handle = (iotcon_request_h)request->getRequestHandle(); + request_s.resource_handle = (iotcon_resource_h)request->getResourceHandle(); + ObservationInfo observationInfo = request->getObservationInfo(); + + request_s.observation_info.action = (iotcon_osbserve_action_e)observationInfo.action; + request_s.observation_info.obs_id = (iotcon_observation_id)observationInfo.obsId; + DBG("obs_info.obsId=%d", observationInfo.obsId); + + /* call handler_cb */ + if (temp_res->rest_api_cb) { + temp_res->rest_api_cb(&request_s); + } + else { + WARN("temp_res->rest_api_cb is null"); + } + + free(request_s.request_type); + free(request_s.res_uri); + if (request_s.repr) /* To avoid unnecessary ERR log (repr could be NULL) */ + iotcon_repr_free(request_s.repr); + g_hash_table_destroy(request_s.header_opts); + g_hash_table_destroy(request_s.query_params); + + return OC_EH_OK; +} + + +extern "C" void* ic_ioty_register_res(const char *uri, const char *rt, + iotcon_interface_e iface, iotcon_resource_property_e rt_property) +{ + OCStackResult ret; + string resUri; + string resType; + string resInterface; + OCResourceHandle handle; + + resUri = uri; + resType = rt; + + if (IOTCON_INTERFACE_LINK == iface) + resInterface = LINK_INTERFACE; + else if (IOTCON_INTERFACE_BATCH == iface) + resInterface = BATCH_INTERFACE; + else if (IOTCON_INTERFACE_GROUP == iface) + resInterface = GROUP_INTERFACE; + else + resInterface = DEFAULT_INTERFACE; + + + ret = registerResource(handle, resUri, resType, resInterface, _entity_handler, + (unsigned int)rt_property); + if (OC_STACK_OK != ret) { + ERR("registerResource Fail(%d)", ret); + return NULL; + } + + return handle; +} + + +extern "C" int ic_ioty_unregister_res(const iotcon_resource_h resource_handle) +{ + OCResourceHandle resourceHandle = resource_handle; + + try { + OCStackResult result = unregisterResource(resourceHandle); + if(OC_STACK_OK != result) { + ERR("OCPlatform::unregisterResource Fail(%d)", result); + return IOTCON_ERR_IOTIVITY; + } + } + catch(OCException& e) { + ERR("unregisterResource() Fail(%s)", e.what()); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + + +extern "C" int ic_ioty_bind_iface_to_res(const iotcon_resource_h resource_handle, + const char *interface_type) +{ + OCStackResult ret = OC_STACK_ERROR; + OCResourceHandle resourceHandle = resource_handle; + + ret = bindInterfaceToResource(resourceHandle, interface_type); + if (OC_STACK_OK != ret) { + ERR("bindInterfaceToResource() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + + +extern "C" int ic_ioty_bind_type_to_res(const iotcon_resource_h resource_handle, + const char *resource_type) +{ + OCStackResult ret; + OCResourceHandle resourceHandle = resource_handle; + + ret = bindTypeToResource(resourceHandle, resource_type); + if (OC_STACK_OK != ret) { + ERR("bindTypeToResource() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_bind_res(iotcon_resource_h parent, iotcon_resource_h child) +{ + OCStackResult ret; + OCResourceHandle p_handle = parent; + OCResourceHandle c_handle = child; + + ret = OCBindResource(p_handle, c_handle); + if (OC_STACK_OK != ret) { + ERR("OCBindResource() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_register_device_info(iotcon_device_info_s *device_info) +{ + FN_CALL; + OCStackResult ret; + + OCDeviceInfo deviceInfo = {0}; + deviceInfo.deviceName = ic_utils_strdup(device_info->device_name); + deviceInfo.hostName = ic_utils_strdup(device_info->host_name); + deviceInfo.deviceUUID = ic_utils_strdup(device_info->device_uuid); + deviceInfo.contentType = ic_utils_strdup(device_info->content_type); + deviceInfo.version = ic_utils_strdup(device_info->version); + deviceInfo.manufacturerName = ic_utils_strdup(device_info->manufacturer_name); + deviceInfo.manufacturerUrl = ic_utils_strdup(device_info->manufacturer_url); + deviceInfo.modelNumber = ic_utils_strdup(device_info->model_number); + deviceInfo.dateOfManufacture = ic_utils_strdup(device_info->date_of_manufacture); + deviceInfo.platformVersion = ic_utils_strdup(device_info->platform_version); + deviceInfo.firmwareVersion = ic_utils_strdup(device_info->firmware_version); + deviceInfo.supportUrl = ic_utils_strdup(device_info->support_url); + + ret = registerDeviceInfo(deviceInfo); + if (OC_STACK_OK != ret) { + ERR("registerDeviceInfo() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + + +extern "C" int ic_ioty_get_device_info(char *host, char *uri) +{ + OCStackResult ret; + string resHost; + string resUri; + + resHost = host; + resUri = uri; + + /* register device_cb + to monitor upper apps who wnat to know other device infomation */ + ret = getDeviceInfo(resHost, resUri, ic_ioty_repr_found_device_cb); + if (OC_STACK_OK != ret) { + ERR("getDeviceInfo() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + + +extern "C" int ic_ioty_send_notify(struct ic_res_response_s *resp, + iotcon_observers observers) +{ + int ret; + ObservationIds obsIds; + OCResourceHandle resHandle; + string interface; + + RETV_IF(NULL == resp, IOTCON_ERR_PARAM); + RETV_IF(NULL == resp->repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == observers, IOTCON_ERR_PARAM); + + resHandle = resp->resource_handle; + + RETV_IF(NULL == resp->repr, IOTCON_ERR_PARAM); + + OCRepresentation ocRep = ic_ioty_repr_parse(resp->repr); + + GList *node = g_list_first(observers); + while (node) { + iotcon_observation_info_s *temp = (iotcon_observation_info_s*)node->data; + obsIds.push_back(temp->obs_id); + + node = node->next; + } + + shared_ptr resourceResponse(new OCResourceResponse()); + resourceResponse->setErrorCode(resp->error_code); + + switch (resp->interface) { + case IOTCON_INTERFACE_GROUP: + interface = GROUP_INTERFACE; + break; + case IOTCON_INTERFACE_BATCH: + interface = BATCH_INTERFACE; + break; + case IOTCON_INTERFACE_LINK: + interface = LINK_INTERFACE; + break; + case IOTCON_INTERFACE_DEFAULT: + default: + interface = DEFAULT_INTERFACE; + } + + resourceResponse->setResourceRepresentation(ocRep, interface); + + ret = notifyListOfObservers(resHandle, obsIds, resourceResponse); + if (OC_STACK_NO_OBSERVERS == ret) { + ERR("No More observers, stopping notifications"); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + + +extern "C" int ic_ioty_send_res_response_data(struct ic_res_response_s *resp) +{ + FN_CALL; + string interface; + int ret = OC_STACK_ERROR; + + RETV_IF(NULL == resp, IOTCON_ERR_PARAM); + + RETV_IF(NULL == resp->repr, IOTCON_ERR_PARAM); + + OCRepresentation ocRep = ic_ioty_repr_parse(resp->repr); + iotcon_repr_free(resp->repr); + + auto pResponse = make_shared(); + if (pResponse) { + pResponse->setRequestHandle(resp->request_handle); + pResponse->setResourceHandle(resp->resource_handle); + pResponse->setErrorCode(resp->error_code); + pResponse->setResponseResult((OCEntityHandlerResult)resp->result); + + switch (resp->interface) { + case IOTCON_INTERFACE_GROUP: + interface = GROUP_INTERFACE; + break; + case IOTCON_INTERFACE_BATCH: + interface = BATCH_INTERFACE; + break; + case IOTCON_INTERFACE_LINK: + interface = LINK_INTERFACE; + break; + case IOTCON_INTERFACE_DEFAULT: + default: + interface = DEFAULT_INTERFACE; + } + + pResponse->setResourceRepresentation(ocRep, interface); + + ret = sendResponse(pResponse); + if (OC_STACK_OK != ret) { + ERR("sendResponse() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + } + + FN_END; + + return IOTCON_ERR_NONE; + +} + +extern "C" iotcon_presence_h ic_ioty_subscribe_presence(const char *host_address, + iotcon_presence_handle_cb presence_handler_cb, void *user_data) +{ + OCStackResult ret; + iotcon_presence_h presence_handle = NULL; + + shared_ptr object + = make_shared(presence_handler_cb, user_data); + SubscribeCallback subscribeCallback + = bind(&icIotivityHandler::presenceObject::presenceHandler, object, + placeholders::_1, placeholders::_2, placeholders::_3); + + ret = subscribePresence(presence_handle, host_address, subscribeCallback); + if (OC_STACK_OK != ret) { + ERR("subscribePresence() Fail(%d)", ret); + return NULL; + } + + return presence_handle; +} + +extern "C" int ic_ioty_unsubscribe_presence(iotcon_presence_h presence_handle) +{ + OCStackResult ret; + + ret = unsubscribePresence(presence_handle); + if (OC_STACK_OK != ret) { + ERR("unsubscribePresence() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_start_presence(const unsigned int time_to_live) +{ + try { + startPresence(time_to_live); + } catch (OCException e) { + ERR("startPresence() Fail(%s)", e.what()); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_stop_presence() +{ + try { + stopPresence(); + } catch (OCException e) { + ERR("stopPresence() Fail(%s)", e.what()); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_find_resource(const char *host, const char *resource_name, + iotcon_found_resource_cb found_resource_cb, void *user_data) +{ + OCStackResult ret; + + shared_ptr object + = make_shared(found_resource_cb, user_data); + FindCallback findCallback = bind(&icIotivityHandler::findObject::foundResource, + object, placeholders::_1); + + ret = findResource(host, resource_name, findCallback); + if (OC_STACK_OK != ret) { + ERR("findResource() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +static OCResource::Ptr _create_oc_resource(iotcon_resource_s resource) +{ + RETV_IF(NULL == resource.resource_host, NULL); + RETV_IF(NULL == resource.resource_uri, NULL); + + string host = resource.resource_host; + string uri = resource.resource_uri; + vector resource_types; + vector resource_ifs; + + HeaderOptions header_options; + GHashTableIter iter; + gpointer key = NULL; + gpointer value = NULL; + + GList *node = resource.resource_types; + for (node = g_list_first(node); NULL != node; node = g_list_next(node)) { + string resource_type_str = (char *)node->data; + resource_types.push_back(resource_type_str); + } + + node = resource.resource_interfaces; + for (node = g_list_first(node); NULL != node; node = g_list_next(node)) { + string resource_if_str = (char *)node->data; + resource_ifs.push_back(resource_if_str); + } + + OCResource::Ptr ocResource = constructResourceObject(host, uri, + resource.is_observable, resource_types, resource_ifs); + + if (NULL != resource.header_options) { + g_hash_table_iter_init(&iter, resource.header_options); + while (g_hash_table_iter_next(&iter, &key, &value)) { + HeaderOption::OCHeaderOption header_option( + GPOINTER_TO_UINT(key), (const char *)value); + header_options.push_back(header_option); + } + ocResource->setHeaderOptions(header_options); + } + + return ocResource; +} + +extern "C" int ic_ioty_get(iotcon_resource_s resource, + iotcon_query_parameters query_params, iotcon_on_get_cb on_get_cb, void *user_data) +{ + FN_CALL; + OCStackResult ret; + OCResource::Ptr ocResource = NULL; + + QueryParamsMap query; + GHashTableIter iter; + gpointer key, value; + + if (NULL != query_params) { + g_hash_table_iter_init(&iter, query_params); + while (g_hash_table_iter_next(&iter, &key, &value)) { + string keyStr = (char *)key; + string valueStr = (char *)value; + query[keyStr] = valueStr; + } + } + + ocResource = _create_oc_resource(resource); + + shared_ptr object + = make_shared(on_get_cb, user_data); + GetCallback getCallback = bind(&icIotivityHandler::getObject::onGet, object, + placeholders::_1, placeholders::_2, placeholders::_3); + ret = ocResource->get(query, getCallback); + if (OC_STACK_OK != ret) { + ERR("get() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_put(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_put_cb on_put_cb, + void *user_data) +{ + FN_CALL; + OCStackResult ret; + + OCResource::Ptr ocResource = NULL; + OCRepresentation ocRep; + QueryParamsMap query; + + GHashTableIter iter; + gpointer key, value; + + if (NULL != query_params) { + g_hash_table_iter_init(&iter, query_params); + while (g_hash_table_iter_next(&iter, &key, &value)) { + string keyStr = (char *)key; + string valueStr = (char *)value; + query[keyStr] = valueStr; + } + } + + ocRep = ic_ioty_repr_parse(repr); + + ocResource = _create_oc_resource(resource); + + shared_ptr object + = make_shared(on_put_cb, user_data); + PutCallback putCallback = bind(&icIotivityHandler::putObject::onPut, object, + placeholders::_1, placeholders::_2, placeholders::_3); + + ret = ocResource->put(ocRep, query, putCallback); + if (OC_STACK_OK != ret) { + ERR("put() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_post(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_post_cb on_post_cb, + void *user_data) +{ + FN_CALL; + OCStackResult ret; + GHashTableIter iter; + gpointer key, value; + QueryParamsMap query; + OCRepresentation ocRep; + OCResource::Ptr ocResource = NULL; + + if (NULL != query_params) { + g_hash_table_iter_init(&iter, query_params); + while (g_hash_table_iter_next(&iter, &key, &value)) { + string keyStr = (char *)key; + string valueStr = (char *)value; + query[keyStr] = valueStr; + } + } + + ocRep = ic_ioty_repr_parse(repr); + + ocResource = _create_oc_resource(resource); + + shared_ptr object + = make_shared(on_post_cb, user_data); + PostCallback postCallback = bind(&icIotivityHandler::postObject::onPost, object, + placeholders::_1, placeholders::_2, placeholders::_3); + + ret = ocResource->post(ocRep, query, postCallback); + if (OC_STACK_OK != ret) { + ERR("post() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_delete_res(iotcon_resource_s resource, + iotcon_on_delete_cb on_delete_cb, void *user_data) +{ + FN_CALL; + OCStackResult ret; + OCResource::Ptr ocResource = NULL; + + ocResource = _create_oc_resource(resource); + + shared_ptr object + = make_shared(on_delete_cb, user_data); + DeleteCallback deleteCallback = bind(&icIotivityHandler::deleteObject::onDelete, + object, placeholders::_1, placeholders::_2); + + ret = ocResource->deleteResource(deleteCallback); + if (OC_STACK_OK != ret) { + ERR("deleteResource() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_observe(iotcon_resource_s *resource, + iotcon_observe_type_e observe_type, + iotcon_query_parameters query_params, + iotcon_on_observe_cb on_observe_cb, + void *user_data) +{ + OCStackResult ret; + + OCResource::Ptr ocResource = NULL; + ObserveType observeType; + + QueryParamsMap query; + GHashTableIter iter; + gpointer key, value; + + if (NULL != query_params) { + g_hash_table_iter_init(&iter, query_params); + while (g_hash_table_iter_next(&iter, &key, &value)) { + string keyStr = (char *)key; + string valueStr = (char *)value; + query[keyStr] = valueStr; + } + } + + if (IOTCON_OBSERVE == observe_type) { + observeType = ObserveType::Observe; + } + else if (IOTCON_OBSERVE_ALL == observe_type) { + observeType = ObserveType::ObserveAll; + } + else { + ERR("Invalid observe_type"); + return IOTCON_ERR_PARAM; + } + + ocResource = _create_oc_resource(*resource); + + resource_handle *obs_h = new resource_handle(); + obs_h->ocResource = ocResource; + resource->observe_handle = (void *)obs_h; + + shared_ptr object + = make_shared(on_observe_cb, user_data); + ObserveCallback observeCallback = bind(&icIotivityHandler::observeObject::onObserve, + object, placeholders::_1, placeholders::_2, placeholders::_3, + placeholders::_4); + ret = ocResource->observe(observeType, query, observeCallback); + if (OC_STACK_OK != ret) { + ERR("observe() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} + +extern "C" int ic_ioty_cancel_observe(iotcon_resource_s resource) +{ + OCStackResult ret; + + OCResource::Ptr ocResource = ((resource_handle *)resource.observe_handle)->ocResource; + delete (resource_handle *)resource.observe_handle; + resource.observe_handle = NULL; + + ret = ocResource->cancelObserve(); + if (OC_STACK_OK != ret) { + ERR("cancelObserve() Fail(%d)", ret); + return IOTCON_ERR_IOTIVITY; + } + + return IOTCON_ERR_NONE; +} diff --git a/lib/ic-ioty.h b/lib/ic-ioty.h new file mode 100644 index 0000000..ba285c5 --- /dev/null +++ b/lib/ic-ioty.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_H__ + +#include "iotcon.h" + +typedef struct _resource_handler_s { + char *rt_name; + char *if_name; + char *uri_name; + iotcon_rest_api_handle_cb rest_api_cb; +} resource_handler_s; + +void ic_iotivity_config(const char *addr, unsigned short port); + +void* ic_ioty_register_res(const char *uri, const char *rt, + iotcon_interface_e iface, iotcon_resource_property_e rt_property); + +int ic_ioty_unregister_res(const iotcon_resource_h resource_handle); + +int ic_ioty_bind_iface_to_res(const iotcon_resource_h resource_handle, + const char *interface_type); + +int ic_ioty_bind_type_to_res(const iotcon_resource_h resource_handle, + const char *resource_type); + +int ic_ioty_bind_res(iotcon_resource_h parent, iotcon_resource_h child); + +int ic_ioty_register_device_info(iotcon_device_info_s *device_info); + +int ic_ioty_get_device_info(char *host, char *uri); + +int ic_ioty_send_notify(struct ic_res_response_s *resp, + iotcon_observers observers); + +int ic_ioty_send_res_response_data(struct ic_res_response_s *resp); + +iotcon_presence_h ic_ioty_subscribe_presence(const char *host_address, + iotcon_presence_handle_cb presence_handler_cb, void *user_data); + +int ic_ioty_unsubscribe_presence(iotcon_presence_h presence_handle); +int ic_ioty_start_presence(const unsigned int time_to_live); +int ic_ioty_stop_presence(); + +int ic_ioty_find_resource(const char *host, const char *resource_name, + iotcon_found_resource_cb found_resource_cb, void *user_data); + +int ic_ioty_get(iotcon_resource_s resource, iotcon_query_parameters query_params, + iotcon_on_get_cb on_get_cb, void *user_data); + +int ic_ioty_put(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_put_cb on_put_cb, + void *user_data); + +int ic_ioty_post(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_put_cb on_post_cb, + void *user_data); + +int ic_ioty_delete_res(iotcon_resource_s resource, + iotcon_on_delete_cb on_delete_cb, void *user_data); + +int ic_ioty_observe(iotcon_resource_s *resource, + iotcon_observe_type_e observe_type, + iotcon_query_parameters query_params, + iotcon_on_observe_cb on_observe_cb, + void *user_data); + +int ic_ioty_cancel_observe(iotcon_resource_s resource); + +/** + * @brief hash-table for resource callback handler + */ +typedef struct _iot_ctx { + GHashTable *entity_cb_hash; + GList *found_device_cb_lst; +} ic_ctx_s; + +ic_ctx_s* ic_get_ctx(); + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_IOTIVITY_H__ diff --git a/lib/ic-log.h b/lib/ic-log.h new file mode 100644 index 0000000..cac29be --- /dev/null +++ b/lib/ic-log.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_LOG_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_LOG_H__ + +#define IC_LOG_RED "\033[0;31m" +#define IC_LOG_GREEN "\033[0;32m" +#define IC_LOG_BROWN "\033[0;33m" +#define IC_LOG_BLUE "\033[0;34m" +#define IC_LOG_END "\033[0;m" + +#undef _DBG +#undef _INFO +#undef _WARN +#undef _ERR + +#undef DBG +#undef INFO +#undef WARN +#undef ERR + +#define TIZEN_DEBUG_ENABLE +#define LOG_TAG "IOTCON" +#include + +#ifdef IC_DAEMON + +#define _DBG(fmt, arg...) SLOGD(IC_LOG_GREEN "" IC_LOG_END fmt, ##arg) +#define _INFO(fmt, arg...) SLOGI(IC_LOG_GREEN "" IC_LOG_END fmt, ##arg) +#define _WARN(fmt, arg...) SLOGW(IC_LOG_GREEN "" IC_LOG_END fmt, ##arg) +#define _ERR(fmt, arg...) SLOGE(IC_LOG_GREEN "" IC_LOG_END fmt, ##arg) + +#else /* IC_DAEMON */ + +#define _DBG(fmt, arg...) SLOGD(fmt, ##arg) +#define _INFO(fmt, arg...) SLOGI(fmt, ##arg) +#define _WARN(fmt, arg...) SLOGW(fmt, ##arg) +#define _ERR(fmt, arg...) SLOGE(fmt, ##arg) + +#endif /* IC_DAEMON */ + +#if 0 +#define _DBG(fmt, arg...) \ + printf("[IoTCon]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _INFO(fmt, arg...) \ + printf("[IoTCon]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _WARN(fmt, arg...) \ + printf("[IoTCon]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _ERR(fmt, arg...) \ + printf("[IoTCon]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#endif + +#define IC_DEBUGGING + +#ifdef IC_DEBUGGING + +#define FN_CALL _INFO(">>>>>>>> called") +#define FN_END _INFO("<<<<<<<< ended") +#define DBG(fmt, arg...) _DBG(fmt, ##arg) +#define WARN(fmt, arg...) _WARN(IC_LOG_BROWN fmt IC_LOG_END, ##arg) +#define ERR(fmt, arg...) _ERR(IC_LOG_RED fmt IC_LOG_END, ##arg) +#define INFO(fmt, arg...) _INFO(IC_LOG_BLUE fmt IC_LOG_END, ##arg) +#define SECURE_DBG(fmt, arg...) SECURE_SLOGD(fmt, ##arg) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) + +#else /* IC_DEBUGGING */ + +#define FN_CALL +#define FN_END +#define DBG(fmt, arg...) +#define WARN(fmt, arg...) +#define ERR(fmt, arg...) _ERR(fmt, ##arg) +#define INFO(fmt, arg...) +#define SECURE_DBG(fmt, arg...) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) + +#endif /* IC_DEBUGGING */ + +#define RET_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + return; \ + }\ + } while(0) + +#define RETV_IF(expr, val) \ + do {\ + if (expr) { \ + ERR("(%s)", #expr); \ + return (val); \ + } \ + } while(0) + +#define RETM_IF(expr, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + }\ + } while(0) + +#define RETVM_IF(expr, val, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while(0) + +#define ERR_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + } \ + } while (0) + +#define WARN_IF(expr) \ + do { \ + if (expr) { \ + WARN("(%s)", #expr); \ + } \ + } while (0) + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_LOG_H__ \ No newline at end of file diff --git a/lib/ic-rep-list.c b/lib/ic-rep-list.c new file mode 100644 index 0000000..9f76542 --- /dev/null +++ b/lib/ic-rep-list.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include + +#include + +#include "iotcon.h" + +#include "ic-common.h" +#include "ic-struct.h" +#include "ic-rep.h" +#include "ic-rep-value.h" +#include "ic-rep-list.h" + +API iotcon_list_h iotcon_int_list_new() +{ + return ic_list_new(IOTCON_VALUE_INT); +} + +API iotcon_list_h iotcon_bool_list_new() +{ + return ic_list_new(IOTCON_VALUE_BOOL); +} + +API iotcon_list_h iotcon_double_list_new() +{ + return ic_list_new(IOTCON_VALUE_DOUBLE); +} + +API iotcon_list_h iotcon_str_list_new() +{ + return ic_list_new(IOTCON_VALUE_STR); +} + +API iotcon_list_h iotcon_list_list_new() +{ + return ic_list_new(IOTCON_VALUE_LIST); +} + +API iotcon_list_h iotcon_repr_list_new() +{ + return ic_list_new(IOTCON_VALUE_REPR); +} + +iotcon_list_h ic_list_new(int type) +{ + iotcon_list_h list; + errno = 0; + + list = calloc(1, sizeof(struct ic_list_s)); + if (NULL == list) { + ERR("calloc() Fail(%d)", errno); + return NULL; + } + + list->type = type; + + return list; +} + +API iotcon_list_h iotcon_list_append_int(iotcon_list_h list, int ival) +{ + int ret = 0; + + RETV_IF(NULL == list, NULL); + RETVM_IF(IOTCON_VALUE_INT != list->type, list, "IOTCON_ERR_PARAM(%d)", list->type); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_INT); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_INT) Fail"); + return list; + } + + ret = ic_value_set_int(value, ival); + if (IOTCON_ERR_NONE != ret) { + ERR("ic_value_set_int(%d) Fail(%d)", ival, ret); + ic_repr_free_basic_value(value); + return list; + } + + list = ic_list_append(list, value); + + return list; +} + +API iotcon_list_h iotcon_list_append_bool(iotcon_list_h list, bool bval) +{ + int ret = 0; + + RETV_IF(NULL == list, NULL); + RETVM_IF(IOTCON_VALUE_BOOL != list->type, list, "IOTCON_ERR_PARAM(%d)", list->type); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_BOOL); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_BOOL) Fail"); + return list; + } + + ret = ic_value_set_bool(value, bval); + if (IOTCON_ERR_NONE != ret) { + ERR("ic_value_set_bool(%d) Fail(%d)", bval, ret); + ic_repr_free_basic_value(value); + return list; + } + + list = ic_list_append(list, value); + + return list; +} + +API iotcon_list_h iotcon_list_append_double(iotcon_list_h list, double dbval) +{ + int ret = 0; + + RETV_IF(NULL == list, NULL); + RETVM_IF(IOTCON_VALUE_DOUBLE != list->type, list, "IOTCON_ERR_PARAM(%d)", + list->type); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_DOUBLE); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_DOUBLE) Fail"); + return list; + } + + ret = ic_value_set_double(value, dbval); + if (IOTCON_ERR_NONE != ret) { + ERR("ic_value_set_double(%lf) Fail(%d)", dbval, ret); + ic_repr_free_basic_value(value); + return list; + } + + list = ic_list_append(list, value); + + return list; +} + +API iotcon_list_h iotcon_list_append_str(iotcon_list_h list, const char *strval) +{ + int ret = 0; + + RETV_IF(NULL == list, NULL); + RETVM_IF(IOTCON_VALUE_STR != list->type, list, "IOTCON_ERR_PARAM(%d)", list->type); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_STR); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_STR) Fail"); + return list; + } + + ret = ic_value_set_str(value, strval); + if (IOTCON_ERR_NONE != ret) { + ERR("ic_value_set_str(%s) Fail(%d)", strval, ret); + ic_repr_free_basic_value(value); + return list; + } + + list = ic_list_append(list, value); + + return list; +} + +API iotcon_list_h iotcon_list_append_rep(iotcon_list_h list, iotcon_repr_h repr) +{ + RETV_IF(NULL == list, NULL); + RETV_IF(NULL == repr, NULL); + RETVM_IF(IOTCON_VALUE_REPR != list->type, list, "IOTCON_ERR_PARAM(%d)", list->type); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_REPR); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_REPR) Fail"); + return list; + } + + ic_val_repr_s *real = (ic_val_repr_s *)value; + + real->repr = repr; + + list = ic_list_append(list, value); + + return list; +} + +API iotcon_repr_h iotcon_list_get_nth_rep(iotcon_list_h list, int index) +{ + RETV_IF(NULL == list, NULL); + RETV_IF(NULL == list->list, NULL); + + iotcon_value_h value = g_list_nth_data(list->list, index); + if (NULL == value) { + ERR("g_list_nth_data() Fail"); + return NULL; + } + + ic_val_repr_s *real = (ic_val_repr_s *) value; + RETVM_IF(IOTCON_VALUE_REPR != real->type, NULL, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->repr; +} + +API int iotcon_list_get_length(iotcon_list_h list) +{ + RETV_IF(NULL == list, IOTCON_ERR_PARAM); + RETV_IF(NULL == list->list, IOTCON_ERR_PARAM); + + return g_list_length(list->list); +} + +API iotcon_list_h iotcon_list_get_nth_list(iotcon_list_h list, int index) +{ + RETV_IF(NULL == list, NULL); + RETV_IF(NULL == list->list, NULL); + + iotcon_value_h value = g_list_nth_data(list->list, index); + if (NULL == value) { + ERR("g_list_nth_data() Fail"); + return NULL; + } + + ic_val_list_s *real = (ic_val_list_s *) value; + RETVM_IF(IOTCON_VALUE_LIST != real->type, NULL, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->list; +} + +API iotcon_value_h iotcon_list_get_nth_value(iotcon_list_h list, int index) +{ + RETV_IF(NULL == list, NULL); + RETV_IF(NULL == list->list, NULL); + + return g_list_nth_data(list->list, index); +} + +int ic_list_remove(iotcon_list_h list, iotcon_value_h val) +{ + RETV_IF(NULL == list, IOTCON_ERR_PARAM); + + list->list = g_list_remove(list->list, val); + + return IOTCON_ERR_NONE; +} + +iotcon_list_h ic_list_append(iotcon_list_h list, iotcon_value_h value) +{ + RETV_IF(NULL == list, NULL); + + list->list = g_list_append(list->list, value); + if (NULL == list->list) { + ERR("g_list_append() Fail"); + return list; + } + + return list; +} + +API void iotcon_list_foreach(iotcon_list_h list, iotcon_list_fn fn, void *user_data) +{ + RETM_IF(NULL == list, "IOTCON_ERR_PARAM(NULL == list)"); + RETM_IF(NULL == fn, "IOTCON_ERR_PARAM(NULL == fn)"); + + g_list_foreach(list->list, (GFunc)fn, user_data); +} + +JsonArray* ic_repr_generate_json_array(iotcon_list_h list) +{ + int i; + int count = 0; + JsonArray *parray = NULL; + JsonNode *node_child = NULL; + int error_code = IOTCON_ERR_NONE; + + JsonObject *obj_child = NULL; + JsonArray *array_child = NULL; + iotcon_repr_h repr_child = NULL; + iotcon_list_h iotlist_child = NULL; + iotcon_value_h iotvalue_child = NULL; + + RETV_IF(NULL == list, NULL); + RETV_IF(NULL == list->list, NULL); + + count = g_list_length(list->list); + DBG("list count(%d)", count); + + parray = json_array_new(); + for (i = 0; i < count; i++) { + iotvalue_child = iotcon_list_get_nth_value(list, i); + + int type = iotcon_value_get_type(iotvalue_child); + switch (type) { + case IOTCON_VALUE_INT: + case IOTCON_VALUE_BOOL: + case IOTCON_VALUE_DOUBLE: + case IOTCON_VALUE_STR: + case IOTCON_VALUE_NULL: + node_child = ic_repr_generate_json_value(iotvalue_child); + if (NULL == node_child) { + ERR("ic_repr_generate_json_value(iotvalue_child) Fail"); + json_array_unref(parray); + return NULL; + } + json_array_add_element(parray, node_child); + break; + case IOTCON_VALUE_LIST: + iotlist_child = iotcon_value_get_list(iotvalue_child); + array_child = ic_repr_generate_json_array(iotlist_child); + if (NULL == array_child) { + ERR("ic_repr_generate_json_array(list_child) Fail"); + json_array_unref(parray); + return NULL; + } + node_child = json_node_new(JSON_NODE_ARRAY); + json_node_set_array(node_child, array_child); + json_array_add_element(parray, node_child); + break; + case IOTCON_VALUE_REPR: + repr_child = iotcon_value_get_rep(iotvalue_child); + obj_child = ic_repr_generate_json_repr(repr_child, &error_code); + if (NULL == obj_child) { + ERR("ic_repr_generate_json_repr(repr_child) Fail"); + json_array_unref(parray); + return NULL; + } + node_child = json_node_new(JSON_NODE_OBJECT); + json_node_set_object(node_child, obj_child); + json_array_add_element(parray, node_child); + } + } + return parray; +} + +iotcon_list_h ic_repr_parse_json_array(JsonArray *parray) +{ + int i; + int count = json_array_get_length(parray); + + iotcon_list_h list = ic_list_new(IOTCON_VALUE_NONE); +// DBG("array count(%d)", count); + + for (i = 0; i < count; i++) { + JsonNode *child_node = json_array_get_element(parray, i); + if (JSON_NODE_HOLDS_NULL(child_node) || JSON_NODE_HOLDS_VALUE(child_node)) { + iotcon_value_h value = ic_repr_parse_json_value(child_node); + if (NULL == value) { + ERR("ic_repr_parse_json_value() Fail(NULL == value)"); + return NULL; + } + + ic_basic_s *real = (ic_basic_s*)value; + if (IOTCON_VALUE_NONE != list->type && list->type != real->type) { + ERR("Type matching Fail(list:%d,value:%d)", list->type, real->type); + ic_repr_free_basic_value(value); + ic_repr_free_list(list); + return NULL; + } + + list = ic_list_append(list, value); + list->type = real->type; + continue; + } + else if (JSON_NODE_HOLDS_ARRAY(child_node)) { + JsonArray *child_array = json_node_get_array(child_node); + iotcon_list_h parsed_list = ic_repr_parse_json_array(child_array); + if (NULL == parsed_list) { + ERR("ic_repr_parse_json_array() Fail(NULL == parsed_list)"); + return NULL; + } + + if (IOTCON_VALUE_NONE != list->type + && IOTCON_VALUE_LIST != list->type) { + ERR("Type matching Fail(%d)", list->type); + ic_repr_free_list(parsed_list); + ic_repr_free_list(list); + return NULL; + } + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_LIST); + ic_value_set_list(value, parsed_list); + list = ic_list_append(list, value); + list->type = IOTCON_VALUE_LIST; + + continue; + } + else if (JSON_NODE_HOLDS_OBJECT(child_node)) { + int error_code = IOTCON_ERR_NONE; + JsonObject *child_obj = json_node_get_object(child_node); + JsonObject *repr_obj = json_object_get_object_member(child_obj, + IOTCON_KEY_REP); + iotcon_repr_h retrep = ic_repr_parse_json_obj(repr_obj, &error_code); + if (NULL == retrep) { + ERR("ic_repr_parse_json_obj() Fail(NULL == retrep)"); + return NULL; + } + + if (IOTCON_VALUE_NONE != list->type + && IOTCON_VALUE_REPR != list->type) { + ERR("Type matching Fail(%d)", list->type); + iotcon_repr_free(retrep); + ic_repr_free_list(list); + return NULL; + } + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_REPR); + ic_value_set_rep(value, retrep); + list = ic_list_append(list, value); + list->type = IOTCON_VALUE_REPR; + continue; + } + } + + return list; +} + +void ic_repr_free_list(iotcon_list_h iotlist) +{ + FN_CALL; + int count = 0; + GList *cur = NULL; + + RET_IF(NULL == iotlist); + + if (iotlist->list) + count = g_list_length(iotlist->list); + + DBG("iotlist count(%d)", count); + cur = iotlist->list; + while (cur) { + ic_repr_free_value(cur->data); + cur = cur->next; + } + free(iotlist); +} diff --git a/lib/ic-rep-list.h b/lib/ic-rep-list.h new file mode 100644 index 0000000..c0b6890 --- /dev/null +++ b/lib/ic-rep-list.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_LIST_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_LIST_H__ + +#include + +#include "iotcon-struct.h" + +iotcon_list_h ic_list_new(int type); +int ic_list_remove(iotcon_list_h list, iotcon_value_h val); +iotcon_list_h ic_list_append(iotcon_list_h list, iotcon_value_h value); + +JsonArray* ic_repr_generate_json_array(iotcon_list_h list); +iotcon_list_h ic_repr_parse_json_array(JsonArray *parray); + +void ic_repr_free_list(iotcon_list_h iotlist); + +#endif // __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_LIST_H__ diff --git a/lib/ic-rep-value.c b/lib/ic-rep-value.c new file mode 100644 index 0000000..6c6aea5 --- /dev/null +++ b/lib/ic-rep-value.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include + +#include + +#include "iotcon.h" + +#include "ic-common.h" +#include "ic-struct.h" +#include "ic-utils.h" +#include "ic-rep.h" +#include "ic-rep-list.h" +#include "ic-rep-value.h" + +iotcon_value_h ic_value_new(int type) +{ + iotcon_value_h ret_val; + errno = 0; + + switch (type) { + case IOTCON_VALUE_INT: + case IOTCON_VALUE_BOOL: + case IOTCON_VALUE_DOUBLE: + case IOTCON_VALUE_STR: + case IOTCON_VALUE_NULL: + ret_val = calloc(1, sizeof(ic_basic_s)); + break; + case IOTCON_VALUE_LIST: + ret_val = calloc(1, sizeof(ic_val_list_s)); + break; + case IOTCON_VALUE_REPR: + ret_val = calloc(1, sizeof(ic_val_repr_s)); + break; + default: + ERR("Invalid Type(%d)", type); + return NULL; + } + + if (NULL == ret_val) { + ERR("calloc() Fail(%d)", errno); + return NULL; + } + + ret_val->type = type; + + return ret_val; +} + +API int iotcon_value_get_type(iotcon_value_h value) +{ + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + return value->type; +} + +API int iotcon_value_get_int(iotcon_value_h value) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_INT != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + return real->val.i; +} + +int ic_value_set_int(iotcon_value_h value, int ival) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_INT != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->val.i = ival; + + return IOTCON_ERR_NONE; +} + +API bool iotcon_value_get_bool(iotcon_value_h value) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_BOOL != real->type, false, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->val.b; +} + +int ic_value_set_bool(iotcon_value_h value, bool bval) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_BOOL != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->val.b = bval; + + return IOTCON_ERR_NONE; +} + +API double iotcon_value_get_double(iotcon_value_h value) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_DOUBLE != real->type, 0, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->val.d; +} + +int ic_value_set_double(iotcon_value_h value, double dbval) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_DOUBLE != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->val.d = dbval; + + return IOTCON_ERR_NONE; +} + +API char* iotcon_value_get_str(iotcon_value_h value) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, NULL); + RETVM_IF(IOTCON_VALUE_STR != real->type, NULL, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->val.s; +} + +int ic_value_set_str(iotcon_value_h value, const char *strval) +{ + ic_basic_s *real = (ic_basic_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_STR != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->val.s = ic_utils_strdup(strval); + + return IOTCON_ERR_NONE; +} + +API iotcon_list_h iotcon_value_get_list(iotcon_value_h value) +{ + ic_val_list_s *real = (ic_val_list_s*)value; + + RETV_IF(NULL == value, NULL); + RETVM_IF(IOTCON_VALUE_LIST != real->type, NULL, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->list; +} + +int ic_value_set_list(iotcon_value_h value, iotcon_list_h list) +{ + ic_val_list_s *real = (ic_val_list_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_LIST != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->list = list; + + return IOTCON_ERR_NONE; +} + +API iotcon_repr_h iotcon_value_get_rep(iotcon_value_h value) +{ + ic_val_repr_s *real = (ic_val_repr_s*)value; + + RETV_IF(NULL == value, NULL); + RETVM_IF(IOTCON_VALUE_REPR != real->type, NULL, "IOTCON_ERR_PARAM(%d)", real->type); + + return real->repr; +} + +int ic_value_set_rep(iotcon_value_h value, iotcon_repr_h repr) +{ + ic_val_repr_s *real = (ic_val_repr_s*)value; + + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + RETVM_IF(IOTCON_VALUE_REPR != real->type, IOTCON_ERR_PARAM, "IOTCON_ERR_PARAM(%d)", + real->type); + + real->repr = repr; + + return IOTCON_ERR_NONE; +} + +JsonNode* ic_repr_generate_json_value(iotcon_value_h value) +{ + RETV_IF(NULL == value, NULL); + + JsonNode *node = json_node_new(JSON_NODE_VALUE); + int type = iotcon_value_get_type(value); + + if (IOTCON_VALUE_INT == type) + json_node_set_int(node, iotcon_value_get_int(value)); + else if (IOTCON_VALUE_BOOL == type) + json_node_set_boolean(node, iotcon_value_get_bool(value)); + else if (IOTCON_VALUE_DOUBLE == type) + json_node_set_double(node, iotcon_value_get_double(value)); + else if (IOTCON_VALUE_STR == type) + json_node_set_string(node, iotcon_value_get_str(value)); + else if (IOTCON_VALUE_NULL == type) + node = json_node_init_null(node); + else + ERR("Invalid type(%d)", type); + + return node; +} + +API iotcon_value_h ic_repr_parse_json_value(JsonNode *node) +{ + iotcon_value_h value = NULL; + GType gtype = 0; + + RETV_IF(NULL == node, NULL); + + if (JSON_NODE_HOLDS_NULL(node)) { + value = ic_value_new(IOTCON_VALUE_NULL); + DBG("Set null value to node"); + return value; + } + + gtype = json_node_get_value_type(node); + if (G_TYPE_INT64 == gtype) { + gint64 ival64 = json_node_get_int(node); + if (INT_MAX < ival64 || ival64 < INT_MIN) { + ERR("integer SHOULD NOT exceeds INT_MAX or INT_MIN. ival64(%lld)", ival64); + return NULL; + } + value = ic_value_new(IOTCON_VALUE_INT); + ic_value_set_int(value, ival64); + DBG("Set int value(%d) to node", (int)ival64); + } + else if (G_TYPE_BOOLEAN == gtype) { + bool bval = json_node_get_boolean(node); + value = ic_value_new(IOTCON_VALUE_BOOL); + ic_value_set_bool(value, bval); + DBG("Set bool value(%d) to node", bval); + } + else if (G_TYPE_DOUBLE == gtype) { + double dbval = json_node_get_double(node); + value = ic_value_new(IOTCON_VALUE_DOUBLE); + ic_value_set_double(value, dbval); + DBG("Set double value(%lf) to node", dbval); + } + else if (G_TYPE_STRING == gtype) { + const char *strval = json_node_get_string(node); + value = ic_value_new(IOTCON_VALUE_STR); + ic_value_set_str(value, strval); + DBG("Set str value(%s) to node", strval); + } + else { + ERR("gtype(%d) Fail", gtype); + } + + return value; +} + +void ic_repr_free_value(gpointer data) +{ + FN_CALL; + iotcon_value_h value = data; + int type = iotcon_value_get_type(value); + + switch (type) { + case IOTCON_VALUE_INT: + case IOTCON_VALUE_BOOL: + case IOTCON_VALUE_DOUBLE: + case IOTCON_VALUE_STR: + case IOTCON_VALUE_NULL: + DBG("value is basic. type(%d)", type); + ic_repr_free_basic_value(value); + break; + case IOTCON_VALUE_LIST: + DBG("value is list"); + iotcon_list_h iotlist_child = iotcon_value_get_list(value); + ic_repr_free_list(iotlist_child); + break; + case IOTCON_VALUE_REPR: + DBG("value is object"); + iotcon_repr_h repr_child = iotcon_value_get_rep(value); + iotcon_repr_free(repr_child); + break; + default: + ERR("Invalid type(%d)", type); + break; + } +} + +void ic_repr_free_basic_value(iotcon_value_h iotvalue) +{ + FN_CALL; + RET_IF(NULL == iotvalue); + + int type = iotcon_value_get_type(iotvalue); + DBG("type(%d)", type); + + if (IOTCON_VALUE_STR == type) { + char *str = iotcon_value_get_str(iotvalue); + free(str); + } + free(iotvalue); +} diff --git a/lib/ic-rep-value.h b/lib/ic-rep-value.h new file mode 100644 index 0000000..c3b315c --- /dev/null +++ b/lib/ic-rep-value.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_VALUE_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_VALUE_H__ + +#include + +#include "iotcon-struct.h" + +enum { + /* SHOULD NOT change this order */ + IOTCON_VALUE_NONE = 0, + IOTCON_VALUE_INT, + IOTCON_VALUE_BOOL, + IOTCON_VALUE_DOUBLE, + IOTCON_VALUE_STR, + IOTCON_VALUE_NULL, + IOTCON_VALUE_LIST, + IOTCON_VALUE_REPR, +}; + +iotcon_value_h ic_value_new(int type); + +int ic_value_set_int(iotcon_value_h value, int ival); +int ic_value_set_bool(iotcon_value_h value, bool bval); +int ic_value_set_double(iotcon_value_h value, double dbval); +int ic_value_set_str(iotcon_value_h value, const char *strval); +int ic_value_set_list(iotcon_value_h value, iotcon_list_h list); +int ic_value_set_rep(iotcon_value_h value, iotcon_repr_h rep); +int ic_value_set_null(iotcon_value_h value); + +JsonNode* ic_repr_generate_json_value(iotcon_value_h value); +iotcon_value_h ic_repr_parse_json_value(JsonNode *node); + +void ic_repr_free_value(gpointer data); +void ic_repr_free_basic_value(iotcon_value_h iotvalue); + +#endif // __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_VALUE_H__ diff --git a/lib/ic-rep.c b/lib/ic-rep.c new file mode 100644 index 0000000..069e940 --- /dev/null +++ b/lib/ic-rep.c @@ -0,0 +1,886 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include +#include + +#include + +#include "iotcon.h" + +#include "ic-common.h" +#include "ic-struct.h" +#include "ic-utils.h" +#include "ic-rep-list.h" +#include "ic-rep-value.h" +#include "ic-rep.h" + +API iotcon_repr_h iotcon_repr_new() +{ + iotcon_repr_h ret_val; + errno = 0; + + ret_val = calloc(1, sizeof(struct ic_repr_s)); + if (NULL == ret_val) { + ERR("calloc() Fail(%d)", errno); + return NULL; + } + + ret_val->hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + ic_repr_free_value); + + return ret_val; +} + +API const char* iotcon_repr_get_uri(iotcon_repr_h repr) +{ + RETV_IF(NULL == repr, NULL); + + return repr->uri; +} + +API int iotcon_repr_set_uri(iotcon_repr_h repr, const char *uri) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == uri, IOTCON_ERR_PARAM); + + repr->uri = ic_utils_strdup(uri); + if (NULL == repr->uri) { + ERR("ic_utils_strdup() Fail"); + return IOTCON_ERR_MEMORY; + } + + return IOTCON_ERR_NONE; +} + +API void iotcon_repr_get_resource_types(iotcon_repr_h repr, iotcon_resourcetype_fn fn, + void *user_data) +{ + RET_IF(NULL == repr); + + /* (GFunc) : fn needs to use "const" qualifier */ + return g_list_foreach(repr->res_types, (GFunc)fn, user_data); +} + +API int iotcon_repr_get_resource_types_count(iotcon_repr_h repr) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + + return g_list_length(repr->res_types); +} + +API int iotcon_repr_append_resource_types(iotcon_repr_h repr, const char *type) +{ + char *res_type = NULL; + + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == type, IOTCON_ERR_PARAM); + + res_type = ic_utils_strdup(type); + if (NULL == res_type) { + ERR("ic_utils_strdup() Fail"); + return IOTCON_ERR_MEMORY; + } + + repr->res_types = g_list_append(repr->res_types, res_type); + + return IOTCON_ERR_NONE; +} + +API void iotcon_repr_get_resource_interfaces(iotcon_repr_h repr, iotcon_interface_fn fn, + void *user_data) +{ + RET_IF(NULL == repr); + + /* (GFunc) : fn needs to use "const" qualifier */ + return g_list_foreach(repr->interfaces, (GFunc)fn, user_data); +} + +API int iotcon_repr_get_resource_interfaces_count(iotcon_repr_h repr) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + + return g_list_length(repr->interfaces); +} + +API int iotcon_repr_append_resource_interfaces(iotcon_repr_h repr, const char *interface) +{ + char *res_interface = NULL; + + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == interface, IOTCON_ERR_PARAM); + + res_interface = ic_utils_strdup(interface); + if (NULL == res_interface) { + ERR("ic_utils_strdup() Fail"); + return IOTCON_ERR_MEMORY; + } + + repr->interfaces = g_list_append(repr->interfaces, res_interface); + return IOTCON_ERR_NONE; +} + +API int iotcon_repr_get_int(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if(NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return IOTCON_ERR_NO_DATA; + } + + ic_basic_s *real = (ic_basic_s*)value; + RETV_IF(IOTCON_VALUE_INT != real->type, IOTCON_ERR_PARAM); + + return real->val.i; +} + +API int iotcon_repr_set_int(iotcon_repr_h repr, const char *key, int ival) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_INT); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_INT) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_basic_s *real = (ic_basic_s*)value; + + real->val.i = ival; + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API bool iotcon_repr_get_bool(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, false); + RETV_IF(NULL == key, false); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if(NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return false; + } + + ic_basic_s *real = (ic_basic_s*)value; + RETV_IF(IOTCON_VALUE_BOOL != real->type, false); + + return real->val.b; +} + +API int iotcon_repr_set_bool(iotcon_repr_h repr, const char *key, bool bval) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_BOOL); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_BOOL) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_basic_s *real = (ic_basic_s*)value; + + real->val.b = bval; + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API double iotcon_repr_get_double(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, 0); + RETV_IF(NULL == key, 0); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if(NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return 0; + } + + ic_basic_s *real = (ic_basic_s*)value; + RETV_IF(IOTCON_VALUE_DOUBLE != real->type, 0); + + return real->val.d; +} + +API int iotcon_repr_set_double(iotcon_repr_h repr, const char *key, double dbval) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_DOUBLE); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_DOUBLE) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_basic_s *real = (ic_basic_s*)value; + + real->val.d = dbval; + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API char* iotcon_repr_get_str(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, NULL); + RETV_IF(NULL == key, NULL); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if(NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return NULL; + } + + ic_basic_s *real = (ic_basic_s*)value; + RETV_IF(IOTCON_VALUE_STR != real->type, NULL); + + return real->val.s; +} + +API int iotcon_repr_set_str(iotcon_repr_h repr, const char *key, const char *strval) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_STR); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_STR) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_basic_s *real = (ic_basic_s*)value; + + real->val.s = ic_utils_strdup(strval); + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API bool iotcon_repr_is_null(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, false); + RETV_IF(NULL == key, false); + + iotcon_value_h value = (iotcon_value_h) g_hash_table_lookup(repr->hash_table, key); + if (NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return false; + } + + ic_basic_s *real = (ic_basic_s*)value; + + return (IOTCON_VALUE_NULL == real->type) ? true : false; +} + +API int iotcon_repr_set_null(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_NULL); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_NULL) Fail"); + return IOTCON_ERR_MEMORY; + } + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API iotcon_list_h iotcon_repr_get_list(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, NULL); + RETV_IF(NULL == key, NULL); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if(NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return NULL; + } + + ic_val_list_s *real = (ic_val_list_s*)value; + RETV_IF(IOTCON_VALUE_LIST != real->type, NULL); + + return real->list; +} + +API int iotcon_repr_replace_list(iotcon_repr_h repr, const char *key, iotcon_list_h list) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_LIST); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_LIST) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_val_list_s *real = (ic_val_list_s*)value; + RETV_IF(IOTCON_VALUE_LIST != real->type, IOTCON_ERR_PARAM); + + real->list = list; + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API iotcon_repr_h iotcon_repr_get_rep(iotcon_repr_h repr, + const char *key) +{ + RETV_IF(NULL == repr, NULL); + RETV_IF(NULL == key, NULL); + + iotcon_value_h value = g_hash_table_lookup(repr->hash_table, key); + if (NULL == value) { + ERR("g_hash_table_lookup() Fail"); + return NULL; + } + + ic_val_repr_s *real = (ic_val_repr_s*)value; + RETV_IF(IOTCON_VALUE_REPR != real->type, NULL); + + return real->repr; +} + +API int iotcon_repr_replace_rep(iotcon_repr_h dest, const char *key, iotcon_repr_h src) +{ + RETV_IF(NULL == dest, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + RETV_IF(NULL == src, IOTCON_ERR_PARAM); + + iotcon_value_h value = ic_value_new(IOTCON_VALUE_REPR); + if (NULL == value) { + ERR("ic_value_new(IOTCON_VALUE_REPR) Fail"); + return IOTCON_ERR_MEMORY; + } + + ic_val_repr_s *real = (ic_val_repr_s*)value; + + real->repr = src; + + g_hash_table_replace(dest->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +int ic_repr_get_value(iotcon_repr_h repr, const char *key, iotcon_value_h *retval) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + + *retval = g_hash_table_lookup(repr->hash_table, key); + if (NULL == retval) + return IOTCON_ERR_NO_DATA; + else + return IOTCON_ERR_NONE; +} + +int ic_repr_replace_value(iotcon_repr_h repr, const char *key, iotcon_value_h value) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == key, IOTCON_ERR_PARAM); + RETV_IF(NULL == value, IOTCON_ERR_PARAM); + + g_hash_table_replace(repr->hash_table, ic_utils_strdup(key), value); + + return IOTCON_ERR_NONE; +} + +API int iotcon_repr_append_child(iotcon_repr_h parent, iotcon_repr_h child) +{ + RETV_IF(NULL == parent, IOTCON_ERR_PARAM); + RETV_IF(NULL == child, IOTCON_ERR_PARAM); + + parent->children = g_list_append(parent->children, child); + + return IOTCON_ERR_NONE; +} + +API GList* iotcon_repr_get_children(iotcon_repr_h parent) +{ + RETV_IF(NULL == parent, NULL); + + return parent->children; +} + +API int iotcon_repr_get_children_count(iotcon_repr_h parent) +{ + RETV_IF(NULL == parent, IOTCON_ERR_PARAM); + RETV_IF(NULL == parent->children, IOTCON_ERR_PARAM); + + return g_list_length(parent->children); +} + +API iotcon_repr_h iotcon_repr_get_nth_child(iotcon_repr_h parent, int index) +{ + RETV_IF(NULL == parent, NULL); + RETV_IF(NULL == parent->children, NULL); + + return g_list_nth_data(parent->children, index); +} + +API GList* iotcon_repr_get_key_list(iotcon_repr_h repr) +{ + RETV_IF(NULL == repr, NULL); + RETV_IF(NULL == repr->hash_table, NULL); + + return g_hash_table_get_keys(repr->hash_table); +} + +API int iotcon_repr_get_keys_count(iotcon_repr_h repr) +{ + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + RETV_IF(NULL == repr->hash_table, IOTCON_ERR_PARAM); + + return g_hash_table_size(repr->hash_table); +} + +bool ic_repr_has_value(iotcon_repr_h repr, const char *key) +{ + RETV_IF(NULL == repr, false); + RETV_IF(NULL == key, false); + + return g_hash_table_contains(repr->hash_table, key); +} + +JsonObject* ic_repr_generate_json_repr(iotcon_repr_h repr, int *err_code) +{ + char *key; + unsigned int i = 0; + GList *key_list = NULL; + JsonObject *json_obj = NULL; + int error_code = IOTCON_ERR_NONE; + + JsonNode *node_child = NULL; + JsonArray *array_child = NULL; + iotcon_list_h iotlist_child = NULL; + iotcon_repr_h repr_child = NULL; + + RETV_IF(NULL == repr, NULL); + + json_obj = json_object_new(); + key_list = iotcon_repr_get_key_list(repr); + ic_utils_print_str_list(key_list); + + for (i = 0; i < g_list_length(key_list); i++) { + int type = 0; + iotcon_value_h iotvalue_child = NULL; + + key = g_list_nth_data(key_list, i); + ic_repr_get_value(repr, key, &iotvalue_child); + type = iotcon_value_get_type(iotvalue_child); + switch (type) { + case IOTCON_VALUE_INT: + case IOTCON_VALUE_BOOL: + case IOTCON_VALUE_DOUBLE: + case IOTCON_VALUE_STR: + case IOTCON_VALUE_NULL: + node_child = ic_repr_generate_json_value(iotvalue_child); + if (NULL == node_child) { + ERR("ic_repr_generate_json_value() Fail(NULL == node_child)"); + json_object_unref(json_obj); + g_list_free(key_list); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + json_object_set_member(json_obj, key, node_child); + break; + case IOTCON_VALUE_LIST: + iotlist_child = iotcon_value_get_list(iotvalue_child); + array_child = ic_repr_generate_json_array(iotlist_child); + if (NULL == array_child) { + ERR("ic_repr_generate_json_array() Fail(NULL == array_child)"); + json_object_unref(json_obj); + g_list_free(key_list); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + node_child = json_node_new(JSON_NODE_ARRAY); + json_node_set_array(node_child, array_child); + json_object_set_member(json_obj, key, node_child); + break; + case IOTCON_VALUE_REPR: + repr_child = iotcon_value_get_rep(iotvalue_child); + JsonObject *obj = ic_repr_generate_json_repr(repr_child, &error_code); + if (NULL == obj) { + ERR("ic_repr_generate_json_repr() Fail(NULL == obj)"); + json_object_unref(json_obj); + g_list_free(key_list); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + node_child = json_node_new(JSON_NODE_OBJECT); + json_node_set_object(node_child, obj); + json_object_set_member(json_obj, key, node_child); + break; + default: + ERR("Invalid type(%d)", type); + json_object_unref(json_obj); + g_list_free(key_list); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + } + g_list_free(key_list); + + JsonObject *ret_obj = json_object_new(); + json_object_set_object_member(ret_obj, IOTCON_KEY_REP, json_obj); + + return ret_obj; +} + +void _ic_repr_get_res_type_fn(const char *res_type, void *user_data) +{ + JsonArray *rt_array = user_data; + json_array_add_string_element(rt_array, res_type); + DBG("res_type(%s)", res_type); +} + +void _ic_repr_get_res_interface_fn(const char *res_if, void *user_data) +{ + JsonArray *if_array = user_data; + json_array_add_string_element(if_array, res_if); + DBG("res_if(%s)", res_if); +} + +JsonObject* _ic_repr_generate_json_foreach(iotcon_repr_h cur_rep, + unsigned int child_index) +{ + FN_CALL; + JsonObject *repr_obj = NULL; + unsigned int rt_count = 0; + unsigned int if_count = 0; + JsonObject *prop_obj = NULL; + + if (0 < iotcon_repr_get_keys_count(cur_rep)) { + int error_code = IOTCON_ERR_NONE; + DBG("Representation has \"%s\" key", IOTCON_KEY_REP); + + repr_obj = ic_repr_generate_json_repr(cur_rep, &error_code); + if (IOTCON_ERR_NONE != error_code) { + ERR("ic_repr_generate_json_repr() Fail(%d)", error_code); + return NULL; + } + } + + if (NULL == repr_obj) // cur_rep didn't have "rep" key and repr_obj was not made. + repr_obj = json_object_new(); + + if (cur_rep->uri) { + const char *uri = iotcon_repr_get_uri(cur_rep); + DBG("Representation has \"%s\" key", IOTCON_KEY_URI); + json_object_set_string_member(repr_obj, IOTCON_KEY_URI, uri); + } + + if (cur_rep->res_types) { + DBG("Representation has \"%s\" key", IOTCON_KEY_RESOURCETYPES); + rt_count = iotcon_repr_get_resource_types_count(cur_rep); + } + if (cur_rep->interfaces) { + DBG("Representation has \"%s\" key", IOTCON_KEY_INTERFACES); + if_count = iotcon_repr_get_resource_interfaces_count(cur_rep); + } + + if (0 < rt_count || 0 < if_count) { + prop_obj = json_object_new(); + json_object_set_object_member(repr_obj, IOTCON_KEY_PROPERTY, prop_obj); + } + + if (0 < rt_count) { + DBG("Representation has \"%s\" key. count(%d)", IOTCON_KEY_RESOURCETYPES, + rt_count); + JsonArray *rt_array = json_array_new(); + iotcon_repr_get_resource_interfaces(cur_rep, _ic_repr_get_res_type_fn, rt_array); + json_object_set_array_member(prop_obj, IOTCON_KEY_RESOURCETYPES, rt_array); + } + + if (0 < if_count) { + DBG("Representation has \"%s\" key. count(%d)", IOTCON_KEY_INTERFACES, if_count); + JsonArray *if_array = json_array_new(); + iotcon_repr_get_resource_types(cur_rep, _ic_repr_get_res_interface_fn, if_array); + json_object_set_array_member(prop_obj, IOTCON_KEY_INTERFACES, if_array); + } + + return repr_obj; +} + +char* ic_repr_generate_json(iotcon_repr_h repr) +{ + JsonObject *repr_obj = NULL; + gchar *json_data = NULL; + JsonObject *root_obj = NULL; + JsonNode *root_node = NULL; + JsonArray *root_array = NULL; + GList *children = NULL; + unsigned int child_count = 0; + unsigned int child_index = 0; + iotcon_repr_h cur_rep = NULL; + + RETV_IF(NULL == repr, NULL); + + root_obj = json_object_new(); + root_array = json_array_new(); + + if (repr->children) { + children = iotcon_repr_get_children(repr); + child_count = g_list_length(children); + } + + cur_rep = repr; + for (child_index = 0; child_index < child_count + 1; child_index++) { + if (1 <= child_index) { // child representation + cur_rep = iotcon_repr_get_nth_child(repr, child_index - 1); + DBG("[Child representation]", child_index); + } + else { + DBG("[Parent representation]"); + } + repr_obj = _ic_repr_generate_json_foreach(cur_rep, child_index); + if (NULL == repr_obj) { + ERR("_ic_repr_generate_json_foreach() Fali(NULL == repr_obj)"); + json_object_unref(root_obj); + json_array_unref(root_array); + return NULL; + } + json_array_add_object_element(root_array, repr_obj); + } + + json_object_set_array_member(root_obj, IOTCON_KEY_OC, root_array); + + JsonGenerator *gen = json_generator_new(); + root_node = json_node_new(JSON_NODE_OBJECT); + json_node_set_object(root_node, root_obj); + json_generator_set_root(gen, root_node); + + json_data = json_generator_to_data(gen, NULL); + DBG("result : %s", json_data); + + return json_data; +} + +iotcon_repr_h ic_repr_parse_json_obj(JsonObject *obj, int *err_code) +{ + iotcon_repr_h repr = iotcon_repr_new(); + GList *key_list = json_object_get_members(obj); + ic_utils_print_str_list(key_list); + char *key; + unsigned int i = 0; + + for (i = 0; i < g_list_length(key_list); i++) { + key = g_list_nth_data(key_list, i); + + // search child object recursively + JsonNode *child_node = json_object_get_member(obj, key); + if (NULL == child_node) { + ERR("json_object_get_member() Fail(NULL == child_node)"); + iotcon_repr_free(repr); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + if (JSON_NODE_HOLDS_NULL(child_node) || JSON_NODE_HOLDS_VALUE(child_node)) { + iotcon_value_h value = ic_repr_parse_json_value(child_node); + if (NULL == value) { + ERR("ic_repr_parse_json_value() Fail(NULL == value)"); + iotcon_repr_free(repr); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + ic_repr_replace_value(repr, key, value); + } + else if (JSON_NODE_HOLDS_ARRAY(child_node)) { + JsonArray *child_array = json_node_get_array(child_node); + iotcon_list_h list = ic_repr_parse_json_array(child_array); + if (NULL == list) { + ERR("ic_repr_parse_json_array() Fail(NULL == list)"); + iotcon_repr_free(repr); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + iotcon_repr_replace_list(repr, key, list); + } + else if (JSON_NODE_HOLDS_OBJECT(child_node)) { + int error_code = IOTCON_ERR_NONE; + JsonObject *child_obj = json_node_get_object(child_node); + JsonObject *repr_obj = json_object_get_object_member(child_obj, + IOTCON_KEY_REP); + iotcon_repr_h retrep = ic_repr_parse_json_obj(repr_obj, &error_code); + if (NULL == retrep) { + ERR("ic_repr_parse_json_obj() Fail(NULL == retrep)"); + iotcon_repr_free(repr); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + iotcon_repr_replace_rep(repr, key, retrep); + } + else { + ERR("node type(%d) Fail", json_node_get_node_type(child_node)); + iotcon_repr_free(repr); + *err_code = IOTCON_ERR_PARAM; + return NULL; + } + } + g_list_free(key_list); + + return repr; +} + +iotcon_repr_h ic_repr_parse_json(const char *json_string) +{ + const char *uri_value = NULL; + + RETV_IF(NULL == json_string, NULL); + + // incoming json format example : {"href":"/a/address","rep":{"text":"Hello world"}} + DBG("input str : %s", json_string); + + GError *error = NULL; + gboolean ret = FALSE; + JsonParser *parser = json_parser_new(); + ret = json_parser_load_from_data(parser, json_string, strlen(json_string), &error); + if (FALSE == ret) { + ERR("json_parser_load_from_data() Fail(%s)", error->message); + g_error_free(error); + g_object_unref(parser); + return NULL; + } + + JsonObject *root_obj = json_node_get_object(json_parser_get_root(parser)); + + iotcon_repr_h repr = NULL; + if (json_object_has_member(root_obj, IOTCON_KEY_REP)) { + int err_code = IOTCON_ERR_NONE; + + DBG("Representation has \"%s\" key", IOTCON_KEY_REP); + JsonObject *repr_obj = json_object_get_object_member(root_obj, IOTCON_KEY_REP); + repr = ic_repr_parse_json_obj(repr_obj, &err_code); + if (IOTCON_ERR_NONE != err_code) { + ERR("ic_repr_parse_json_obj() Fail(%d)", err_code); + g_object_unref(parser); + return NULL; + } + } + + // root_obj didn't have "repr" key and iotcon_repr_h was not made. + if (NULL == repr) + repr = iotcon_repr_new(); + + if (json_object_has_member(root_obj, IOTCON_KEY_URI)) { + uri_value = json_object_get_string_member(root_obj, IOTCON_KEY_URI); + DBG("Representation has \"%s\" key (%s)", IOTCON_KEY_URI, uri_value); + iotcon_repr_set_uri(repr, uri_value); + } + + if (json_object_has_member(root_obj, IOTCON_KEY_PROPERTY)) { + DBG("Representation has \"%s\" key", IOTCON_KEY_PROPERTY); + JsonObject *property_obj = json_object_get_object_member(root_obj, + IOTCON_KEY_PROPERTY); + + if (json_object_has_member(property_obj, IOTCON_KEY_RESOURCETYPES)) { + DBG("Representation has \"%s\" key", IOTCON_KEY_RESOURCETYPES); + JsonArray *rt_array = json_object_get_array_member(property_obj, + IOTCON_KEY_RESOURCETYPES); + unsigned int rt_count = json_array_get_length(rt_array); + + DBG("rt_count:%d", rt_count); + + unsigned int rt_index = 0; + for (rt_index = 0; rt_index < rt_count; rt_index++) { + iotcon_repr_append_resource_types(repr, + json_array_get_string_element(rt_array, rt_index)); + } + } + if (json_object_has_member(property_obj, IOTCON_KEY_INTERFACES)) { + DBG("Representation has \"%s\" key", IOTCON_KEY_INTERFACES); + JsonArray *if_array = json_object_get_array_member(property_obj, + IOTCON_KEY_INTERFACES); + unsigned int if_count = json_array_get_length(if_array); + + DBG("if_count:%d", if_count); + + unsigned int if_index = 0; + for (if_index = 0; if_index < if_count; if_index++) + iotcon_repr_append_resource_interfaces(repr, + json_array_get_string_element(if_array, if_index)); + } + } + + if (NULL == repr) { + ERR("repr is NULL"); + g_object_unref(parser); + return NULL; + } + + g_object_unref(parser); + + FN_END; + + return repr; +} + +API void iotcon_repr_free(iotcon_repr_h repr) +{ + FN_CALL; + RET_IF(NULL == repr); + + free(repr->uri); + + /* (GDestroyNotify) : iotcon_repr_h is proper type than gpointer */ + g_list_free_full(repr->children, (GDestroyNotify)iotcon_repr_free); + g_list_free_full(repr->interfaces, g_free); + g_list_free_full(repr->res_types, g_free); + g_hash_table_destroy(repr->hash_table); + free(repr); + + FN_END; +} + +API void iotcon_repr_print(iotcon_repr_h repr) +{ + FN_CALL; + gchar *json_data = NULL; + JsonNode *root_node = NULL; + int error_code = IOTCON_ERR_NONE; + + JsonObject *repr_obj = ic_repr_generate_json_repr(repr, &error_code); + if (NULL == repr_obj) { + ERR("ic_repr_generate_json_repr() Fail(NULL == repr_obj)"); + return; + } + + root_node = json_node_new(JSON_NODE_OBJECT); + JsonGenerator *gen = json_generator_new(); + json_generator_set_pretty(gen, TRUE); + json_node_set_object(root_node, repr_obj); + json_generator_set_root(gen, root_node); + + json_data = json_generator_to_data(gen, NULL); + DBG("\n%s", json_data); +} diff --git a/lib/ic-rep.h b/lib/ic-rep.h new file mode 100644 index 0000000..9ecf92b --- /dev/null +++ b/lib/ic-rep.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_H__ + +#include + +#include "ic-struct.h" + +#define IOTCON_KEY_OC "oc" +#define IOTCON_KEY_URI "href" +#define IOTCON_KEY_RESOURCETYPES "rt" +#define IOTCON_KEY_INTERFACES "if" +#define IOTCON_KEY_PROPERTY "prop" +#define IOTCON_KEY_REP "rep" + +int ic_repr_get_value(iotcon_repr_h repr, const char *key, iotcon_value_h *retval); +int ic_repr_replace_value(iotcon_repr_h repr, const char *key, iotcon_value_h value); +bool ic_repr_has_value(iotcon_repr_h repr, const char *key); + +JsonObject* ic_repr_generate_json_repr(iotcon_repr_h repr, int *err_code); +char* ic_repr_generate_json(iotcon_repr_h repr); + +iotcon_repr_h ic_repr_parse_json_obj(JsonObject *obj, int *err_code); +iotcon_repr_h ic_repr_parse_json(const char *json_string); + +#endif // __IOT_CONNECTIVITY_MANAGER_INTERNAL_REPRESENTATION_H__ diff --git a/lib/ic-struct.h b/lib/ic-struct.h new file mode 100644 index 0000000..3ed997c --- /dev/null +++ b/lib/ic-struct.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_STRUCT_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_STRUCT_H__ + +#include "iotcon-struct.h" + +struct ic_value_s { + int type; +}; + +struct ic_list_s { + int type; + GList *list; +}; + +struct ic_repr_s { + char *uri; + GHashTable *hash_table; + GList *children; + GList *res_types; + GList *interfaces; +}; + +typedef struct { + int type; + union { + int i; + bool b; + double d; + char *s; + } val; +} ic_basic_s; + +typedef struct { + int type; + struct ic_list_s *list; +} ic_val_list_s; + +typedef struct { + int type; + struct ic_repr_s *repr; +} ic_val_repr_s; + +/* related with iotcon_response_property_e */ +struct ic_res_response_s { + char *new_resource_uri; + int error_code; + iotcon_header_options header_options; + iotcon_interface_e interface; + iotcon_request_h request_handle; + iotcon_resource_h resource_handle; + iotcon_entity_handler_result_e result; + iotcon_repr_h repr; +}; + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_STRUCT_H__ diff --git a/lib/ic-utils.c b/lib/ic-utils.c new file mode 100644 index 0000000..8210cf6 --- /dev/null +++ b/lib/ic-utils.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include + +#include "ic-common.h" +#include "ic-utils.h" + +char* ic_utils_strdup(const char *src) +{ + char *dest = NULL; + + RETV_IF(NULL == src, NULL); + + errno = 0; + dest = strdup(src); + if (NULL == dest) { + ERR("strdup() Fail(%d)", errno); + return NULL; + } + + return dest; +} + +static void _ic_utils_print_str(void *str, void *user_data) +{ + char *s = str; + + if (s) + DBG("list item : %s", s); +} + +void ic_utils_print_str_list(GList *list) +{ + g_list_foreach(list, _ic_utils_print_str, NULL); +} diff --git a/lib/ic-utils.h b/lib/ic-utils.h new file mode 100644 index 0000000..a3884d1 --- /dev/null +++ b/lib/ic-utils.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_INTERNAL_UTILITY_H__ +#define __IOT_CONNECTIVITY_MANAGER_INTERNAL_UTILITY_H__ + +#include + +char* ic_utils_strdup(const char *src); +void ic_utils_print_str_list(GList *list); + +#endif //__IOT_CONNECTIVITY_MANAGER_INTERNAL_UTILITY_H__ diff --git a/lib/ic.c b/lib/ic.c new file mode 100644 index 0000000..bbd2a12 --- /dev/null +++ b/lib/ic.c @@ -0,0 +1,807 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include +#include +#include +#include + +#include "iotcon.h" + +#include "ic-common.h" +#include "ic-utils.h" +#include "ic-struct.h" +#include "ic-ioty.h" + +/** + * @brief global context + */ +static ic_ctx_s ic_ctx; +static gboolean ic_is_init = FALSE; + +static const char *IC_INTERFACE_DEFAULT = "oc.mi.def"; +static const char *IC_INTERFACE_LINK = "oc.mi.ll"; +static const char *IC_INTERFACE_BATCH = "oc.mi.b"; +static const char *IC_INTERFACE_GROUP = "oc.mo.grp"; + +ic_ctx_s* ic_get_ctx() +{ + return &ic_ctx; +} + + +static void _delete_resource_value(gpointer data) +{ + resource_handler_s *value = data; + + RET_IF(NULL == data); + + free(value->if_name); + free(value->rt_name); + free(value->uri_name); + value->rest_api_cb = NULL; +} + +gboolean iotcon_is_init(void) +{ + return ic_is_init; +} + +static void _set_iotcon_init(gboolean tag) +{ + ic_is_init = tag; +} + +API void iotcon_initialize(const char *addr, unsigned short port) +{ + FN_CALL; + + RETM_IF(TRUE == iotcon_is_init(), "already initialized"); + + ic_iotivity_config(addr, port); + ic_ctx.entity_cb_hash = g_hash_table_new_full(g_int_hash, g_str_equal, NULL, + _delete_resource_value); +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init(); +#endif + _set_iotcon_init(TRUE); +} + +API void iotcon_deinitialize() +{ + FN_CALL; + + RETM_IF(FALSE == iotcon_is_init(), "Not initialized"); + + g_hash_table_destroy(ic_ctx.entity_cb_hash); + g_list_free(ic_ctx.found_device_cb_lst); + _set_iotcon_init(FALSE); +} + +API iotcon_response_h iotcon_create_response(iotcon_request_h req_h, + iotcon_resource_h res_h) +{ + FN_CALL; + + iotcon_response_h resp = calloc(1, sizeof(struct ic_res_response_s)); + if (NULL == resp) { + ERR("calloc() Fail(%d)", errno); + return NULL; + } + + resp->request_handle = req_h; + resp->resource_handle = res_h; + + return resp; +} + + +API int iotcon_response_set(iotcon_response_h resp, iotcon_response_property_e prop, + ...) +{ + int value; + va_list args; + + va_start(args, prop); + + switch (prop) { + case IOTCON_RESP_REPRESENTATION: + resp->repr = va_arg(args, iotcon_repr_h); + break; + case IOTCON_RESP_RESULT: + value = va_arg(args, int); + if (value < IOTCON_EH_OK || IOTCON_EH_MAX <= value) { + ERR("Invalid value"); + return IOTCON_ERR_PARAM; + } + resp->result = value; + break; + case IOTCON_RESP_ERR_CODE: + resp->error_code = va_arg(args, int); + break; + case IOTCON_RESP_RES_URI: + resp->new_resource_uri = va_arg(args, char*); + break; + case IOTCON_RESP_NONE: + default: + break; + } + + va_end(args); + + return IOTCON_ERR_NONE; +} + +API void iotcon_delete_response(iotcon_response_h resp) +{ + FN_CALL; + struct ic_res_response_s *data = resp; + + RET_IF(NULL == resp); + + free(data->new_resource_uri); + iotcon_delete_header_options(data->header_options); + iotcon_repr_free(resp->repr); + free(data); +} + +API iotcon_repr_h iotcon_request_get_representation(const iotcon_request_s *request) +{ + RETV_IF(NULL == request, NULL); + return request->repr; +} + +API iotcon_resource_h iotcon_register_resource(const char *iot_uri, + const char *iot_rt, + iotcon_interface_e iot_if, + iotcon_resource_property_e iot_rt_type, + iotcon_rest_api_handle_cb entity_handler_cb) +{ + FN_CALL; + + resource_handler_s *res; + iotcon_resource_h ret_handle; + + RETV_IF(NULL == iot_uri, NULL); + RETV_IF(NULL == iot_rt, NULL); + RETV_IF(NULL == entity_handler_cb, NULL); + + res = calloc(1, sizeof(resource_handler_s)); + if (NULL == res) { + ERR("calloc Fail(%d)", errno); + return NULL; + } + + switch (iot_if) { + case IOTCON_INTERFACE_GROUP: + res->if_name = ic_utils_strdup(IC_INTERFACE_GROUP); + break; + case IOTCON_INTERFACE_BATCH: + res->if_name = ic_utils_strdup(IC_INTERFACE_BATCH); + break; + case IOTCON_INTERFACE_LINK: + res->if_name = ic_utils_strdup(IC_INTERFACE_LINK); + break; + case IOTCON_INTERFACE_DEFAULT: + default: + res->if_name = ic_utils_strdup(IC_INTERFACE_DEFAULT); + break; + } + + res->rt_name = ic_utils_strdup(iot_rt); + if (NULL == res->rt_name) { + ERR("ic_utils_strdup() Fail(%d)", errno); + free(res); + return NULL; + } + + res->uri_name = ic_utils_strdup(iot_uri); + if (NULL == res->uri_name) { + ERR("ic_utils_strdup() Fail(%d)", errno); + free(res->rt_name); + free(res); + return NULL; + } + + res->rest_api_cb = entity_handler_cb; + + ret_handle = ic_ioty_register_res(iot_uri, iot_rt, iot_if, iot_rt_type); + if (NULL == ret_handle) { + ERR("registerResource Fail"); + free(res->rt_name); + free(res->uri_name); + free(res); + return NULL; + } + + g_hash_table_insert(ic_ctx.entity_cb_hash, ret_handle, res); + + return ret_handle; +} + + +API int iotcon_unregister_resource(const iotcon_resource_h resource_handle) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_unregister_res(resource_handle); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_bind_type_to_res() Fail(%d)", ret); + + g_hash_table_remove(ic_ctx.entity_cb_hash, resource_handle); + + return ret; +} + +API int iot_bind_interface_to_resource(iotcon_resource_h resource_handle, + const char *interface_type) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_bind_iface_to_res(resource_handle, interface_type); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_bind_type_to_res() Fail(%d)", ret); + + return ret; +} + +API int iotcon_bind_type_to_resource(iotcon_resource_h resource_handle, + const char *resource_type) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_bind_type_to_res(resource_handle, resource_type); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_bind_type_to_res() Fail(%d)", ret); + + return ret; +} + +API int iotcon_bind_resource(iotcon_resource_h parent, iotcon_resource_h child) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_bind_res(parent, child); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_bind_res() Fail(%d)", ret); + + return ret; +} + + +API int iotcon_register_device_info(iotcon_device_info_s *device_info) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_register_device_info(device_info); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_register_device_info() Fail(%d)", ret); + + return ret; +} + +API int iotcon_subscribe_device_info(char *host, char *uri, + iotcon_found_device_info_cb found_cb /*, int QoS*/) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + RETV_IF(NULL == uri, IOTCON_ERR_PARAM); + RETV_IF(NULL == found_cb, IOTCON_ERR_PARAM); + + /* If we add device_cb to manage app's CB if we don't have any app's cb */ + if (0 == g_list_length(ic_ctx.found_device_cb_lst)) { + ret = ic_ioty_get_device_info(host, uri); + if (IOTCON_ERR_NONE != ret) { + ERR("ic_ioty_get_device_info() Fail(%d)", ret); + return ret; + } + } + + ic_ctx.found_device_cb_lst = g_list_append(ic_ctx.found_device_cb_lst, found_cb); + + return IOTCON_ERR_NONE; +} + +API void iotcon_unsubscribe_device_info(char *host, char *uri, + iotcon_found_device_info_cb found_cb) +{ + FN_CALL; + + GList *node = g_list_first(ic_ctx.found_device_cb_lst); + while (node) { + GList *next_node = node->next; + + iotcon_found_device_info_cb found_cb_check = node->data; + if (found_cb_check == found_cb) { + ic_ctx.found_device_cb_lst = g_list_remove_link(ic_ctx.found_device_cb_lst, + node); + g_list_free_1(node); + } + node = next_node; + } +} + +API int iotcon_send_notify_response(iotcon_response_h resp, iotcon_observers observers) +{ + FN_CALL; + int ret; + + ret = ic_ioty_send_notify(resp, observers); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_send_notify() Fail(%d)", ret); + + return ret; +} + +API int iotcon_send_resource_response(iotcon_response_h resp) +{ + FN_CALL; + int ret; + + ret = ic_ioty_send_res_response_data(resp); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_send_res_response_data() Fail(%d)", ret); + + return ret; +} + +API iotcon_presence_h iotcon_subscribe_presence(const char *host_address, + iotcon_presence_handle_cb presence_handler_cb, void *user_data) +{ + iotcon_presence_h handle; + + handle = ic_ioty_subscribe_presence(host_address, presence_handler_cb, user_data); + if (NULL == handle) + ERR("ic_ioty_subscribe_presence() Fail"); + + return handle; +} + +API int iotcon_unsubscribe_presence(iotcon_presence_h presence_handle) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_unsubscribe_presence(presence_handle); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_unsubscribe_presence() Fail(%d)", ret); + + return ret; +} + +API int iotcon_start_presence(const unsigned int time_to_live) +{ + FN_CALL; + + int ret; + + ret = ic_ioty_start_presence(time_to_live); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_start_presence() Fail(%d)", ret); + + return ret; +} + +API int iotcon_stop_presence() +{ + FN_CALL; + + int ret; + + ret = ic_ioty_stop_presence(); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_stop_presence() Fail(%d)", ret); + + return ret; +} + +API int iotcon_find_resource(const char *host, const char *resource_name, + iotcon_found_resource_cb found_resource_cb, void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + RETV_IF(NULL == host, IOTCON_ERR_PARAM); + RETV_IF(NULL == resource_name, IOTCON_ERR_PARAM); + RETV_IF(NULL == found_resource_cb, IOTCON_ERR_PARAM); + + ret = ic_ioty_find_resource(host, resource_name, found_resource_cb, user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_find_resource() Fail(%d)", ret); + + return ret; +} + +API iotcon_resource_s iotcon_construct_resource_object(const char *host, + const char *uri, + bool is_observable, + iotcon_resource_types resource_type, + iotcon_resource_interfaces resource_if) +{ + FN_CALL; + + iotcon_resource_s resource_s = {0}; + GList *node = NULL; + + resource_s.resource_host = ic_utils_strdup(host); + resource_s.resource_uri = ic_utils_strdup(uri); + resource_s.is_observable = is_observable; + resource_s.resource_types = iotcon_new_resource_types(); + resource_s.resource_interfaces = iotcon_new_resource_interfaces(); + + for (node = g_list_first(resource_type); NULL != node; node = g_list_next(node)) { + resource_s.resource_types = g_list_append(resource_s.resource_types, + ic_utils_strdup(node->data)); + } + + for (node = g_list_first(resource_if); NULL != node; node = g_list_next(node)) { + resource_s.resource_interfaces = g_list_append(resource_s.resource_interfaces, + ic_utils_strdup(node->data)); + } + + return resource_s; +} + +API void iotcon_destruct_resource_object(iotcon_resource_s *resource) +{ + FN_CALL; + + free(resource->resource_uri); + free(resource->resource_host); + iotcon_delete_header_options(resource->header_options); + iotcon_delete_resource_types(resource->resource_types); + iotcon_delete_resource_interfaces(resource->resource_interfaces); +} + +API iotcon_resource_s iotcon_copy_resource(iotcon_resource_s resource) +{ + FN_CALL; + + iotcon_resource_s resource_s = {0}; + GList *node = NULL; + + resource_s.resource_host = ic_utils_strdup(resource.resource_host); + resource_s.resource_uri = ic_utils_strdup(resource.resource_uri); + resource_s.is_observable = resource.is_observable; + resource_s.resource_types = iotcon_new_resource_types(); + resource_s.resource_interfaces = iotcon_new_resource_interfaces(); + resource_s.observe_handle = resource.observe_handle; + + for (node = g_list_first(resource.resource_types); NULL != node; + node = g_list_next(node)) { + resource_s.resource_types = g_list_append(resource_s.resource_types, + ic_utils_strdup(node->data)); + } + + for (node = g_list_first(resource.resource_interfaces); NULL != node; + node = g_list_next(node)) { + resource_s.resource_interfaces = g_list_append(resource_s.resource_interfaces, + ic_utils_strdup(node->data)); + } + + return resource_s; +} + +API int iotcon_get(iotcon_resource_s resource, iotcon_query_parameters query_params, + iotcon_on_get_cb on_get_cb, void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + ret = ic_ioty_get(resource, query_params, on_get_cb, user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_get() Fail(%d)", ret); + + return ret; +} + +API int iotcon_put(iotcon_resource_s resource, iotcon_repr_h repr, + iotcon_query_parameters query_params, iotcon_on_put_cb on_put_cb, void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + + ret = ic_ioty_put(resource, repr, query_params, on_put_cb, user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_put() Fail(%d)", ret); + + return ret; +} + +API int iotcon_post(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_post_cb on_post_cb, + void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + RETV_IF(NULL == repr, IOTCON_ERR_PARAM); + + ret = ic_ioty_post(resource, repr, query_params, on_post_cb, user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_post() Fail(%d)", ret); + + return ret; +} + +API int iotcon_delete_resource(iotcon_resource_s resource, + iotcon_on_delete_cb on_delete_cb, void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + ret = ic_ioty_delete_res(resource, on_delete_cb, user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_delete_res() Fail(%d)", ret); + + return ret; +} + +API int iotcon_observe(iotcon_observe_type_e observe_type, + iotcon_resource_s *resource, + iotcon_query_parameters query_params, + iotcon_on_observe_cb on_observe_cb, + void *user_data) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + ret = ic_ioty_observe(resource, observe_type, query_params, on_observe_cb, + user_data); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_observe() Fail(%d)", ret); + + return ret; +} + +API int iotcon_cancel_observe(iotcon_resource_s resource) +{ + FN_CALL; + + int ret = IOTCON_ERR_NONE; + + ret = ic_ioty_cancel_observe(resource); + if (IOTCON_ERR_NONE != ret) + ERR("ic_ioty_cancel_observe() Fail(%d)", ret); + + return ret; +} + +API iotcon_resource_types iotcon_new_resource_types() +{ + return NULL; +} + +API iotcon_resource_types iotcon_add_resource_types(iotcon_resource_types resource_types, + const char *resource_type) +{ + FN_CALL; + + resource_types = g_list_append(resource_types, ic_utils_strdup(resource_type)); + return resource_types; +} + +API void iotcon_delete_resource_types(iotcon_resource_types resource_types) +{ + FN_CALL; + + g_list_free_full(resource_types, g_free); +} + +API iotcon_resource_interfaces iotcon_new_resource_interfaces() +{ + FN_CALL; + + return NULL; +} + +API iotcon_resource_interfaces iotcon_add_resource_interfaces( + iotcon_resource_interfaces resource_interfaces, iotcon_interface_e interface) +{ + FN_CALL; + + char *resource_interface; + + switch (interface) { + case IOTCON_INTERFACE_GROUP: + resource_interface = ic_utils_strdup(IC_INTERFACE_GROUP); + break; + case IOTCON_INTERFACE_BATCH: + resource_interface = ic_utils_strdup(IC_INTERFACE_BATCH); + break; + case IOTCON_INTERFACE_LINK: + resource_interface = ic_utils_strdup(IC_INTERFACE_LINK); + break; + case IOTCON_INTERFACE_DEFAULT: + resource_interface = ic_utils_strdup(IC_INTERFACE_DEFAULT); + break; + default: + ERR("Invalid Interface"); + return resource_interfaces; + } + + resource_interfaces = g_list_append(resource_interfaces, resource_interface); + + return resource_interfaces; +} + +API void iotcon_delete_resource_interfaces(iotcon_resource_interfaces resource_interfaces) +{ + FN_CALL; + + g_list_free_full(resource_interfaces, g_free); +} + +API iotcon_header_options iotcon_new_header_options() +{ + iotcon_header_options options = NULL; + options = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + return options; +} + +API iotcon_error_e iotcon_add_header_option(iotcon_header_options options, + const unsigned short id, const char *data) +{ + FN_CALL; + + RETV_IF(((id < IOTCON_HEADER_OPTIONID_MIN) + || (IOTCON_HEADER_OPTIONID_MAX < id)), IOTCON_ERR_PARAM); + + gpointer value = ic_utils_strdup(data); + + g_hash_table_insert(options, GUINT_TO_POINTER(id), value); + + return IOTCON_ERR_NONE; +} + +API void iotcon_delete_header_options(iotcon_header_options options) +{ + RET_IF(NULL == options); + + g_hash_table_destroy(options); +} + +API iotcon_query_parameters iotcon_new_query_params() +{ + iotcon_query_parameters query_params = NULL; + + query_params = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + + return query_params; +} + +API void iotcon_add_query_param(iotcon_query_parameters query_params, const char *key, + const char *value) +{ + g_hash_table_insert(query_params, ic_utils_strdup(key), ic_utils_strdup(value)); +} + +API void iotcon_delete_query_params(iotcon_query_parameters query_params) +{ + RET_IF(NULL == query_params); + + g_hash_table_destroy(query_params); +} + +API char* iotcon_find_query_param(iotcon_query_parameters query_params, const char *key) +{ + return g_hash_table_lookup(query_params, key); +} + +API iotcon_observers iotcon_new_observation() +{ + return NULL; +} + +API iotcon_observers iotcon_add_observation(iotcon_observers observers, + iotcon_observation_info_s obs) +{ + iotcon_observation_info_s *obs_node = calloc(1, sizeof(iotcon_observation_info_s)); + RETV_IF(NULL == obs_node, observers); + + obs_node->action = obs.action; + obs_node->obs_id = obs.obs_id; + + observers = g_list_append(observers, obs_node); + + return observers; +} + +API iotcon_observers iotcon_delete_observation(iotcon_observers observers, + iotcon_observation_info_s obs) +{ + GList *node = NULL; + + node = g_list_find(observers, (gconstpointer)&obs); + observers = g_list_delete_link(observers, node); + + return observers; +} + +API void iotcon_free_observation(iotcon_observers observers) +{ + g_list_free_full(observers, g_free); +} + +API char* iotcon_get_resource_uri(iotcon_resource_s resource_s) +{ + return resource_s.resource_uri; +} + +API char* iotcon_get_resource_host(iotcon_resource_s resource_s) +{ + return resource_s.resource_host; +} + +API iotcon_resource_types iotcon_get_resource_types(iotcon_resource_s resource_s) +{ + return resource_s.resource_types; +} + +API iotcon_resource_interfaces iotcon_get_resource_interfaces( + iotcon_resource_s resource_s) +{ + return resource_s.resource_interfaces; +} + +API void iotcon_set_header_options(iotcon_resource_s *resource_s, + iotcon_header_options options) +{ + iotcon_header_options header_options; + GHashTableIter iter; + gpointer key = NULL; + gpointer value = NULL; + + RET_IF(NULL == resource_s); + RET_IF(NULL == options); + + header_options = iotcon_new_header_options(); + g_hash_table_iter_init(&iter, options); + while (g_hash_table_iter_next(&iter, &key, &value)) { + iotcon_add_header_option(header_options, GPOINTER_TO_UINT(key), value); + } + resource_s->header_options = header_options; +} + +API void iotcon_unset_header_options(iotcon_resource_s *resource_s) +{ + RET_IF(NULL == resource_s); + iotcon_delete_header_options(resource_s->header_options); + resource_s->header_options = NULL; +} diff --git a/lib/include/iotcon-constant.h b/lib/include/iotcon-constant.h new file mode 100644 index 0000000..4ebb314 --- /dev/null +++ b/lib/include/iotcon-constant.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_CONSTANT_H__ +#define __IOT_CONNECTIVITY_MANAGER_CONSTANT_H__ + +/** + * @brief HeaderOption range from 2048 t0 3000 + * NOTE: HeaderOptionID is an unsigned integer value which MUST be within + * range of 2048 to 3000 inclusive of lower and upper bound. + * HeaderOptions instance creation fails if above condition is not satisfied. + */ +#define IOTCON_HEADER_OPTIONID_MIN 2048 +#define IOTCON_HEADER_OPTIONID_MAX 3000 + + +/** + * @brief Action associated with observation + */ +typedef enum { + IOTCON_OBSERVE_REGISTER = 0, + IOTCON_OBSERVE_DEREGISTER = 1, + IOTCON_OBSERVE_NO_OPTION = 2 +} iotcon_osbserve_action_e; + +typedef enum { + IOTCON_OBSERVE = 0, + IOTCON_OBSERVE_ALL = 1 +} iotcon_observe_type_e; + +typedef enum { + IOTCON_INTERFACE_DEFAULT = 0, + IOTCON_INTERFACE_LINK = 1, + IOTCON_INTERFACE_BATCH = 2, + IOTCON_INTERFACE_GROUP = 3, + IOTCON_INTERFACE_MAX = 4 +} iotcon_interface_e; + +typedef enum { + IOTCON_HIDDEN = 0, + IOTCON_ACTIVE = (1 << 0), + IOTCON_DISCOVERABLE = (1 << 1), + IOTCON_OBSERVABLE = (1 << 2), + IOTCON_SLOW = (1 << 3), + IOTCON_SECURE = (1 << 4), +} iotcon_resource_property_e; + +typedef enum { + IOTCON_RESP_NONE = 0, + IOTCON_RESP_RES_URI = 1, + IOTCON_RESP_ERR_CODE = 2, + IOTCON_RESP_RESULT = 3, + IOTCON_RESP_REPRESENTATION = 4, +} iotcon_response_property_e; + +typedef enum { + IOTCON_INIT_FLAG = (1 << 0), + IOTCON_REQUEST_FLAG = (1 << 1), + IOTCON_OBSERVE_FLAG = (1 << 2) +} iotcon_entity_handler_flag_e; + +typedef enum { + IOTCON_EH_OK = 0, + IOTCON_EH_ERROR, + IOTCON_EH_RESOURCE_CREATED, + IOTCON_EH_RESOURCE_DELETED, + IOTCON_EH_SLOW, + IOTCON_EH_FORBIDDEN, + IOTCON_EH_MAX +} iotcon_entity_handler_result_e; + +#endif //__IOT_CONNECTIVITY_MANAGER_CONSTANT_H__ diff --git a/lib/include/iotcon-errors.h b/lib/include/iotcon-errors.h new file mode 100644 index 0000000..aefa06a --- /dev/null +++ b/lib/include/iotcon-errors.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_ERRORS_H__ +#define __IOT_CONNECTIVITY_MANAGER_ERRORS_H__ + +typedef enum +{ + IOTCON_ERR_NONE = 0, + IOTCON_ERR_MEMORY = -1, + IOTCON_ERR_GDBUS = -2, + IOTCON_ERR_ENVIRONMENT = -3, + IOTCON_ERR_SYSTEM = -4, + IOTCON_ERR_PLUGIN = -5, + IOTCON_ERR_PARAM = -6, + IOTCON_ERR_ALREADY = -7, + IOTCON_ERR_BUSY = -8, + IOTCON_ERR_NOT_SUPPORT = -9, + IOTCON_ERR_DISABLE = -10, + IOTCON_ERR_IOTIVITY = -11, + IOTCON_ERR_NO_DATA = -12 +}iotcon_error_e; + +#endif //__IOT_CONNECTIVITY_MANAGER_ERRORS_H__ diff --git a/lib/include/iotcon-struct.h b/lib/include/iotcon-struct.h new file mode 100644 index 0000000..93f2763 --- /dev/null +++ b/lib/include/iotcon-struct.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_STRUCT_H__ +#define __IOT_CONNECTIVITY_MANAGER_STRUCT_H__ + +#include +#include + +#include "iotcon-constant.h" + +typedef struct ic_value_s* iotcon_value_h; +typedef struct ic_list_s* iotcon_list_h; +typedef struct ic_repr_s* iotcon_repr_h; + +/** + * @brief Handle to an OCResource object owned by the OCStack. + */ +typedef void* iotcon_resource_h; +typedef void* iotcon_request_h; +typedef void* iotcon_presence_h; +typedef void* iotcon_observe_h; + +typedef GList* iotcon_observers; +typedef unsigned char iotcon_observation_id; +typedef GHashTable* iotcon_header_options; +typedef GHashTable* iotcon_query_parameters; + +typedef GList *iotcon_resource_types; +typedef GList *iotcon_resource_interfaces; + + +typedef struct ic_res_response_s* iotcon_response_h; + +/** + * @brief These are used in setting header options. + */ +typedef struct { + unsigned short option_id; + char *option_data; +} iotcon_header_option; + + +/** + * @brief observation information structure + */ +typedef struct { + // Action associated with observation request + iotcon_osbserve_action_e action; + // Identifier for observation being registered/deregistered + iotcon_observation_id obs_id; +} iotcon_observation_info_s; + + +typedef struct { + char *resource_uri; + char *resource_host; + bool is_observable; + bool is_collection; + iotcon_header_options header_options; + iotcon_resource_types resource_types; + iotcon_resource_interfaces resource_interfaces; + iotcon_observe_h observe_handle; +} iotcon_resource_s; + + +typedef struct { + char *request_type; + char *res_uri; + iotcon_header_options header_opts; + iotcon_query_parameters query_params; + int request_handler_flag; + iotcon_request_h request_handle; + iotcon_resource_h resource_handle; + iotcon_observation_info_s observation_info; + iotcon_repr_h repr; +} iotcon_request_s; + + +/** + * @brief Following structure describes the device properties. + * All non-Null properties will be included in a device discovery request. + */ +typedef struct +{ + char *device_name; + char *host_name; + char *device_uuid; + char *content_type; + char *version; + char *manufacturer_name; + char *manufacturer_url; + char *model_number; + char *date_of_manufacture; + char *platform_version; + char *firmware_version; + char *support_url; +} iotcon_device_info_s; +#endif //__IOT_CONNECTIVITY_MANAGER_STRUCT_H__ diff --git a/lib/include/iotcon.h b/lib/include/iotcon.h new file mode 100644 index 0000000..6a5c1a4 --- /dev/null +++ b/lib/include/iotcon.h @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_H__ +#define __IOT_CONNECTIVITY_MANAGER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +void iotcon_initialize(const char *addr, unsigned short port); +void iotcon_deinitialize(); + +iotcon_response_h iotcon_create_response(iotcon_request_h req_h, + iotcon_resource_h res_h); +void iotcon_delete_response(iotcon_response_h resp); + +typedef void (*iotcon_rest_api_handle_cb)(const iotcon_request_s *request); + +iotcon_repr_h iotcon_request_get_representation(const iotcon_request_s *request); + +iotcon_resource_h iotcon_register_resource(const char *uri, const char *rt, + iotcon_interface_e iot_if, iotcon_resource_property_e rt_type, + iotcon_rest_api_handle_cb entity_handler_cb); +int iotcon_unregister_resource(const iotcon_resource_h resource_handle); + +int iotcon_bind_interface_to_resource(iotcon_resource_h resource_handle, + const char *interface_type); +int iotcon_bind_type_to_resource(iotcon_resource_h resource_handle, + const char *resource_type); +int iotcon_bind_resource(iotcon_resource_h parent, iotcon_resource_h child); + +typedef void (*iotcon_found_device_info_cb)(const iotcon_device_info_s *info); + +int iotcon_register_device_info(iotcon_device_info_s *device_info); + +int iotcon_subscribe_device_info(char *host, char *uri, + iotcon_found_device_info_cb found_cb); +void iotcon_unsubscribe_device_info(char *host, char *uri, + iotcon_found_device_info_cb found_cb); + +int iotcon_response_set(iotcon_response_h resp, iotcon_response_property_e prop, ...); + +int iotcon_send_notify_response(iotcon_response_h resp, iotcon_observers observers); +int iotcon_send_resource_response(iotcon_response_h resp); + +typedef void (*iotcon_presence_handle_cb)(iotcon_error_e result, const unsigned int nonce, + const char *host_address, void *user_data); + +iotcon_presence_h iotcon_subscribe_presence(const char *host_address, + iotcon_presence_handle_cb presence_handler_cb, void *user_data); +int iotcon_unsubscribe_presence(iotcon_presence_h presence_handle); +int iotcon_start_presence(const unsigned int time_to_live); +int iotcon_stop_presence(); + +typedef void (*iotcon_found_resource_cb)(iotcon_resource_s *resource, void *user_data); + +int iotcon_find_resource(const char *host, const char *resource_name, + iotcon_found_resource_cb found_resource_cb, void *user_data); + +typedef void (*iotcon_on_get_cb)(const iotcon_header_options header_options, + const iotcon_repr_h repr, const int e_code, void *user_data); +typedef void (*iotcon_on_put_cb)(const iotcon_header_options header_options, + const iotcon_repr_h repr, const int e_code, void *user_data); +typedef void (*iotcon_on_post_cb)(const iotcon_header_options header_options, + const iotcon_repr_h repr, const int e_code, void *user_data); +typedef void (*iotcon_on_observe_cb)(const iotcon_header_options header_options, + const iotcon_repr_h repr, const int e_code, const int sequence_number, + void *user_data); +typedef void (*iotcon_on_delete_cb)(const iotcon_header_options header_options, + const int e_code, void *user_data); + +iotcon_resource_s iotcon_construct_resource_object(const char *host, + const char *uri, + bool is_observable, + iotcon_resource_types resource_type, + iotcon_resource_interfaces resource_if); +void iotcon_destruct_resource_object(iotcon_resource_s *resource); +iotcon_resource_s iotcon_copy_resource(iotcon_resource_s resource); + +int iotcon_get(iotcon_resource_s resource, iotcon_query_parameters query_params, + iotcon_on_get_cb on_get_cb, void *user_data); +int iotcon_put(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_put_cb on_put_cb, + void *user_data); +int iotcon_post(iotcon_resource_s resource, + iotcon_repr_h repr, + iotcon_query_parameters query_params, + iotcon_on_post_cb on_post_cb, + void *user_data); +int iotcon_delete_resource(iotcon_resource_s resource, + iotcon_on_delete_cb on_delete_cb, + void *user_data); + +int iotcon_observe(iotcon_observe_type_e observe_type, + iotcon_resource_s *resource, + iotcon_query_parameters query_params, + iotcon_on_observe_cb on_observe_cb, + void *user_data); +int iotcon_cancel_observe(iotcon_resource_s resource); + +iotcon_resource_types iotcon_new_resource_types(); +iotcon_resource_types iotcon_add_resource_types(iotcon_resource_types resource_types, + const char *resource_type); +void iotcon_delete_resource_types(iotcon_resource_types resource_types); + +iotcon_resource_interfaces iotcon_new_resource_interfaces(); +iotcon_resource_interfaces iotcon_add_resource_interfaces( + iotcon_resource_interfaces resource_interfaces, iotcon_interface_e interface); +void iotcon_delete_resource_interfaces(iotcon_resource_interfaces resource_interfaces); + +iotcon_header_options iotcon_new_header_options(); +iotcon_error_e iotcon_add_header_option(iotcon_header_options options, + const unsigned short id, const char *data); +void iotcon_delete_header_options(iotcon_header_options options); + +iotcon_query_parameters iotcon_new_query_params(); +void iotcon_add_query_param(iotcon_query_parameters query_params, const char *key, + const char *value); +void iotcon_delete_query_params(iotcon_query_parameters query_params); +char* iotcon_find_query_param(iotcon_query_parameters query_params, const char *key); + +iotcon_observers iotcon_new_observation(); +iotcon_observers iotcon_add_observation(iotcon_observers observers, + iotcon_observation_info_s obs); +iotcon_observers iotcon_delete_observation(iotcon_observers observers, + iotcon_observation_info_s obs); +void iotcon_free_observation(iotcon_observers observers); + +char* iotcon_get_resource_uri(iotcon_resource_s resource_s); +char* iotcon_get_resource_host(iotcon_resource_s resource_s); +iotcon_resource_types iotcon_get_resource_types(iotcon_resource_s resource_s); +iotcon_resource_interfaces iotcon_get_resource_interfaces(iotcon_resource_s resource_s); +void iotcon_set_header_options(iotcon_resource_s *resource_s, + iotcon_header_options options); +void iotcon_unset_header_options(iotcon_resource_s *resource_s); + +iotcon_repr_h iotcon_repr_new(); +const char* iotcon_repr_get_uri(iotcon_repr_h repr); +int iotcon_repr_set_uri(iotcon_repr_h repr, const char *uri); + +typedef void (*iotcon_resourcetype_fn)(const char *res_type, void *user_data); +void iotcon_repr_get_resource_types(iotcon_repr_h repr, iotcon_resourcetype_fn fn, + void *user_data); +int iotcon_repr_append_resource_types(iotcon_repr_h repr, const char *type); +int iotcon_repr_get_resource_types_count(iotcon_repr_h repr); + +typedef void (*iotcon_interface_fn)(const char *res_if, void *user_data); +void iotcon_repr_get_resource_interfaces(iotcon_repr_h repr, iotcon_interface_fn fn, + void *user_data); +int iotcon_repr_append_resource_interfaces(iotcon_repr_h repr, const char *interface); +int iotcon_repr_get_resource_interfaces_count(iotcon_repr_h repr); + +int iotcon_repr_get_int(iotcon_repr_h repr, const char *key); +int iotcon_repr_set_int(iotcon_repr_h repr, const char *key, int ival); +bool iotcon_repr_get_bool(iotcon_repr_h repr, const char *key); +int iotcon_repr_set_bool(iotcon_repr_h repr, const char *key, bool bval); +double iotcon_repr_get_double(iotcon_repr_h repr, const char *key); +int iotcon_repr_set_double(iotcon_repr_h repr, const char *key, double dbval); +char* iotcon_repr_get_str(iotcon_repr_h repr, const char *key); +int iotcon_repr_set_str(iotcon_repr_h repr, const char *key, const char *strval); +iotcon_list_h iotcon_repr_get_list(iotcon_repr_h repr, const char *key); +int iotcon_repr_replace_list(iotcon_repr_h repr, const char *key, iotcon_list_h list); +iotcon_repr_h iotcon_repr_get_rep(iotcon_repr_h repr, const char *key); +int iotcon_repr_replace_rep(iotcon_repr_h dest, const char *key, iotcon_repr_h src); +bool iotcon_repr_is_null(iotcon_repr_h repr, const char *key); +int iotcon_repr_set_null(iotcon_repr_h repr, const char *key); + +GList* iotcon_repr_get_children(iotcon_repr_h parent); +int iotcon_repr_get_children_count(iotcon_repr_h parent); +int iotcon_repr_append_child(iotcon_repr_h parent, iotcon_repr_h child); +iotcon_repr_h iotcon_repr_get_nth_child(iotcon_repr_h parent, int index); + +GList* iotcon_repr_get_key_list(iotcon_repr_h repr); +int iotcon_repr_get_keys_count(iotcon_repr_h repr); + +iotcon_list_h iotcon_int_list_new(); +iotcon_list_h iotcon_bool_list_new(); +iotcon_list_h iotcon_double_list_new(); +iotcon_list_h iotcon_str_list_new(); +iotcon_list_h iotcon_list_list_new(); +iotcon_list_h iotcon_repr_list_new(); +iotcon_list_h iotcon_list_append_int(iotcon_list_h list, int ival); +iotcon_list_h iotcon_list_append_bool(iotcon_list_h list, bool bval); +iotcon_list_h iotcon_list_append_double(iotcon_list_h list, double dbval); +iotcon_list_h iotcon_list_append_str(iotcon_list_h list, const char *strval); +iotcon_list_h iotcon_list_append_rep(iotcon_list_h list, iotcon_repr_h repr); +iotcon_repr_h iotcon_list_get_nth_rep(iotcon_list_h list, int index); +int iotcon_list_get_length(iotcon_list_h list); +iotcon_list_h iotcon_list_get_nth_list(iotcon_list_h list, int index); +iotcon_value_h iotcon_list_get_nth_value(iotcon_list_h list, int index); + +typedef void (*iotcon_list_fn)(iotcon_value_h value, void *user_data); +void iotcon_list_foreach(iotcon_list_h list, iotcon_list_fn fn, void *user_data); + +int iotcon_value_get_type(iotcon_value_h value); +int iotcon_value_get_int(iotcon_value_h value); +bool iotcon_value_get_bool(iotcon_value_h value); +double iotcon_value_get_double(iotcon_value_h value); +char* iotcon_value_get_str(iotcon_value_h value); +iotcon_list_h iotcon_value_get_list(iotcon_value_h value); +iotcon_repr_h iotcon_value_get_rep(iotcon_value_h value); + +void iotcon_repr_free(iotcon_repr_h repr); + +void iotcon_repr_print(iotcon_repr_h repr); + +#ifdef __cplusplus +} +#endif + +#endif //__IOT_CONNECTIVITY_MANAGER_H__ diff --git a/lib/iotcon.pc.in b/lib/iotcon.pc.in new file mode 100644 index 0000000..7750f73 --- /dev/null +++ b/lib/iotcon.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix}/bin +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@/@CLIENT@ + +Name: @CLIENT@ +Description: IoT Connectivity Manager +Version: @FULLVER@ +Requires: +Libs: -L${libdir} -l@CLIENT@ +Cflags: -I${includedir} diff --git a/packaging/iotcon.manifest b/packaging/iotcon.manifest new file mode 100644 index 0000000..5e0c7a6 --- /dev/null +++ b/packaging/iotcon.manifest @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/iotcon.spec b/packaging/iotcon.spec new file mode 100644 index 0000000..e288d5c --- /dev/null +++ b/packaging/iotcon.spec @@ -0,0 +1,57 @@ +Name: iotcon +Summary: IoT Connectivity Manager +Version: 0.0.1 +Release: 0 +Group: Network & Connectivity/Other +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +BuildRequires: cmake +BuildRequires: boost-devel +BuildRequires: iotivity-devel +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(notification) + + +%description +IoT Connectivity Manager and Library + +%package devel +Summary: IoT Connectivity Manager (devel) +Group: Network & Connectivity/Development +Requires: %{name} = %{version} + +%description devel +IoT Connectivity Manager development Kit + +%prep +%setup -q +cp %{SOURCE1001} . + +%build +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%cmake . -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DBIN_INSTALL_DIR:PATH=%{_bindir} + + +%install +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/lib%{name}.so.* +%license LICENSE.APLv2 +%{_bindir}/crud-test-client +%{_bindir}/crud-test-server + +%files devel +%{_libdir}/lib%{name}.so +%{_libdir}/pkgconfig/%{name}.pc +%{_includedir}/%{name}/*.h + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..ef2b277 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,20 @@ +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/include) + +SET(CRUD_TEST_CLIENT "crud-test-client") +SET(CRUD_TEST_SERVER "crud-test-server") + +FILE(GLOB CRUD_TEST_CLIENT_SRCS crud-test-client.c) +FILE(GLOB CRUD_TEST_SERVER_SRCS crud-test-server.c) + +pkg_check_modules(test_pkgs REQUIRED dlog glib-2.0 notification) +INCLUDE_DIRECTORIES(${test_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${test_pkgs_LIBRARY_DIRS}) + +ADD_EXECUTABLE(${CRUD_TEST_CLIENT} ${CRUD_TEST_CLIENT_SRCS}) +TARGET_LINK_LIBRARIES(${CRUD_TEST_CLIENT} ${test_pkgs_LIBRARIES} ${CLIENT}) +INSTALL(TARGETS ${CRUD_TEST_CLIENT} DESTINATION ${BIN_INSTALL_DIR}) + +ADD_EXECUTABLE(${CRUD_TEST_SERVER} ${CRUD_TEST_SERVER_SRCS}) +TARGET_LINK_LIBRARIES(${CRUD_TEST_SERVER} ${test_pkgs_LIBRARIES} ${CLIENT}) +INSTALL(TARGETS ${CRUD_TEST_SERVER} DESTINATION ${BIN_INSTALL_DIR}) \ No newline at end of file diff --git a/test/crud-test-client.c b/test/crud-test-client.c new file mode 100644 index 0000000..45f1936 --- /dev/null +++ b/test/crud-test-client.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include +#include "test-log.h" + +#define CRUD_MAX_BUFFER_SIZE (256) + +const char* const door_uri = "/a/door"; + +iotcon_resource_s door_resource = {0}; + +char* _alloc_str_from_glist(GList *list) +{ + int i; + char buf[CRUD_MAX_BUFFER_SIZE] = {0}; + char *ret_str = NULL; + + for (i = 0; i < g_list_length(list); i++) { + char *str = g_list_nth_data(list, i); + strncat(buf, str, strlen(str)); + } + + ret_str = strdup(buf); + return ret_str; +} + +void _get_res_type_fn(const char *res_type, void *user_data) +{ + DBG("resource type : %s", res_type); +} + +void _get_res_interface_fn(const char *res_if, void *user_data) +{ + DBG("resource interface : %s", res_if); +} + +void _print_repr_info(iotcon_repr_h repr) +{ + const char *uri = iotcon_repr_get_uri(repr); + if (uri) + DBG("uri : %s", uri); + + if (0 < iotcon_repr_get_keys_count(repr)) { + DBG("rep :"); + iotcon_repr_print(repr); + } + + iotcon_repr_get_resource_types(repr, _get_res_type_fn, NULL); + iotcon_repr_get_resource_interfaces(repr, _get_res_interface_fn, NULL); + +} + +static void _on_put(const iotcon_header_options header_options, iotcon_repr_h repr, + const int e_code, void *user_data) +{ + FN_CALL; + + if (e_code == IOTCON_ERR_NONE) { + INFO("PUT request was successful"); + + DBG("[%s] parent", iotcon_repr_get_uri(repr)); + _print_repr_info(repr); + + GList *children = iotcon_repr_get_children(repr); + if (children) { + int child_count = iotcon_repr_get_children_count(repr); + int child_index = 0; + for (child_index = 0; child_index < child_count; child_index++) { + DBG("[%s] %dth child", child_index + 1, iotcon_repr_get_uri(repr)); + _print_repr_info(iotcon_repr_get_nth_child(repr, child_index)); + } + } + } + else { + ERR("onPUT Response error(%d)", e_code); + } + /* set the flag for receiving response succesfully */ +} + +void _on_get(const iotcon_header_options header_options, iotcon_repr_h repr, + const int e_code, void *user_data) +{ + FN_CALL; + + if (e_code == IOTCON_ERR_NONE) { + INFO("GET request was successful"); + + DBG("[%s] parent", iotcon_repr_get_uri(repr)); + _print_repr_info(repr); + + GList *children = iotcon_repr_get_children(repr); + if (children) { + int child_count = iotcon_repr_get_children_count(repr); + int child_index = 0; + for (child_index = 0; child_index < child_count; child_index++) { + DBG("[%s] %dth child", child_index + 1, iotcon_repr_get_uri(repr)); + _print_repr_info(iotcon_repr_get_nth_child(repr, child_index)); + } + } + + iotcon_repr_h repr = iotcon_repr_new(); + iotcon_repr_set_bool(repr, "opened", true); + + iotcon_query_parameters query_params = iotcon_new_query_params(); + iotcon_put(door_resource, repr, query_params, _on_put, NULL); + + } + else { + ERR("onGET Response error(%d)", e_code); + } + /* set the flag for receiving response succesfully */ +} + +static void _found_resource(iotcon_resource_s *resource, void *user_data) +{ + char *resource_uri = NULL; + char *resource_host = NULL; + iotcon_resource_types resource_types = NULL; + iotcon_resource_interfaces resource_interfaces = NULL; + + if (resource) { + char *interfaces_str = NULL; + char *res_types_str = NULL; + + INFO("===== resource found ====="); + + /* Get the resource URI */ + resource_uri = iotcon_get_resource_uri(*resource); + if (NULL == resource_uri) { + ERR("uri is NULL"); + return; + } + /* Get the resource host address */ + resource_host = iotcon_get_resource_host(*resource); + DBG("[%s] resource host : %s", resource_uri, resource_host); + + /* Get the resource interfaces */ + resource_interfaces = iotcon_get_resource_interfaces(*resource); + if (resource_interfaces) { + interfaces_str = _alloc_str_from_glist(resource_interfaces); + DBG("[%s] resource interfaces : %s", resource_uri, interfaces_str); + free(interfaces_str); + } + + /* Get the resource types */ + resource_types = iotcon_get_resource_types(*resource); + if (resource_types) { + res_types_str = _alloc_str_from_glist(resource_types); + DBG("[%s] resource types : %s", resource_uri, res_types_str); + free(res_types_str); + } + + if (!strcmp(door_uri, resource_uri)) { + door_resource = iotcon_copy_resource(*resource); + + iotcon_query_parameters query_params = iotcon_new_query_params(); + + /* send GET Request */ + iotcon_get(*resource, query_params, _on_get, NULL); + + iotcon_delete_query_params(query_params); + } + } +} + +int main(int argc, char **argv) +{ + FN_CALL; + GMainLoop *loop; + loop = g_main_loop_new(NULL, FALSE); + + iotcon_initialize("0.0.0.0", 0); + + iotcon_find_resource("", "coap://224.0.1.187/oc/core?rt=core.door", &_found_resource, NULL); + + g_main_loop_run(loop); + g_main_loop_unref(loop); + + return 0; +} diff --git a/test/crud-test-server.c b/test/crud-test-server.c new file mode 100644 index 0000000..e4d78b5 --- /dev/null +++ b/test/crud-test-server.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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 +#include "test-log.h" + +const char* const door_uri = "/a/door"; +const char* const door_type = "core.door"; + +typedef struct _door_resource_s { + bool state; + char *uri; + char *type; + iotcon_repr_h repr; +} door_resource_s; + +static door_resource_s my_door; + +static void _set_door_resource(door_resource_s *door_s) +{ + door_s->state = false; + door_s->type = strdup(door_type); + door_s->uri = strdup(door_uri); +} + +static void _entity_handler_door(const iotcon_request_s *request_s) +{ + FN_CALL; + + RET_IF(NULL == request_s); + + char *requestType = request_s->request_type; + + int requestFlag = request_s->request_handler_flag; + if (requestFlag & IOTCON_REQUEST_FLAG) { + iotcon_response_h pResponse = iotcon_create_response(request_s->request_handle, + request_s->resource_handle); + if (NULL == pResponse) { + ERR("pResponse is NULL"); + return; + } + + if (!strcmp("GET", requestType)) { + INFO("GET request"); + + iotcon_repr_h door_rep = iotcon_repr_new(); + iotcon_repr_set_uri(door_rep, my_door.uri); + iotcon_repr_set_bool(door_rep, "opened", my_door.state); + + iotcon_response_set(pResponse, IOTCON_RESP_REPRESENTATION, door_rep); + iotcon_response_set(pResponse, IOTCON_RESP_ERR_CODE, 200); + iotcon_response_set(pResponse, IOTCON_RESP_RESULT, IOTCON_EH_OK); + iotcon_send_resource_response(pResponse); + + } + else if (!strcmp("PUT", requestType)) { + INFO("PUT request"); + + iotcon_repr_h repr = iotcon_request_get_representation(request_s); + my_door.state = iotcon_repr_get_bool(repr, "opened"); + iotcon_repr_h door_rep = iotcon_repr_new(); + iotcon_repr_set_uri(door_rep, my_door.uri); + iotcon_repr_set_bool(door_rep, "opened", my_door.state); + + iotcon_response_set(pResponse, IOTCON_RESP_REPRESENTATION, door_rep); + iotcon_response_set(pResponse, IOTCON_RESP_ERR_CODE, 200); + iotcon_response_set(pResponse, IOTCON_RESP_RESULT, IOTCON_EH_OK); + iotcon_send_resource_response(pResponse); + + } + } +} + +int main(int argc, char **argv) +{ + FN_CALL; + GMainLoop *loop; + int result = 0; + + loop = g_main_loop_new(NULL, FALSE); + + /* initialize address and port */ + iotcon_initialize("0.0.0.0", 0); + + _set_door_resource(&my_door); + + /* register door resource */ + iotcon_resource_h door_handle = iotcon_register_resource(door_uri, + door_type, IOTCON_INTERFACE_DEFAULT, + (IOTCON_DISCOVERABLE | IOTCON_OBSERVABLE), _entity_handler_door); + if (0 != result) { + ERR("register %s resource Fail(%d)", "/a/light", result); + return result; + } + + g_main_loop_run(loop); + g_main_loop_unref(loop); + + iotcon_unregister_resource(door_handle); + + return 0; +} diff --git a/test/test-log.h b/test/test-log.h new file mode 100644 index 0000000..26fa292 --- /dev/null +++ b/test/test-log.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd 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. + */ +#ifndef __IOT_CONNECTIVITY_MANAGER_TEST_LOG_H__ +#define __IOT_CONNECTIVITY_MANAGER_TEST_LOG_H__ + +#define ICTEST_LOGRED "\033[0;31m" +#define ICTEST_LOGGREEN "\033[0;32m" +#define ICTEST_LOGBROWN "\033[0;33m" +#define ICTEST_LOGBLUE "\033[0;34m" +#define ICTEST_LOGEND "\033[0;m" + +#undef _DBG +#undef _INFO +#undef _WARN +#undef _ERR + +#undef DBG +#undef INFO +#undef WARN +#undef ERR + +#define TIZEN_DEBUG_ENABLE +#define LOG_TAG "ICTEST" +#include + +#define _DBG(fmt, arg...) SLOGD(fmt, ##arg) +#define _INFO(fmt, arg...) SLOGI(fmt, ##arg) +#define _WARN(fmt, arg...) SLOGW(fmt, ##arg) +#define _ERR(fmt, arg...) SLOGE(fmt, ##arg) + +#if 0 +#define _DBG(fmt, arg...) \ + printf("[IoTConTest]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _INFO(fmt, arg...) \ + printf("[IoTConTest]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _WARN(fmt, arg...) \ + printf("[IoTConTest]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#define _ERR(fmt, arg...) \ + printf("[IoTConTest]%s(%d):" fmt "\n", __FUNCTION__, __LINE__, ##arg) +#endif + +#define ICTEST_DEBUGGING + +#ifdef ICTEST_DEBUGGING + +#define FN_CALL _INFO(">>>>>>>> called") +#define FN_END _INFO("<<<<<<<< ended") +#define DBG(fmt, arg...) _DBG(fmt, ##arg) +#define WARN(fmt, arg...) _WARN(ICTEST_LOGBROWN fmt ICTEST_LOGEND, ##arg) +#define ERR(fmt, arg...) _ERR(ICTEST_LOGRED fmt ICTEST_LOGEND, ##arg) +#define INFO(fmt, arg...) _INFO(ICTEST_LOGBLUE fmt ICTEST_LOGEND, ##arg) +#define SECURE_DBG(fmt, arg...) SECURE_SLOGD(fmt, ##arg) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) +#define ABORT() abort() + +#else /* ICTEST_DEBUGGING */ + +#define FN_CALL +#define FN_END +#define DBG(fmt, arg...) +#define WARN(fmt, arg...) +#define ERR(fmt, arg...) _ERR(fmt, ##arg) +#define INFO(fmt, arg...) +#define SECURE_DBG(fmt, arg...) +#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) +#define ABORT() + +#endif /* ICTEST_DEBUGGING */ + +#define RET_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + return; \ + }\ + } while(0) + +#define RETV_IF(expr, val) \ + do {\ + if (expr) { \ + ERR("(%s)", #expr); \ + return (val); \ + } \ + } while(0) + +#define RETM_IF(expr, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + }\ + } while(0) + +#define RETVM_IF(expr, val, fmt, arg...) \ + do {\ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ + } while(0) + +#define ERR_IF(expr) \ + do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + } \ + } while (0) + +#define WARN_IF(expr) \ + do { \ + if (expr) { \ + WARN("(%s)", #expr); \ + } \ + } while (0) + +#endif //__IOT_CONNECTIVITY_MANAGER_TEST_LOG_H__ -- 2.7.4