--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(iot-broker_main CXX)
+
+# Setup For pkgconfig File
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "${PREFIX}/bin")
+SET(LIBDIR "${PREFIX}/lib")
+SET(INCLUDEDIR "${PREFIX}/include")
+SET(VERSION 1.0)
+
+SET(OCLIB "oc")
+SET(OCLOGGER "oc_logger")
+SET(OCLOGGER_CORE "oc_logger_core")
+SET(CA "connectivity_abstraction")
+SET(OCTBSTACK "octbstack")
+
+# Common Options
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -omit-frame-pointer -std=gnu++0x")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-section -Wl,--print-gc-section")
+MESSAGE("FLAGS: ${CMAKE_CXX_FLAGS}")
+MESSAGE("FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
+
+add_definitions(-DUSE_DLOG_LOG)
+
+# Internal Debugging Options
+#add_definitions(-Wall -g -D_DEBUG)
+
+# Sub-directory
+add_subdirectory(src)
+
+# Tests
+add_subdirectory(test)
+
+FILE(GLOB RRS_HEADER include/*.h)
+INSTALL(FILES ${RRS_HEADER} DESTINATION ${INCLUDEDIR})
--- /dev/null
+Copyright (c) 2000 - 2014 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.
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 __RRS_DOC_H__
+#define __RRS_DOC_H__
+
+/**
+ * @ingroup CAPI_CONVERGENCE_FRAMEWORK
+ * @defgroup CAPI_RRS_MODULE Remote Resource Service
+ *
+ * @brief The Remote Resource Service (RRS) provides Application and Platform
+ * Developer with APIs, enabling access to nearby Tizen resources.
+ *
+ * @section CAPI_RRS_MODULE_HEADER Required Header
+ * \#include <rrs.h>
+ *
+ * @section CAPI_RRS_MODULE_OVERVIEW Overview
+ *
+ * The Remote Resource Service is used to connect to resources on remote devices.
+ *
+ * @section CAPI_RRS_MODULE_FEATURE Features
+ * Tizen Convergence - Remote Resource Service enables applications on a device
+ * to connect with the remote resources on any other Tizen device over IOTCON
+ * connectivity. New resources are introduced by adding new resource schema files.
+ * Schema files are parsed to instantiate identical resource representations on
+ * both client and server. Data communication between resource client and server
+ * happens by exchanging resource representation state data.
+ *
+ * @subsection CAPI_RRS_MODULE_API Resources
+ * Applications which use the Remote Resource Service API can discover, control,
+ * monitor and receive data events from remote resources. The API provides handles
+ * for connecting with multiple remote resources on different devices.
+ *
+ * @subsection CAPI_RRS_MODULE_SERVER RRS Server
+ * These Tizen resources created on a device are connected to the different mobile
+ * services through a service broker. The RRS server provides management for the
+ * various created resources and the service brokers.
+ *
+ *
+ * @if WEARABLE
+ * @section CAPI_RRS_MODULE_FEATURE Related Features
+ * This API is related with the following features:
+ * - http://tizen.org/feature/network.internet
+ * - http://tizen.org/feature/network.bluetooth
+ * - http://tizen.org/feature/network.wifi
+ * - http://tizen.org/feature/network.wifi.direct
+ * - http://tizen.org/feature/sensor.accelerometer
+ * - http://tizen.org/feature/sensor.accelerometer.wakeup
+ * - http://tizen.org/feature/sensor.activity_recognition
+ * - http://tizen.org/feature/sensor.barometer
+ * - http://tizen.org/feature/sensor.barometer.wakeup
+ * - http://tizen.org/feature/sensor.gesture_recognition
+ * - http://tizen.org/feature/sensor.gravity
+ * - http://tizen.org/feature/sensor.gyroscope
+ * - http://tizen.org/feature/sensor.gyroscope.wakeup
+ * - http://tizen.org/feature/sensor.heart_rate_monitor
+ * - http://tizen.org/feature/sensor.humidity
+ * - http://tizen.org/feature/sensor.linear_acceleration
+ * - http://tizen.org/feature/sensor.magnetometer
+ * - http://tizen.org/feature/sensor.magnetometer.wakeup
+ * - http://tizen.org/feature/sensor.pedometer
+ * - http://tizen.org/feature/sensor.photometer
+ * - http://tizen.org/feature/sensor.photometer.wakeup
+ * - http://tizen.org/feature/sensor.proximity
+ * - http://tizen.org/feature/sensor.proximity.wakeup
+ * - http://tizen.org/feature/sensor.rotation_vector
+ * - http://tizen.org/feature/sensor.temperature
+ * - http://tizen.org/feature/sensor.tiltmeter
+ * - http://tizen.org/feature/sensor.tiltmeter.wakeup
+ * - http://tizen.org/feature/sensor.ultraviolet
+ * - http://tizen.org/feature/sensor.wrist_up
+ *
+ * It is recommended to design feature related codes in your application for
+ * reliability.\n
+ *
+ * You can check if a device supports the related features for this API by using
+ * @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of
+ * your application.\n
+ *
+ * To ensure your application is only running on the device with specific
+ * features, please define the features in your manifest file using the manifest
+ * editor in the SDK.\n
+ *
+ * More details on featuring your application can be found from
+ * <a href="https://developer.tizen.org/development/tools/native-tools/manifest-text-editor#feature"><b>Feature Element</b>.</a>
+ * @endif
+ */
+
+#endif /*__RRS_DOC_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_H_
+#define _RRS_H_
+
+#include <tizen_type.h>
+#include "rrs_main.h"
+#include "rrs_resource.h"
+#include "rrs_error.h"
+#include "rrs_event_data.h"
+#include "rrs_control_data.h"
+
+/*
+ * CAPI_RRS_MODULE
+ *
+ * This file includes all the modules
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RRS_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_CONTROL_DATA_H_
+#define _RRS_CONTROL_DATA_H_
+
+#include "rrs_main.h"
+
+/**
+ * @ingroup CAPI_RRS_CLIENT
+ * @defgroup CAPI_RRS_CONTROL_DATA_MODULE Control data
+ *
+ * @file rrs_control_data.h
+ * @brief This file contains the RRS Control Data API
+ * @addtogroup CAPI_RRS_CONTROL_DATA_MODULE
+ * @{
+ * @brief This provides APIs related to control data handling
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Handle of control data.
+ * @details The handle to generate control data for controlling remote resource.
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_control_data_destroy().
+ *
+ * @see rrs_control_data_destroy()
+ */
+typedef void * rrs_control_data_h;
+
+
+/**
+ * @brief Creates an instance of structured control data.
+ * @details This function creates an instance of structured control data and issues a new handle for it.
+ * @since_tizen 3.0
+ *
+ * @remarks @a data handle must be released using rrs_control_data_destroy().
+ *
+ * @param[in] type Resource type
+ * @param[out] data The handle of newly created data instance
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_INVALID_TYPE Invalid type
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see rrs_control_data_destroy()
+ * @see rrs_control_data_clone()
+ * @see rrs_resource_e
+ */
+int rrs_control_data_create(const rrs_resource_e type,
+ rrs_control_data_h *data);
+
+
+/**
+ * @brief Destroys the data handle.
+ * @details This function releases the data handle.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle to destroy
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_control_data_clone()
+ */
+int rrs_control_data_destroy(rrs_control_data_h data);
+
+
+/**
+ * @brief Clones the data handle.
+ * @details This function clones the structured data handle @a origin.
+ * @since_tizen 3.0
+ *
+ * @remarks @a cloned must be released using rrs_control_data_destroy().
+ *
+ * @param[in] origin The original data handle
+ * @param[out] cloned A cloned data handle
+ * @return 0 on success, otherwise a negative error data
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_control_data_destroy()
+ */
+int rrs_control_data_clone(const rrs_control_data_h origin,
+ rrs_control_data_h *cloned);
+
+
+/**
+ * @brief Sets boolean field value.
+ * @details This function sets the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_send_control()
+ */
+int rrs_control_data_set_bool(rrs_control_data_h data,
+ const char *name,
+ const bool value);
+
+
+/**
+ * @brief Sets integer field value.
+ * @details This function sets the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_send_control()
+ */
+int rrs_control_data_set_int(rrs_control_data_h data,
+ const char *name,
+ const int value);
+
+
+/**
+ * @brief Sets floating point field value.
+ * @details This function sets the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_send_control()
+ */
+int rrs_control_data_set_double(rrs_control_data_h data,
+ const char *name,
+ const double value);
+
+
+/**
+ * @brief Sets string field value.
+ * @details This function sets the string field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_send_control()
+ */
+int rrs_control_data_set_string(rrs_control_data_h data,
+ const char *name,
+ const char *value);
+
+
+/**
+ * @brief Gets boolean field value.
+ * @details This function gets the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to bool in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_monitor_control()
+ */
+int rrs_control_data_get_bool(const rrs_control_data_h data,
+ const char *name,
+ bool *value);
+
+
+/**
+ * @brief Gets integer field value.
+ * @details This function gets the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to int in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_monitor_control()
+ */
+int rrs_control_data_get_int(const rrs_control_data_h data,
+ const char *name,
+ int *value);
+
+
+/**
+ * @brief Gets floating point field value.
+ * @details This function gets the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to double in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_monitor_control()
+ */
+int rrs_control_data_get_double(const rrs_control_data_h data,
+ const char *name,
+ double *value);
+
+
+/**
+ * @brief Gets string field value.
+ * @details This function gets the sting field value.
+ * @since_tizen 3.0
+ *
+ * @remarks Release the value @a value using free().
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to char * in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_control_data_create() functions.
+ *
+ * @see rrs_control_data_create()
+ * @see rrs_resource_monitor_control()
+ */
+int rrs_control_data_get_string(const rrs_control_data_h data,
+ const char *name,
+ char **value);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* _RRS_CONTROL_DATA_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_ERROR_H_
+#define _RRS_ERROR_H_
+
+#include <tizen_type.h>
+#include <tizen_error.h>
+
+/**
+ * @ingroup CAPI_RRS_MODULE
+ * @defgroup CAPI_RRS_ERROR_MODULE Errors
+ *
+ * @file rrs_error.h
+ * @brief This file contains the list of RRS errors
+ *
+ * @addtogroup CAPI_RRS_ERROR_MODULE
+ * @{
+ * @brief This provides a list of RRS API errors
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Base RRS error code (to be added to tizen header files)
+ * @since_tizen 3.0
+ */
+#define TIZEN_ERROR_RRS_SERVICE 1000
+
+/**
+ * @brief Enumerations of RRS error codes
+ * @since_tizen 3.0
+ */
+typedef enum {
+ RRS_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ RRS_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid Parameter */
+ RRS_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid Operation */
+ RRS_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out Of Memory */
+ RRS_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission Denied */
+ RRS_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not Supported */
+ RRS_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No Data Error */
+ RRS_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Unknown Error */
+ RRS_ERROR_KEY_NOT_AVAILABLE = TIZEN_ERROR_KEY_NOT_AVAILABLE, /**< Key Not Available */
+ RRS_ERROR_SERVICE_NOT_AVAILABLE = TIZEN_ERROR_RRS_SERVICE | 0x01, /**< Service Not Available */
+ RRS_ERROR_NOT_FOUND = TIZEN_ERROR_RRS_SERVICE | 0x02, /**< Not Found Error */
+ RRS_ERROR_NETWORK_UNREACHABLE = TIZEN_ERROR_RRS_SERVICE | 0x03, /**< Network Unreachable */
+ RRS_ERROR_TIMEOUT = TIZEN_ERROR_RRS_SERVICE | 0x04, /**< Timeout */
+ RRS_ERROR_INVALID_TYPE = TIZEN_ERROR_RRS_SERVICE | 0x05 /**< Invalid Type */
+} rrs_error_e;
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+
+#endif /* _RRS_ERROR_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_EVENT_DATA_H_
+#define _RRS_EVENT_DATA_H_
+
+#include "rrs_main.h"
+
+/**
+ * @ingroup CAPI_RRS_CLIENT
+ * @defgroup CAPI_RRS_EVENT_DATA_MODULE Event data
+ *
+ * @file rrs_event_data.h
+ * @brief This file contains the RRS Event Data API
+ * @addtogroup CAPI_RRS_EVENT_DATA_MODULE
+ * @{
+ * @brief This provides APIs related to event data handling
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Handle of event data.
+ * @details The handle to generate event data for sent events from remote resource.
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_event_data_destroy().
+ *
+ * @see rrs_event_data_destroy()
+ */
+typedef void * rrs_event_data_h;
+
+
+/**
+ * @brief Creates an instance of structured event data.
+ * @details This function creates an instance of structured event data and issues a new handle for it.
+ * @since_tizen 3.0
+ *
+ * @remarks @a data handle must be released using rrs_event_data_destroy().
+ *
+ * @param[in] type Resource_type
+ * @param[out] data The handle of newly created data instance
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_INVALID_TYPE Invalid type
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see rrs_event_data_destroy()
+ * @see rrs_event_data_clone()
+ * @see rrs_resource_e
+ */
+int rrs_event_data_create(const rrs_resource_e type,
+ rrs_event_data_h *data);
+
+
+/**
+ * @brief Destroys the data handle.
+ * @details This function releases the data handle.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle to destroy
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_event_data_clone()
+ */
+int rrs_event_data_destroy(rrs_event_data_h data);
+
+
+/**
+ * @brief Clones the data handle.
+ * @details This function clones the structured data handle @a origin.
+ * @since_tizen 3.0
+ *
+ * @remarks @a cloned must be released using rrs_event_data_destroy().
+ *
+ * @param[in] origin The original data handle
+ * @param[out] cloned A cloned data handle
+ * @return 0 on success, otherwise a negative error data
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_event_data_destroy()
+ */
+int rrs_event_data_clone(const rrs_event_data_h origin,
+ rrs_event_data_h *cloned);
+
+
+/**
+ * @brief Sets boolean field value.
+ * @details This function sets the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ */
+int rrs_event_data_set_bool(rrs_event_data_h data,
+ const char *name,
+ const bool value);
+
+
+/**
+ * @brief Sets integer field value.
+ * @details This function sets the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ */
+int rrs_event_data_set_int(rrs_event_data_h data,
+ const char *name,
+ const int value);
+
+
+/**
+ * @brief Sets floating point field value.
+ * @details This function sets the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ */
+int rrs_event_data_set_double(rrs_event_data_h data,
+ const char *name,
+ const double value);
+
+
+/**
+ * @brief Sets string field value.
+ * @details This function sets the string field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] value The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ */
+int rrs_event_data_set_string(rrs_event_data_h data,
+ const char *name,
+ const char *value);
+
+
+/**
+ * @brief Gets boolean field value.
+ * @details This function gets the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to bool in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_resource_receive_event()
+ */
+int rrs_event_data_get_bool(const rrs_event_data_h data,
+ const char *name,
+ bool *value);
+
+
+/**
+ * @brief Gets integer field value.
+ * @details This function gets the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to int in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_resource_receive_event()
+ */
+int rrs_event_data_get_int(const rrs_event_data_h data,
+ const char *name,
+ int *value);
+
+
+/**
+ * @brief Gets floating point field value.
+ * @details This function gets the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to double in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_resource_receive_event()
+ */
+int rrs_event_data_get_double(const rrs_event_data_h data,
+ const char *name,
+ double *value);
+
+
+/**
+ * @brief Gets string field value.
+ * @details This function gets the sting field value.
+ * @since_tizen 3.0
+ *
+ * @remarks Release the value @a value using free().
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[out] value The pointer to char * in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre @a data handle is created with rrs_event_data_create() functions.
+ *
+ * @see rrs_event_data_create()
+ * @see rrs_resource_receive_event()
+ */
+int rrs_event_data_get_string(const rrs_event_data_h data,
+ const char *name,
+ char **value);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* _RRS_EVENT_DATA_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_MAIN_H_
+#define _RRS_MAIN_H_
+
+#include <tizen_type.h>
+#include <iotcon.h>
+#include <common.h>
+#include "rrs_error.h"
+
+/**
+ * @ingroup CAPI_RRS_MODULE
+ * @defgroup CAPI_RRS_MAIN_MODULE General
+ *
+ * @file rrs_main.h
+ * @brief This file contains functions related to RRS API.
+ * @addtogroup CAPI_RRS_MAIN_MODULE
+ * @{
+ * @brief This provides APIs related to RRS
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Handle of the RRS.
+ * @details The RRS handle can be obtained via call of rrs_create().
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_destroy().
+ *
+ * @par Example
+ * @code
+ * #include <rrs.h>
+ * // Usage of RRS in the app
+ * int main(void) {
+ * // Creating RRS
+ * rrs_h rrs = 0;
+ * rrs_create(&rrs);
+ *
+ * // Do something with RRS
+ * // Destroy schema and data when no more needed
+ * rrs_destroy(rrs);
+ *
+ * return 0;
+ * }
+ * @endcode
+ *
+ * @see rrs_create()
+ * @see rrs_destroy()
+ */
+typedef int rrs_h;
+
+
+/**
+ * @brief Enumerations of resources, supported by RRS
+ * @since_tizen 3.0
+ */
+typedef enum _rrs_resource_e {
+ RRS_RESOURCE_NONE = 0, /**< Invalid sensor */
+ RRS_RESOURCE_DISCOVERY = 1, /**< Discovery resource */
+ RRS_RESOURCE_ACCELEROMETER, /**< Accelerometer sensor */
+ RRS_RESOURCE_PROXIMITY, /**< Proximity sensor */
+ RRS_RESOURCE_AUTO_ROTATION, /**< Auto rotation sensor */
+ RRS_RESOURCE_HRM, /**< Bio HRM sensor */
+ RRS_RESOURCE_HRM_LED_GREEN, /**< Bio LED green sensor */
+ RRS_RESOURCE_HRM_LED_RED, /**< Bio LED RED sensor */
+ RRS_RESOURCE_HRM_LED_IR, /**< Bio LED IR sensor */
+ RRS_RESOURCE_GYROSCOPE, /**< Gyroscope sensor */
+ RRS_RESOURCE_MAGNETOMETER, /**< Geomagnetic sensor */
+ RRS_RESOURCE_LIGHT, /**< Light sensor */
+ RRS_RESOURCE_PRESSURE, /**< Pressure sensor */
+ RRS_RESOURCE_TEMPERATURE, /**< Temperature sensor */
+ RRS_RESOURCE_HUMIDITY, /**< Humidity sensor */
+ RRS_RESOURCE_UV, /**< Ultraviolet sensor */
+ RRS_RESOURCE_ORIENTATION, /**< Orientation sensor */
+ RRS_RESOURCE_GRAVITY, /**< Gravity sensor */
+ RRS_RESOURCE_LINEAR_ACCELERATION,/**< Linear acceleration sensor */
+ RRS_RESOURCE_ROTATION_VECTOR, /**< Rotation vector sensor */
+ RRS_RESOURCE_GYROSCOPE_ROTATION_VECTOR, /**< Gyroscope Rotation Vector sensor */
+ RRS_RESOURCE_GEOMAGNETIC_ROTATION_VECTOR, /**< Geomagnetic Rotation Vector sensor */
+ RRS_RESOURCE_UNCALIBRATED_GYROSCOPE, /**< Uncalibrated gyroscope sensor */
+ RRS_RESOURCE_UNCALIBRATED_MAGNETOMETER, /**< Uncalibrated geomagnetic sensor */
+ RRS_RESOURCE_ALL
+} rrs_resource_e;
+
+/**
+ * @brief Creates an RRS and assigns it with a handle.
+ * @details This function creates an RRS and issues a new handle for it.
+ * \n The handle is used to discover resources.
+ * @since_tizen 3.0
+ *
+ * @remarks @a rrs handle must be released using rrs_destroy().
+ *
+ * @param[out] rrs A handle of the newly created RRS
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_destroy()
+ */
+int rrs_create(rrs_h *rrs);
+
+
+/**
+ * @brief Destroys the RRS handle.
+ * @details This function releases the RRS handle.
+ * @since_tizen 3.0
+ *
+ * @param[in] rrs The RRS handle to destroy
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre Call rrs_create() to create RRS and get its handle.
+ *
+ * @see rrs_create()
+ */
+int rrs_destroy(const rrs_h rrs);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+
+#endif /* _RRS_MAIN_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_RESOURCE_H_
+#define _RRS_RESOURCE_H_
+
+#include "rrs_main.h"
+#include "rrs_event_data.h"
+#include "rrs_control_data.h"
+
+/**
+ * @ingroup CAPI_RRS_CLIENT
+ * @defgroup CAPI_RRS_RESOURCE_MODULE Resource
+ *
+ * @file rrs_resource.h
+ * @brief This file contains the RRS Resource Client API
+ * @addtogroup CAPI_RRS_RESOURCE_MODULE
+ * @{
+ * @brief This provides APIs related to client-side usage of resource
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Handle of the virtual resource.
+ * @details The resource handle can be obtained via call of
+ * rrs_resource_find().
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_resource_destroy().
+ *
+ *
+ * @see rrs_create()
+ * @see rrs_destroy()
+ */
+typedef int rrs_resource_h;
+
+
+/**
+ * @brief Callback for each remote resource found.
+ * @details This callback is invoked when remote resources are found. The
+ * resource handle obtained is valid outside of this callback. The handle
+ * may be released with rrs_resource_destroy().
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of remote resource search
+ * @param[in] resource The handle of remote resource
+ * @param[in] user_data The user data passed from rrs_resource_find()
+ *
+ * @pre rrs_resource_find() will invoke this callback.
+ *
+ * @see rrs_resource_find()
+ * @see #rrs_resource_h
+ */
+typedef bool(*rrs_resource_found_cb) (rrs_error_e result,
+ rrs_resource_h resource,
+ void *user_data);
+
+
+/**
+ * @brief Callback that iterates over list of found remote resources.
+ * @details This callback is invoked when remote found resources. The
+ * resource handle obtained is valid outside of this callback. The handle
+ * may be released with rrs_resource_destroy().
+ * @since_tizen 3.0
+ *
+ * @remarks @a resource must not be released by the user.
+ *
+ * @param[in] resource The handle of remote resource
+ * @param[in] user_data The user data passed from rrs_foreach_resource()
+ * @return @c true to continue with the next iteration of the loop, \n @c
+ * false to break out of the loop
+ *
+ * @pre rrs_foreach_resource() will invoke this callback.
+ *
+ * @see rrs_foreach_resource()
+ * @see #rrs_resource_h
+ */
+typedef bool(*rrs_foreach_resource_cb) (rrs_resource_h resource,
+ void *user_data);
+
+
+/**
+ * @brief Callback triggered when client resource information is removed from server resource observers.
+ * @details This callback is triggered when server responds to removal of remote resource information.
+ * The resource handle obtained is not valid outside of this callback.
+ * @since_tizen 3.0
+ *
+ * @remarks @a resource must not be released by the user.
+ *
+ * @param[in] result The result of resource destroy request
+ * @param[in] resource The handle of remote resource
+ * @param[in] user_data The user data passed from rrs_resource_destroy()
+ *
+ * @pre rrs_resource_destroy() will invoke this callback.
+ *
+ * @see rrs_resource_destroy()
+ * @see #rrs_resource_h
+ */
+typedef void(*rrs_resource_destroy_cb) (rrs_error_e result,
+ rrs_resource_h resource,
+ void *user_data);
+
+
+/**
+ * @brief Called to notify remote resource event data is received.
+ * @details This callback is invoked when remote resource event is received in the client.
+ * The event data handle obtained is not valid outside of this callback and can be cloned
+ * using rrs_event_data_clone().
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of request
+ * @param[in] event The handle of received resource event data
+ * @param[in] user_data The user data pointer passed in rrs_resource_subscribe_event()
+ *
+ * @pre RRS invokes this callback when remote resource is changed
+ * on the server.
+ *
+ * @see rrs_resource_subscribe_event()
+ * @see rrs_resource_unsubscribe_event()
+ */
+typedef void(*rrs_resource_observe_cb) (rrs_error_e result,
+ rrs_event_data_h event,
+ void *user_data);
+
+
+/**
+ * @brief Called to notify response from remote resource for send control.
+ * @details This callback is invoked when remote resource responds to send control command.
+ * The resource handle obtained is valid outside of this callback. The handle may be
+ * released with rrs_resource_destroy().
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of request
+ * @param[in] resource The handle of remote resource
+ * @param[in] user_data The user data pointer passed in rrs_resource_send_control()
+ *
+ * @pre RRS invokes this callback when remote resource responds to send control.
+ *
+ * @see rrs_resource_send_control()
+ */
+typedef void(*rrs_resource_send_control_cb) (rrs_error_e result,
+ rrs_resource_h resource,
+ void *user_data);
+
+
+/**
+ * @brief Called to notify control information received from remote resource.
+ * @details This callback is invoked when remote resource responds to monitor control command.
+ * The resource handle obtained is valid outside of this callback. The resource handle may be
+ * released with rrs_resource_destroy(). The control data handle obtained is not valid outside of
+ * this callback and can be cloned using rrs_control_data_clone(). The control data handle can be
+ * destroyed using rrs_control_data_destroy().
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of request
+ * @param[in] resource The handle of remote resource
+ * @param[in] control The handle of control information received
+ * @param[in] user_data The user data pointer passed in rrs_resource_send_control()
+ *
+ * @pre RRS invokes this callback when remote resource responds to rrs_resource_monitor_control().
+ *
+ * @see rrs_resource_monitor_control()
+ */
+typedef void(*rrs_resource_monitor_control_cb) (rrs_error_e result,
+ rrs_resource_h resource,
+ rrs_control_data_h control,
+ void *user_data);
+
+
+/**
+ * @brief Called to notify event data information received from remote resource.
+ * @details This callback is invoked when remote resource resource responds to receive event command.
+ * The resource handle obtained is valid outside of this callback. The resource handle may be
+ * released with rrs_resource_destroy(). The event data handle obtained is not valid outside of
+ * this callback and can be cloned using rrs_event_data_clone(). The event data handle can be
+ * destroyed using rrs_event_data_destroy().
+ * @since_tizen 3.0
+ *
+ * @param[in] result The result of request
+ * @param[in] resource The handle of remote resource
+ * @param[in] event The handle of event data received
+ * @param[in] user_data The user data pointer passed in rrs_resource_receive_event()
+ *
+ * @pre RRS invokes this callback when remote resource responds to rrs_resource_receive_event().
+ *
+ * @see rrs_resource_receive_event()
+ */
+typedef void(*rrs_resource_receive_event_cb) (rrs_error_e result,
+ rrs_resource_h resource,
+ rrs_event_data_h event,
+ void *user_data);
+
+
+/**
+ * @brief Find nearby resources by id.
+ * @details This function finds all nearby resources of a specified type.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] rrs The RRS handle of the group
+ * @param[in] type The specified resource type
+ * @param[in] callback The callback which will retrieve the remote resource handles
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return RRS_ERROR_NONE on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_TYPE Invalid Type
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_NOT_FOUND Not Found
+ *
+ * @see rrs_resource_found_cb()
+ * @see rrs_resource_destroy()
+ * @see rrs_resoruce_e
+ */
+int rrs_resource_find(const rrs_h rrs,
+ const rrs_resource_e type,
+ rrs_resource_found_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Iterate over found resource handles.
+ * @details This function provides each found resource handle, through callback.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] type The specified resource type
+ * @param[in] callback The callback which will retrieve the remote resource handles
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_TYPE Invalid Type
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see rrs_foreach_resource_cb()
+ * @see rrs_resource_destroy()
+ */
+int rrs_foreach_resource(const rrs_h rrs,
+ const rrs_resource_e type,
+ rrs_foreach_resource_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Destroys the resource client handle.
+ * @details This function releases the resource client handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle to destroy
+ * @param[in] callback The callback triggered once client information is removed in remote resource.
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_find()
+ * @see rrs_resource_destroy_cb()
+ */
+int rrs_resource_destroy(const rrs_resource_h resource,
+ rrs_resource_destroy_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Gets the count of found resource handles stored in client.
+ * @details This function provides the count of found remote resource handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] type The specified resource type
+ * @param[out] count The number of resources found
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_get_count()
+ */
+int rrs_resource_get_count(const rrs_h rrs,
+ const rrs_resource_e type,
+ int *count);
+
+
+/**
+ * @brief Get resource type based on resource handle.
+ * @details This function gets the remote resource type based on remote resource handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[out] type Resource type
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_find()
+ */
+int rrs_resource_get_type(const rrs_resource_h resource,
+ rrs_resource_e *type);
+
+
+/**
+ * @brief Get device id of the resource based on resource handle.
+ * @details This function gets the remote device id based on remote resource handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[out] device_id Device ID
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_find()
+ */
+int rrs_resource_get_device_id(const rrs_resource_h resource,
+ char **device_id);
+
+
+/**
+ * @brief Get device name of the resource based on resource handle.
+ * @details This function gets the remote device name based on remote resource handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[out] device_name Device Name
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_find()
+ */
+int rrs_resource_get_device_name(const rrs_resource_h resource,
+ char **device_name);
+
+
+/**
+ * @brief Get uri path of the resource based on resource handle.
+ * @details This function gets the remote uri path of resource based on remote resource handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[out] uri_path URI path of the resource
+ * @remark Please free memory
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @pre Call rrs_resource_find() to find nearby remote resources.
+ *
+ * @see rrs_resource_find()
+ */
+int rrs_resource_get_uri_path(const rrs_resource_h resource,
+ char **uri_path);
+
+
+/**
+ * @brief Send remote resource control data.
+ * @details This function sends the control data to remote resource.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[in] control The control data to send to the remote resource
+ * @param[in] callback The function triggered after remote resource responds to send control.
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see rrs_resource_monitor_control()
+ * @see rrs_resource_send_control_cb()
+ */
+int rrs_resource_send_control(const rrs_resource_h resource,
+ const rrs_control_data_h control,
+ rrs_resource_send_control_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Receive remote resource control data state.
+ * @details This function receives the control data from remote resource.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @param[in] callback The function triggered after remote resource responds with control data state.
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see rrs_resource_send_control()
+ * @see rrs_resource_monitor_control_cb()
+ */
+int rrs_resource_monitor_control(const rrs_resource_h resource,
+ rrs_resource_monitor_control_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Receive remote resource event data.
+ * @details This function receives the event data from remote resource.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource handle
+ * @param[in] callback The function is triggered after remote resource responds with event data.
+ * @param[in] user_data The user data pointer to be passed to callback functions
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @see rrs_resource_unsubscribe_event()
+ * @see rrs_resource_monitor_control_cb()
+ */
+int rrs_resource_receive_event(const rrs_resource_h resource,
+ rrs_resource_receive_event_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Subscribe for events from remote resource
+ * @details This function subscribes for remote resource events.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource handle
+ * @param[in] callback The callback which will be invoked when remote resource sends event data.
+ * @param[in] user_data The user data pointer to be passed to the callback function
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre call rrs_resource_find() to find remote resource handles.
+ *
+ * @see rrs_resource_unset_observe_cb()
+ * @see rrs_resource_observe_cb()
+ */
+int rrs_resource_subscribe_event(const rrs_resource_h resource,
+ rrs_resource_observe_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Un-subscribe for events from remote resource
+ * @details This function un-subscribes for remote resource events.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] resource The resource client handle
+ * @return 0 on success, otherwise a non-negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ * @retval #RRS_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre call rrs_resource_find() to find remote resource handles.
+ *
+ * @see rrs_resource_subscribe_event()
+ */
+int rrs_resource_unsubscribe_event(const rrs_resource_h resource);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* _RRS_RESOURCE_H_ */
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+[Unit]
+Description=RRS service
+After=dlog-main.service dbus.service
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rrs-server
+Restart=always
+
+[Install]
+WantedBy=default.target
--- /dev/null
+Name: rrs-serverd
+Summary: Remote Resource Service
+Version: 0.0.1
+Release: 0
+Group: Network & Connectivity/Service
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Source1: remote-resource-service.service
+Source2: %{name}.manifest
+Source3: capi-rrs-client.manifest
+
+BuildRequires: cmake
+BuildRequires: boost-devel
+BuildRequires: pkgconfig(iotcon)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(json-glib-1.0)
+BuildRequires: pkgconfig(sensor)
+BuildRequires: pkgconfig(cynara-creds-gdbus)
+BuildRequires: pkgconfig(cynara-client)
+BuildRequires: pkgconfig(cynara-session)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(libtzplatform-config)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%define build_test_suite ON
+
+%description
+remote resource service
+
+%package rrs-serverd
+Summary: Remote Resource Service
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description rrs-serverd
+remote resource service
+
+%package -n capi-rrs-client
+Summary: Client library
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description -n capi-rrs-client
+remote resource service client
+
+%package -n capi-rrs-client-devel
+Summary: Client library devel
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description -n capi-rrs-client-devel
+remote resource service client devel
+
+%if %{build_test_suite} == "ON"
+%package -n rrs-test
+Summary: Test executable
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description -n rrs-test
+Sensor functional testing
+
+%endif
+
+%prep
+%setup -q
+
+cp %{SOURCE2} ./
+cp %{SOURCE3} ./
+
+
+%build
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+
+export CFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default"
+export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default -Wnon-virtual-dtor -Wno-c++0x-compat -std=c++0x"
+
+export CFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
+export CXXFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
+
+export CFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow -fno-common"
+export CXXFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
+
+export CFLAGS+=" -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS+=" -DTIZEN_ENGINEER_MODE"
+export FFLAGS+=" -DTIZEN_ENGINEER_MODE"
+
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -DLIBDIR=%{_libdir}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system
+mkdir -p %{buildroot}%{_libdir}/systemd/system/default.target.wants
+ln -sf remote-resource-service.service %{buildroot}%{_libdir}/systemd/system/default.target.wants/remote-resource-service.service
+mkdir -p %{buildroot}/usr/share/license
+#cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+%post -n capi-rrs-client -p /sbin/ldconfig
+%post -n capi-rrs-client-devel -p /sbin/ldconfig
+
+%postun -n capi-rrs-client -p /sbin/ldconfig
+%postun -n capi-rrs-client-devel -p /sbin/ldconfig
+
+chown -R root:root %{buildroot}/root/share/rrs/*.dat
+chsmack -a '_' %{buildroot}/root/share/rrs/*.dat
+
+chown -R owner:users %{buildroot}/home/owner/share/rrs/*.dat
+chsmack -a 'User::App::Shared' %{buildroot}/home/owner/share/rrs/*.dat
+
+%files -n rrs-serverd
+%manifest packaging/rrs-serverd.manifest
+%defattr(-,root,root,-)
+%{_bindir}/rrs-server*
+%{_libdir}/rrs/libsensor-framework-broker.so*
+%{_includedir}/*
+%{_libdir}/systemd/system/remote-resource-service.service
+%{_libdir}/systemd/system/default.target.wants/remote-resource-service.service
+%license LICENSE.APLv2
+%attr(0644,root,root)/usr/share/rrs/*.dat
+/root/share/rrs/*.dat
+%attr(0644,root,root)/usr/lib/rrs/schemas/rrsdiscovery.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/sensorcontrol.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/accelerometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/proximity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/autorotation.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/geomagneticrotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gravity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gyroscope.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gyroscoperotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrm.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledgreen.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledir.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledred.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/humidity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/light.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/linearacceleration.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/magnetometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/orientation.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/pressure.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/rotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/temperature.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uncalibratedgyroscope.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uncalibratedmagnetometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uv.json
+
+%files -n capi-rrs-client
+%manifest packaging/capi-rrs-client.manifest
+%defattr(-,root,root,-)
+%{_libdir}/librrs-client.so*
+%{_libdir}/librrs-common.so*
+%license LICENSE.APLv2
+%attr(0644,root,root)/usr/share/rrs/*.dat
+%attr(0644,owner,users)/home/owner/share/rrs/*.dat
+%attr(0644,root,root)/usr/lib/rrs/schemas/rrsdiscovery.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/sensorcontrol.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/accelerometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/proximity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/autorotation.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/geomagneticrotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gravity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gyroscope.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/gyroscoperotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrm.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledgreen.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledir.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/hrmledred.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/humidity.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/light.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/linearacceleration.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/magnetometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/orientation.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/pressure.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/rotationvector.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/temperature.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uncalibratedgyroscope.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uncalibratedmagnetometer.json
+%attr(0644,root,root)/usr/lib/rrs/schemas/uv.json
+
+%files -n capi-rrs-client-devel
+%defattr(-,root,root,-)
+%{_includedir}/*.h
+%{_libdir}/librrs-client.so*
+%{_libdir}/librrs-common.so*
+%{_libdir}/pkgconfig/rrs-client.pc
+%license LICENSE.APLv2
+
+
+%if %{build_test_suite} == "ON"
+%files -n rrs-test
+%defattr(-,root,root,-)
+%{_bindir}/rrs-test
+%license LICENSE.APLv2
+%endif
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+add_subdirectory(common)
+add_subdirectory(server)
+add_subdirectory(brokers)
+add_subdirectory(client)
\ No newline at end of file
--- /dev/null
+add_subdirectory(sensor_framework)
\ No newline at end of file
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(sensor-framework-broker CXX)
+
+SET(SERVICE_NAME sensor-framework-broker)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(sf-broker-pkgs REQUIRED glib-2.0 gio-2.0 dlog sensor iotcon)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+include_directories(${CMAKE_SOURCE_DIR}/src/server/daemon)
+
+FOREACH(flag ${sf-broker-pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${sf-broker-pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+add_library(${SERVICE_NAME} SHARED
+ SensorFrameworkBroker.cpp
+ )
+
+target_link_libraries(${SERVICE_NAME} ${sf-broker-pkgs_LDFLAGS} "-lm")
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"RRS-BROKER\"")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
+
+install(TARGETS ${SERVICE_NAME} DESTINATION lib/rrs)
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "SensorFrameworkBroker.h"
+#include "common.h"
+#include "schema.h"
+
+using std::bind1st;
+using std::mem_fun;
+
+#define BROKER_NAME "SENSOR_FRAMEWORK_BROKER"
+
+#define ACCELEROMETER_RAW_DATA_EVENT (ACCELEROMETER_SENSOR << 16) | 0x0001
+#define PROXIMITY_CHANGE_STATE_EVENT (PROXIMITY_SENSOR << 16) | 0x0001
+
+SensorFrameworkBroker::SensorFrameworkBroker()
+{
+ __name = std::string(BROKER_NAME);
+ ServiceManager::setThread(SensorFrameworkBroker::working, this);
+}
+
+SensorFrameworkBroker::~SensorFrameworkBroker()
+{
+ INFO("SensorFrameworkBroker is destroyed!\n");
+}
+
+bool SensorFrameworkBroker::init()
+{
+ INFO("%s is created!\n", getName());
+ return true;
+}
+
+void SensorFrameworkBroker::getSensorInfo(const rrs_resource_e resource_type, sensor_type_t *sensor_type, unsigned int *event_type)
+{
+ switch(resource_type) {
+ case RRS_RESOURCE_ACCELEROMETER:
+ *sensor_type = ACCELEROMETER_SENSOR;
+ *event_type = ACCELEROMETER_RAW_DATA_EVENT;
+ break;
+
+ case RRS_RESOURCE_PROXIMITY:
+ *sensor_type = PROXIMITY_SENSOR;
+ *event_type = PROXIMITY_CHANGE_STATE_EVENT;
+ break;
+
+ default :
+ break;
+ }
+}
+
+RrsService SensorFrameworkBroker::getType(void) {
+ return SENSOR_FRAMEWORK;
+}
+
+const char* SensorFrameworkBroker::getName(void)
+{
+ return __name.c_str();
+}
+
+bool SensorFrameworkBroker::working(void *inst)
+{
+ SensorFrameworkBroker *broker = (SensorFrameworkBroker *)inst;
+ return broker->processCommand();
+}
+
+bool SensorFrameworkBroker::onStart(void)
+{
+ INFO("Sensor Framework Broker Thread Started\n");
+ return startThread();
+}
+
+bool SensorFrameworkBroker::onStop(void)
+{
+ INFO("Sensor Framework Broker Thread Stopped\n");
+ return stopThread();
+}
+
+bool SensorFrameworkBroker::processEvent(const BrokerResource event_resource)
+{
+ ResourceQueue::__receive_event_instance().push(event_resource);
+ return true;
+}
+
+void SensorFrameworkBroker::__sensord_callback(const sensor_t sensor, const unsigned int event_type, sensor_data_t *data, void *user_data)
+{
+ SensorFrameworkBroker *broker_map_ptr = (SensorFrameworkBroker *) user_data;
+ BrokerResource event_resource;
+ BrokerResource *event_resource_ptr = NULL;
+
+ switch(event_type >> 16) {
+ case ACCELEROMETER_SENSOR:
+ // fix resource index = 1 hardcoding in the future
+ event_resource_ptr = broker_map_ptr->getEventResourceInfo(RRS_RESOURCE_ACCELEROMETER, 1);
+
+ event_resource.service_type = event_resource_ptr->service_type;
+ event_resource.resource_type = event_resource_ptr->resource_type;
+ event_resource.resource_index = event_resource_ptr->resource_index;
+
+ rrs_event_data_clone(event_resource_ptr->data, &(event_resource.data));
+
+ rrs_event_data_set_double(event_resource.data, "x", data->values[0]);
+ rrs_event_data_set_double(event_resource.data, "y", data->values[1]);
+ rrs_event_data_set_double(event_resource.data, "z", data->values[2]);
+
+ DBG("Sensor Type = %d, Event Type = %d, [%lld] [%6.6f] [%6.6f] [%6.6f]\n", sensor, event_type, data->timestamp, data->values[0], data->values[1], data->values[2]);
+ break;
+
+ case PROXIMITY_SENSOR:
+ // fix resource index = 1 hardcoding in the future
+ event_resource_ptr = broker_map_ptr->getEventResourceInfo(RRS_RESOURCE_PROXIMITY, 1);
+
+ event_resource.service_type = event_resource_ptr->service_type;
+ event_resource.resource_type = event_resource_ptr->resource_type;
+ event_resource.resource_index = event_resource_ptr->resource_index;
+
+ rrs_event_data_clone(event_resource_ptr->data, &(event_resource.data));
+
+ rrs_event_data_set_int(event_resource.data, "state", data->values[0]);
+
+ DBG("Sensor Type = %d, Event Type = %d, [%lld] [%6.6f]\n", sensor, event_type, data->timestamp, data->values[0]);
+ break;
+
+ default :
+ break;
+ }
+
+ processEvent(event_resource);
+}
+
+bool SensorFrameworkBroker::conSensor(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr)
+{
+ rrs_data_h control_data = broker_command_ptr.data;
+ unsigned int event_type = 0;
+ sensor_type_t sensor_type = UNKNOWN_SENSOR;
+
+ getSensorInfo(broker_command_ptr.resource_type, &sensor_type, &event_type);
+ sensor_t sensor = sensord_get_sensor(sensor_type);
+
+ if (!control_data) {
+ ERR("No Resource delivered in the command!!!");
+ }
+
+ if (!addClient(broker_command_ptr.resource_type)) {
+ ERR("Error adding client information for resource - %d", broker_command_ptr.resource_type);
+ return false;
+ }
+
+ if (getClientCnt(broker_command_ptr.resource_type) == 1) {
+ command_resource_ptr = getControlResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (command_resource_ptr == NULL) {
+ command_resource_ptr = new BrokerResource;
+ command_resource_ptr->service_type = broker_command_ptr.service_type;
+ command_resource_ptr->resource_type = broker_command_ptr.resource_type;
+ command_resource_ptr->resource_index = broker_command_ptr.resource_index;
+ rrs_data_clone(control_data, &(command_resource_ptr->data));
+ addControlResource(command_resource_ptr->resource_type, command_resource_ptr);
+ }
+
+ event_resource_ptr = getEventResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (event_resource_ptr == NULL) {
+ event_resource_ptr = new BrokerResource;
+ event_resource_ptr->service_type = broker_command_ptr.service_type;
+ event_resource_ptr->resource_type = broker_command_ptr.resource_type;
+ event_resource_ptr->resource_index = broker_command_ptr.resource_index;
+ addEventResource(event_resource_ptr->resource_type, event_resource_ptr);
+
+ if (rrs_event_data_create(event_resource_ptr->resource_type, &(event_resource_ptr->data))) {
+ ERR("rrs_event_data_create() failed");
+ return false;
+ }
+ }
+
+ command_resource_ptr->handle = sensord_connect(sensor);
+
+ INFO("Connected handle - %d, sensor event - %d\n", command_resource_ptr->handle, event_type);
+
+ rrs_data_set_bool(command_resource_ptr->data, "connect_sensor", true);
+ rrs_data_set_bool(command_resource_ptr->data, "disconnect_sensor", false);
+ }
+
+ return true;
+}
+
+bool SensorFrameworkBroker::disconSensor(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr)
+{
+ if (!deleteClient(broker_command_ptr.resource_type)) {
+ ERR("Error deleting client information for resource - %d", broker_command_ptr.resource_type);
+ return false;
+ }
+
+ if (getClientCnt(broker_command_ptr.resource_type) == 0) {
+ command_resource_ptr = getControlResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (command_resource_ptr != NULL) {
+ sensord_stop(command_resource_ptr->handle);
+ sensord_disconnect(command_resource_ptr->handle);
+
+ INFO("Disconnected handle - %d\n", command_resource_ptr->handle);
+
+ rrs_control_data_destroy(command_resource_ptr->data);
+ deleteControlResource(command_resource_ptr->resource_type, command_resource_ptr->resource_index);
+ delete command_resource_ptr;
+ } else {
+ ERR("Information for Resource Type - %d, Resource Index - %d, is missing in broker", broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ return false;
+ }
+
+ event_resource_ptr = getEventResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (event_resource_ptr != NULL) {
+ rrs_event_data_destroy(event_resource_ptr->data);
+ deleteEventResource(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ delete event_resource_ptr;
+ } else {
+ ERR("Information for Resource Type - %d, Resource Index - %d, is missing in broker", broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool SensorFrameworkBroker::regEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, int interval, int max_batch_latency)
+{
+ unsigned int event_type = 0;
+ sensor_type_t sensor_type = UNKNOWN_SENSOR;
+
+ getSensorInfo(broker_command_ptr.resource_type, &sensor_type, &event_type);
+
+ command_resource_ptr = getControlResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (command_resource_ptr == NULL) {
+ ERR("Broker not connected to resource\n");
+ return false;
+ }
+
+ if (!sensord_register_event(command_resource_ptr->handle, event_type, interval, max_batch_latency, __sensord_callback, (void *) this)) {
+ ERR("Error registering handle - %d, sensor event - %d, interval - %d\n", command_resource_ptr->handle, event_type, interval);
+ return false;
+ }
+
+ if (getClientCnt(broker_command_ptr.resource_type) == 1) {
+ sensord_start(command_resource_ptr->handle, 0);
+ }
+
+ rrs_data_set_bool(command_resource_ptr->data, "register_event", true);
+ rrs_data_set_int(command_resource_ptr->data, "interval", interval);
+ rrs_data_set_int(command_resource_ptr->data, "max_batch_latency", max_batch_latency);
+
+ return true;
+}
+
+bool SensorFrameworkBroker::unregEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr)
+{
+ unsigned int event_type = 0;
+ sensor_type_t sensor_type = UNKNOWN_SENSOR;
+
+ getSensorInfo(broker_command_ptr.resource_type, &sensor_type, &event_type);
+
+ command_resource_ptr = getControlResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (command_resource_ptr == NULL) {
+ ERR("Broker not connected to resource\n");
+ return false;
+ }
+
+ if (!sensord_unregister_event(command_resource_ptr->handle, event_type)) {
+ ERR("Error unregistering sensor event - %d\n\n", event_type);
+ return false;
+ }
+
+ rrs_data_set_bool(command_resource_ptr->data, "unregister_event", true);
+
+ return true;
+}
+
+bool SensorFrameworkBroker::pollEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr)
+{
+ sensor_data_t data;
+ BrokerResource event_resource;
+ unsigned int event_type = 0;
+ sensor_type_t sensor_type = UNKNOWN_SENSOR;
+
+ getSensorInfo(broker_command_ptr.resource_type, &sensor_type, &event_type);
+
+ command_resource_ptr = getControlResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (command_resource_ptr == NULL) {
+ ERR("Broker not connected to resource\n");
+ return false;
+ }
+
+ if (getClientCnt(broker_command_ptr.resource_type) == 1) {
+ sensord_start(command_resource_ptr->handle, 0);
+ }
+
+ event_resource_ptr = getEventResourceInfo(broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ if (event_resource_ptr == NULL) {
+ ERR("Information for Resource Type - %d, Resource Index - %d, is missing in broker", broker_command_ptr.resource_type, broker_command_ptr.resource_index);
+ return false;
+ }
+
+ rrs_data_set_bool(command_resource_ptr->data, "get_data", true);
+
+ if (!sensord_get_data(command_resource_ptr->handle, event_type, &data)) {
+ ERR("Error getting data from sensord");
+ return false;
+ }
+
+ switch(event_type >> 16) {
+ case ACCELEROMETER_SENSOR:
+ rrs_data_set_double(event_resource_ptr->data, "x", data.values[0]);
+ rrs_data_set_double(event_resource_ptr->data, "y", data.values[1]);
+ rrs_data_set_double(event_resource_ptr->data, "z", data.values[2]);
+ break;
+ case PROXIMITY_SENSOR:
+ rrs_data_set_int(event_resource_ptr->data, "state", data.values[0]);
+ break;
+ default :
+ break;
+ }
+
+ if (getClientCnt(broker_command_ptr.resource_type) == 0) {
+ sensord_stop(command_resource_ptr->handle);
+ }
+
+ event_resource.service_type = event_resource_ptr->service_type;
+ event_resource.resource_type = event_resource_ptr->resource_type;
+ event_resource.resource_index = event_resource_ptr->resource_index;
+ rrs_data_clone(event_resource_ptr->data, &(event_resource.data));
+
+ ResourceQueue::__receive_event_instance().push(event_resource);
+
+ return true;
+}
+
+bool SensorFrameworkBroker::processCommand()
+{
+ int interval = 0;
+ int max_batch_latency = 0;
+ bool connect_sensor = false;
+ bool disconnect_sensor = false;
+ bool register_event = false;
+ bool unregister_event = false;
+ bool get_data = false;
+
+ rrs_data_h control_data = NULL;
+ BrokerResource *broker_command_ptr = NULL;
+ BrokerResource *command_resource_ptr = NULL, *event_resource_ptr = NULL;
+
+ broker_command_ptr = (BrokerResource *) ResourceQueue::__transmit_control_instance().pop();
+
+ if (broker_command_ptr->service_type != SENSOR_FRAMEWORK)
+ return true;
+
+ control_data = broker_command_ptr->data;
+ if (!control_data) {
+ ERR("No Resource delivered in the command!!!");
+ }
+
+ if (broker_command_ptr->service_type == SENSOR_FRAMEWORK) {
+ rrs_data_get_bool(control_data, "connect_sensor", &connect_sensor);
+ rrs_data_get_bool(control_data, "disconnect_sensor", &disconnect_sensor);
+ rrs_data_get_int(control_data, "interval", &interval);
+ rrs_data_get_int(control_data, "max_batch_latency", &max_batch_latency);
+ rrs_data_get_bool(control_data, "register_event", ®ister_event);
+ rrs_data_get_bool(control_data, "unregister_event", &unregister_event);
+ rrs_data_get_bool(control_data, "get_data", &get_data);
+
+ INFO("\tconnect_sensor: %d, disconnect_sensor: %d, interval: %d, max batch lat: %d, reg event: %d, unreg event: %d, get data %d",
+ connect_sensor, disconnect_sensor, interval, max_batch_latency, register_event, unregister_event, get_data);
+
+ if (connect_sensor) {
+ if (!conSensor(*broker_command_ptr, command_resource_ptr, event_resource_ptr)) {
+ ERR("Error connecting to resource - %d", broker_command_ptr->resource_type);
+ return false;
+ }
+
+ INFO("SensorFrameworkBroker: Connected Sensor!\n");
+
+ rrs_data_set_bool(control_data, "connect_sensor", false);
+ }
+ if (register_event) {
+ if (!regEvent(*broker_command_ptr, command_resource_ptr, interval, max_batch_latency)) {
+ ERR("Error registering for resource event - %d", broker_command_ptr->resource_type);
+ return false;
+ }
+
+ rrs_data_set_bool(control_data, "register_event", false);
+
+ INFO("SensorFrameworkBroker: Registered for Sensor Data Event!\n");
+ }
+ if (unregister_event) {
+ if (!unregEvent(*broker_command_ptr, command_resource_ptr)) {
+ ERR("Error unregistering resource event - %d", broker_command_ptr->resource_type);
+ return false;
+ }
+
+ rrs_data_set_bool(control_data, "unregister_event", false);
+
+ INFO("SensorFrameworkBroker: Unregistered for Sensor Data Event!\n");
+ }
+ if (get_data) {
+ if (!pollEvent(*broker_command_ptr, command_resource_ptr, event_resource_ptr)) {
+ ERR("Error polling data from resource - %d", broker_command_ptr->resource_type);
+ return false;
+ }
+
+ rrs_data_set_bool(control_data, "get_data", false);
+
+ INFO("SensorFrameworkBroker: Polling for Sensor Data completed!\n");
+ }
+ if (disconnect_sensor) {
+ if (!disconSensor(*broker_command_ptr, command_resource_ptr, event_resource_ptr)) {
+ ERR("Error disconnecting from resource - %d", broker_command_ptr->resource_type);
+ return false;
+ }
+
+ rrs_data_set_bool(control_data, "disconnect_sensor", false);
+
+ INFO("SensorFrameworkBroker: Disconnected Sensor!\n");
+ }
+ }
+
+ rrs_data_destroy(control_data);
+
+ return true;
+}
+
+extern "C" IotTizenModule* create(void)
+{
+ SensorFrameworkBroker *broker = NULL;
+
+ try {
+ broker = new(std::nothrow) SensorFrameworkBroker;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ IotTizenModule *broker_module = new(std::nothrow) IotTizenModule;
+ RETVM_IF(!broker_module || !broker, NULL, "Failed to allocate memory");
+
+ broker_module->modules.push_back(broker);
+
+ return broker_module;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _SENSOR_FRAMEWORK_BROKER_H_
+#define _SENSOR_FRAMEWORK_BROKER_H_
+
+#include <sensor_internal.h>
+#include <sensor_common.h>
+#include "ServiceManager.h"
+#include "PluginLoader.h"
+#include "rrs.h"
+
+class SensorFrameworkBroker : public ServiceManager {
+public:
+ SensorFrameworkBroker();
+ virtual ~SensorFrameworkBroker();
+
+ bool init();
+ RrsService getType(void);
+ const char* getName(void);
+ static bool working(void *inst);
+ static bool processEvent(const BrokerResource broker_resource);
+ bool processCommand(void);
+
+ static void __sensord_callback(const sensor_t sensor, const unsigned int event_type, sensor_data_t *data, void *user_data);
+
+private:
+ bool onStart(void);
+ bool onStop(void);
+ void getSensorInfo(const rrs_resource_e resource_type, sensor_type_t *sensor_type, unsigned int *event_type);
+ bool conSensor(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr);
+ bool disconSensor(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr);
+ bool regEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, int interval, int max_batch_latency);
+ bool unregEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr);
+ bool pollEvent(const BrokerResource broker_command_ptr, BrokerResource *command_resource_ptr, BrokerResource *event_resource_ptr);
+
+ std::string __name;
+};
+
+#endif
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(rrs-client CXX)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(rrs-client-pkgs REQUIRED dlog glib-2.0 iotcon)
+
+INCLUDE_DIRECTORIES(include)
+FILE(GLOB rrs-client-srcs *.c *.cpp)
+
+FOREACH(flag ${rrs-client-pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${rrs-client-pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+
+add_library(${PROJECT_NAME} SHARED ${rrs-client-srcs} )
+
+target_link_libraries(${PROJECT_NAME} ${rrs-client-pkgs_LDFLAGS} "rrs-common" "-lrt -ldl -pthread")
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc @ONLY)
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"RRS-CLIENT\"")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
+
+install(TARGETS ${PROJECT_NAME} DESTINATION lib)
+INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "ClientManager.h"
+#include <stdlib.h>
+#include <glib.h>
+#include <string>
+#include "common.h"
+
+ClientManager::ClientManager()
+{
+}
+
+ClientManager::~ClientManager()
+{
+}
+
+void ClientManager::addResource(const rrs_resource_e res, ResourceClient *info)
+{
+ client_map::iterator it;
+
+ it = __clientInfo.insert(std::make_pair(res, info));
+}
+
+bool ClientManager::deleteResource(const iotcon_remote_resource_h resource)
+{
+ client_map::iterator it;
+
+ for (it = __clientInfo.begin(); it != __clientInfo.end(); ++it) {
+ if (((*it).second)->__remoteResource == resource) {
+ __clientInfo.erase(it);
+ }
+ }
+
+ return true;
+}
+
+rrs_resource_h ClientManager::createHandle(ResourceClient *resource)
+{
+ int handle = 1;
+
+ AUTOLOCK(__handleLock);
+
+ while (__handleInfo.count(handle) > 0)
+ handle++;
+
+ if (handle == MAX_CLIENT_HANDLE) {
+ ERR("Max Handles reached");
+ return ERROR_HANDLE;
+ }
+
+ __handleInfo.insert(std::pair<int,ResourceClient *> (handle, resource));
+
+ return handle;
+}
+
+bool ClientManager::deleteHandle(const rrs_resource_h handle)
+{
+ AUTOLOCK(__handleLock);
+
+ auto it_handle = __handleInfo.find(handle);
+
+ if (it_handle == __handleInfo.end()) {
+ ERR("Handle[%d] is not found", handle);
+ return false;
+ }
+
+ __handleInfo.erase(it_handle);
+ return true;
+}
+
+int ClientManager::getHandle(ResourceClient *resource)
+{
+ handle_map::iterator it;
+
+ for (it = __handleInfo.begin(); it != __handleInfo.end(); ++it) {
+ if (it->second == resource) {
+ return (it->first);
+ }
+ }
+
+ INFO("Handle not found for resource with address - %p", resource);
+
+ return ERROR_HANDLE;
+}
+
+bool ClientManager::getResourceFromHandle(const rrs_resource_h handle, ResourceClient **resource)
+{
+ auto it_handle = __handleInfo.find(handle);
+
+ if (it_handle == __handleInfo.end()) {
+ ERR("Handle[%d] is not found", handle);
+ return false;
+ }
+
+ *resource = it_handle->second;
+ return true;
+}
+
+ResourceClient *ClientManager::getResourceInfo(const iotcon_remote_resource_h resource)
+{
+ client_map::iterator it;
+
+ for (it = __clientInfo.begin(); it != __clientInfo.end(); ++it) {
+ if ((it->second)->__remoteResource == resource) {
+ return (it->second);
+ }
+ }
+
+ return NULL;
+}
+
+bool ClientManager::iterateForEachResource(const rrs_resource_e type, foreach_resource_cb callback, void *user_data)
+{
+ handle_map::iterator it;
+
+ for (it = __handleInfo.begin(); it != __handleInfo.end(); ++it) {
+ if ((it->second)->__resourceType == type) {
+ if (callback(it->first, user_data) == false)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int ClientManager::getCount(const rrs_resource_e type)
+{
+ client_map::iterator it;
+ int count = 0;
+
+ for (it = __clientInfo.begin(); it != __clientInfo.end(); ++it) {
+ if ((it->second)->__resourceType == type) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+ClientManager& ClientManager::__get_instance()
+{
+ static ClientManager inst;
+ return inst;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _CLIENT_MANAGER_H_
+#define _CLIENT_MANAGER_H_
+
+#include <stdint.h>
+#include <map>
+#include <unordered_map>
+#include "rrs.h"
+#include "schema.h"
+#include "services_common.h"
+#include "ResourceClient.h"
+#include "Mutex.h"
+
+#define MAX_CLIENT_HANDLE 10000
+#define ERROR_HANDLE -1
+
+typedef bool(*foreach_resource_cb) (rrs_resource_h resource, void *user_data);
+
+class ClientManager {
+public:
+ typedef std::multimap<rrs_resource_e, ResourceClient *> client_map;
+ typedef std::unordered_map<rrs_resource_h, ResourceClient *> handle_map;
+
+ static ClientManager& __get_instance();
+ rrs_resource_h createHandle(ResourceClient *resource);
+ bool deleteHandle(const rrs_resource_h handle);
+ int getHandle(ResourceClient *resource);
+ bool getResourceFromHandle(const rrs_resource_h handle, ResourceClient **resource);
+ void addResource(const rrs_resource_e res, ResourceClient *info);
+ bool deleteResource(const iotcon_remote_resource_h resource);
+ ResourceClient *getResourceInfo(const iotcon_remote_resource_h resource);
+ bool iterateForEachResource(const rrs_resource_e type, foreach_resource_cb callback, void *user_data);
+ int getCount(const rrs_resource_e type);
+
+ client_map __clientInfo;
+ handle_map __handleInfo;
+ Mutex __handleLock;
+private:
+ ClientManager();
+ virtual ~ClientManager();
+};
+
+#endif /* _CLIENT_MANAGER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 "FindResourceInfo.h"
+
+FindResourceInfo::FindResourceInfo()
+: __foundcb(NULL)
+, __foundData(NULL)
+, __rrs(0)
+, __resourceType(RRS_RESOURCE_NONE)
+{
+}
+
+FindResourceInfo::~FindResourceInfo()
+{
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _FIND_RESOURCE_INFO_H_
+#define _FIND_RESOURCE_INFO_H_
+
+#include "rrs.h"
+
+class FindResourceInfo {
+public:
+ FindResourceInfo();
+ virtual ~FindResourceInfo();
+
+ rrs_resource_found_cb __foundcb;
+ void *__foundData;
+ rrs_h __rrs;
+ rrs_resource_e __resourceType;
+};
+
+#endif /* _FIND_RESOURCE_INFO_H_ */
--- /dev/null
+/*
+ * 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 "ResourceClient.h"
+#include <stdlib.h>
+#include <glib.h>
+#include <string>
+#include <tizen_type.h>
+#include <new>
+#include "common.h"
+#include "IotconToRrs.h"
+#include "ClientManager.h"
+#include "RrsManager.h"
+
+ResourceClient::ResourceClient()
+: __foundcb(NULL)
+, __foundDiscoverycb(NULL)
+, __observecb(NULL)
+, __sendControlcb(NULL)
+, __monitorControlcb(NULL)
+, __receiveEventcb(NULL)
+, __destroycb(NULL)
+, __remoteResource(NULL)
+, __interfaces(NULL)
+, __connectivityType(IOTCON_CONNECTIVITY_ALL)
+, __eventRepr(NULL)
+, __foundData(NULL)
+, __foundDiscoveryData(NULL)
+, __observeData(NULL)
+, __sendControlData(NULL)
+, __monitorControlData(NULL)
+, __receiveEventData(NULL)
+, __destroyData(NULL)
+, __rrs(0)
+, __resourceType(RRS_RESOURCE_NONE)
+, __controlSchema(NULL)
+, __eventSchema(NULL)
+, __controlData(NULL)
+, __eventData(NULL)
+, __observeEnabled(false)
+, __type(NULL)
+, __hostAddress(NULL)
+{
+}
+
+ResourceClient::~ResourceClient()
+{
+ if (__controlData)
+ rrs_data_destroy(__controlData);
+ __controlData = NULL;
+
+ if (__eventData)
+ rrs_data_destroy(__eventData);
+ __eventData = NULL;
+
+ if (__controlSchema)
+ rrs_schema_destroy(__controlSchema);
+ __controlSchema = NULL;
+
+ if (__eventSchema)
+ rrs_schema_destroy(__eventSchema);
+ __eventSchema = NULL;
+}
+
+void ResourceClient::__on_observe(iotcon_remote_resource_h resource, iotcon_error_e err, int sequence_number, iotcon_response_h response, void *user_data)
+{
+ ResourceClient *client = (ResourceClient *) user_data;
+
+ if (sequence_number > 0) {
+ client->onResponseGetEvent(response);
+ client->__observecb(RRS_ERROR_NONE, client->__eventData, client->__observeData);
+ }
+}
+
+void ResourceClient::__on_response(iotcon_remote_resource_h resource, iotcon_error_e err, iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
+{
+ INFO("request(%d) was successful", request_type);
+
+ ResourceClient *inst = (ResourceClient *)user_data;
+
+ switch (request_type) {
+ case IOTCON_REQUEST_GET:
+ inst->onResponseGetControl(response);
+ break;
+ case IOTCON_REQUEST_PUT:
+ inst->onResponsePut(response);
+ break;
+ case IOTCON_REQUEST_DELETE:
+ inst->onResponseDelete(response);
+ break;
+ default:
+ ERR("Invalid request type (%d)", request_type);
+ return;
+ }
+}
+
+bool ResourceClient::__found_discovery_resource(iotcon_remote_resource_h resource, iotcon_error_e result, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+ ResourceClient *client = NULL;
+ FindResourceInfo *info = NULL;
+
+ if (resource == NULL || user_data == NULL)
+ return false;
+
+ INFO("===== discovery resource found =====");
+
+ client = new (std::nothrow) ResourceClient;
+ if (client == NULL) {
+ ERR("Error allocating memory for remote discovery resource handle!");
+ return false;
+ }
+
+ info = (FindResourceInfo *) user_data;
+
+ client->__rrs = info->__rrs;
+ client->__resourceType = info->__resourceType;
+ client->__foundDiscoverycb = info->__foundcb;
+ client->__foundDiscoveryData = info->__foundData;
+
+ ret = iotcon_remote_resource_get_host_address(resource, &client->__hostAddress);
+ if (ret != IOTCON_ERROR_NONE) {
+ delete client;
+ ERR("iotcon_remote_resource_get_host_address() Fail(%d)", ret);
+ return false;
+ }
+
+ DBG("[%s] resource host : %s", client->__uriPath, client->__hostAddress);
+
+ ret = iotcon_remote_resource_get_connectivity_type(resource, &client->__connectivityType);
+ if (ret != IOTCON_ERROR_NONE) {
+ delete client;
+ ERR("iotcon_remote_resource_get_connectivity_type() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_remote_resource_get_interfaces(resource, &client->__interfaces);
+ if (ret != IOTCON_ERROR_NONE) {
+ delete client;
+ ERR("iotcon_remote_resource_get_interfaces() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = rrs_discovery_schema_load(client->__resourceType, &client->__controlSchema);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_discovery_schema_load() Fail(%d)", ret);
+ delete client;
+ return false;
+ }
+
+ ret = rrs_schema_create_data(client->__controlSchema, &client->__controlData);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() Fail(%d)", ret);
+ rrs_schema_destroy(client->__controlSchema);
+ delete client;
+ return false;
+ }
+
+ ret = iotcon_remote_resource_clone(resource, &client->__remoteResource);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_clone() Fail(%d)", ret);
+ rrs_data_destroy(client->__controlData);
+ rrs_schema_destroy(client->__controlSchema);
+ delete client;
+ return false;
+ }
+
+ ClientManager::__get_instance().addResource(client->__resourceType, client);
+
+ handle = ClientManager::__get_instance().createHandle(client);
+ if (handle == ERROR_HANDLE) {
+ ERR("Error creating new client handle!");
+ delete client;
+ return false;
+ }
+
+ if (client->__foundDiscoverycb != NULL)
+ client->__foundDiscoverycb(RRS_ERROR_NONE, handle, client->__foundDiscoveryData);
+
+ return true;
+}
+
+bool ResourceClient::__found_resource(iotcon_remote_resource_h resource, iotcon_error_e result, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+ ResourceClient *client = NULL;
+ FindResourceInfo *info = NULL;
+ char *hostAddress = NULL;
+
+ if (resource == NULL || user_data == NULL)
+ return false;
+
+ INFO("===== resource found =====");
+
+ client = new (std::nothrow) ResourceClient;
+ if (client == NULL) {
+ ERR("Error allocating memory for remote resource handle!");
+ return false;
+ }
+
+ info = (FindResourceInfo *) user_data;
+
+ client->__rrs = info->__rrs;
+ client->__resourceType = info->__resourceType;
+ client->__foundcb = info->__foundcb;
+ client->__foundData = info->__foundData;
+
+ ret = iotcon_remote_resource_get_host_address(resource, &hostAddress);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_get_host_address() Fail(%d)", ret);
+ delete client;
+ return false;
+ }
+ DBG("[%s] resource host : %s", client->__uriPath, hostAddress);
+ client->__hostAddress = strdup(hostAddress);
+
+ ret = iotcon_remote_resource_get_connectivity_type(resource, &client->__connectivityType);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_get_connectivity_type() Fail(%d)", ret);
+ delete client;
+ return false;
+ }
+
+ ret = iotcon_remote_resource_get_interfaces(resource, &client->__interfaces);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_get_interfaces() Fail(%d)", ret);
+ delete client;
+ return false;
+ }
+
+ ret = rrs_schema_load(client->__resourceType, &client->__controlSchema, &client->__eventSchema);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_schema_load() Fail(%d)", ret);
+ delete client;
+ return false;
+ }
+
+ ret = rrs_schema_create_data(client->__controlSchema, &client->__controlData);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() Fail(%d)", ret);
+ rrs_schema_destroy(client->__controlSchema);
+ rrs_schema_destroy(client->__eventSchema);
+ delete client;
+ return false;
+ }
+
+ ret = rrs_schema_create_data(client->__eventSchema, &client->__eventData);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() Fail(%d)", ret);
+ rrs_data_destroy(client->__controlData);
+ rrs_schema_destroy(client->__controlSchema);
+ rrs_schema_destroy(client->__eventSchema);
+ delete client;
+ return false;
+ }
+
+ ret = iotcon_remote_resource_clone(resource, &client->__remoteResource);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_clone() Fail(%d)", ret);
+ rrs_data_destroy(client->__controlData);
+ rrs_data_destroy(client->__eventData);
+ rrs_schema_destroy(client->__controlSchema);
+ rrs_schema_destroy(client->__eventSchema);
+ delete client;
+ return false;
+ }
+
+ ClientManager::__get_instance().addResource(client->__resourceType, client);
+
+ handle = ClientManager::__get_instance().createHandle(client);
+ if (handle == ERROR_HANDLE) {
+ ERR("Error creating new client handle!");
+ delete client;
+ return false;
+ }
+
+ if (client->__foundcb != NULL)
+ client->__foundcb(RRS_ERROR_NONE, handle, client->__foundData);
+
+ return true;
+}
+
+bool ResourceClient::setControlRepresentation(iotcon_representation_h *repr)
+{
+ int ret = IOTCON_ERROR_NONE;
+ iotcon_attributes_h state = NULL;
+
+ ret = iotcon_attributes_create(&state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_create() Fail(%d)", ret);
+ return false;
+ }
+
+ IotconToRrs converter(__controlData, __controlSchema, state);
+ converter.setToIotcon();
+
+ ret = iotcon_representation_set_attributes(*repr, state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_set_attributes() Fail(%d)", ret);
+ iotcon_attributes_destroy(state);
+ return false;
+ }
+
+ iotcon_attributes_destroy(state);
+
+ return true;
+}
+
+bool ResourceClient::getControlRepresentation(const iotcon_representation_h repr)
+{
+ iotcon_attributes_h state = NULL;
+
+ const int ret = iotcon_representation_get_attributes(repr, &state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_get_attributes() Fail(%d)", ret);
+ return false;
+ }
+
+ IotconToRrs converter(__controlData, __controlSchema, state);
+
+ converter.getFromIotcon();
+
+ return true;
+}
+
+bool ResourceClient::getEventRepresentation(const iotcon_representation_h repr)
+{
+ iotcon_attributes_h state = NULL;
+
+ const int ret = iotcon_representation_get_attributes(repr, &state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_get_attributes() Fail(%d)", ret);
+ return false;
+ }
+
+ IotconToRrs converter(__eventData, __eventSchema, state);
+
+ converter.getFromIotcon();
+
+ return true;
+}
+
+bool ResourceClient::onResponseDelete(const iotcon_response_h response)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+ iotcon_response_result_e response_result;
+
+ ret = iotcon_response_get_result(response, &response_result);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_get_result() Fail(%d)", ret);
+ return false;
+ }
+
+ if (response_result != IOTCON_RESPONSE_OK && response_result != IOTCON_RESPONSE_RESOURCE_DELETED) {
+ ERR("on_response_delete Response error(%d)", response_result);
+ return false;
+ }
+
+ handle = ClientManager::__get_instance().getHandle(this);
+
+ if (__destroycb != NULL)
+ __destroycb(RRS_ERROR_NONE, handle, __destroyData);
+
+ DBG("DELETE request was successful");
+
+ return true;
+}
+
+bool ResourceClient::onResponsePut(const iotcon_response_h response)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+ iotcon_response_result_e response_result;
+
+ ret = iotcon_response_get_result(response, &response_result);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_get_result() Fail(%d)", ret);
+ return false;
+ }
+
+ if (response_result != IOTCON_RESPONSE_OK) {
+ ERR("on_response_put Response error(%d)", response_result);
+ return false;
+ }
+
+ handle = ClientManager::__get_instance().getHandle(this);
+
+ if (__sendControlcb != NULL)
+ __sendControlcb(RRS_ERROR_NONE, handle, __sendControlData);
+
+ DBG("PUT request was successful");
+
+ return true;
+}
+
+bool ResourceClient::onResponseGetEvent(const iotcon_response_h response)
+{
+ int ret = IOTCON_ERROR_NONE;
+
+ ret = iotcon_response_get_representation(response, &__eventRepr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_get_representation() Fail(%d)", ret);
+ return false;
+ }
+
+ getEventRepresentation(__eventRepr);
+
+ DBG("GET event request was successful");
+
+ return true;
+}
+
+bool ResourceClient::onResponseGetControl(const iotcon_response_h response)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+ iotcon_representation_h repr;
+
+ ret = iotcon_response_get_representation(response, &repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_get_representation() Fail(%d)", ret);
+ return false;
+ }
+
+ getControlRepresentation(repr);
+
+ handle = ClientManager::__get_instance().getHandle(this);
+
+ if (__monitorControlEnabled) {
+ if (__monitorControlcb != NULL) {
+ __monitorControlcb(RRS_ERROR_NONE, handle, __controlData, __monitorControlData);
+ __monitorControlEnabled = false;
+ }
+ }
+
+ if (__receiveEventEnabled) {
+ if (__receiveEventcb != NULL) {
+ rrs_convert_control_to_event_data(__controlData, &__eventData);
+ __receiveEventcb(RRS_ERROR_NONE, handle, __eventData, __receiveEventData);
+ __receiveEventEnabled = false;
+ }
+ }
+
+ iotcon_representation_destroy(repr);
+
+ DBG("GET control request was successful");
+
+ return true;
+}
+
+bool ResourceClient::deleteResource(rrs_resource_destroy_cb callback, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+ int handle = ERROR_HANDLE;
+
+ INFO("Delete Resource has been initiated");
+
+ __destroycb = callback;
+ __destroyData = user_data;
+
+ ret = iotcon_remote_resource_delete(__remoteResource, ResourceClient::__on_response, NULL);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon_remote_resource_delete() Fail(%d)", ret);
+ return false;
+ }
+
+ iotcon_remote_resource_destroy(__remoteResource);
+
+ observeUnregister();
+
+ free(__hostAddress);
+
+ if (__eventData)
+ rrs_data_destroy(__eventData);
+ __eventData = NULL;
+
+ if (__controlData)
+ rrs_data_destroy(__controlData);
+ __controlData = NULL;
+
+ if (__eventSchema)
+ rrs_schema_destroy(__eventSchema);
+ __eventSchema = NULL;
+
+ if (__controlSchema)
+ rrs_schema_destroy(__controlSchema);
+ __controlSchema = NULL;
+
+ handle = ClientManager::__get_instance().getHandle(this);
+
+ if (!ClientManager::__get_instance().deleteHandle(handle)) {
+ ERR("Cannot delete handle - %d", handle);
+ return false;
+ }
+
+ if (!ClientManager::__get_instance().deleteResource(__remoteResource)) {
+ ERR("Cannot delete remote resource handle - %d", __remoteResource);
+ return false;
+ }
+
+ return true;
+}
+
+bool ResourceClient::putControlData(rrs_resource_send_control_cb callback, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+ iotcon_representation_h repr = NULL;
+
+ INFO("Put Control Data has been initiated");
+
+ __sendControlcb = callback;
+ __sendControlData = user_data;
+
+ ret = iotcon_representation_create(&repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_create() Fail(%d)", ret);
+ return false;
+ }
+
+ if (!setControlRepresentation(&repr)) {
+ ERR("set_representation failed!");
+ iotcon_representation_destroy(repr);
+ return false;
+ }
+
+ ret = iotcon_remote_resource_put(__remoteResource, repr, NULL, ResourceClient::__on_response, (void *) this);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_post() Fail(%d)", ret);
+ iotcon_representation_destroy(repr);
+ return false;
+ }
+
+ iotcon_representation_destroy(repr);
+
+ return true;
+}
+
+bool ResourceClient::getControlData(rrs_resource_monitor_control_cb callback, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+
+ INFO("Get Control Data has been initiated");
+
+ __monitorControlcb = callback;
+ __monitorControlData = user_data;
+ __monitorControlEnabled = true;
+
+ ret = iotcon_remote_resource_get(__remoteResource, NULL, ResourceClient::__on_response, (void *) this);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon_remote_resource_get() Fail(%d)", ret);
+ return false;
+ }
+
+ return true;
+}
+
+bool ResourceClient::getEventData(rrs_resource_receive_event_cb callback, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+
+ INFO("Get Event Data has been initiated");
+
+ __receiveEventcb = callback;
+ __receiveEventData = user_data;
+ __receiveEventEnabled = true;
+
+ ret = iotcon_remote_resource_get(__remoteResource, NULL, ResourceClient::__on_response, (void *) this);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon_remote_resource_get() Fail(%d)", ret);
+ return false;
+ }
+
+ return true;
+}
+
+bool ResourceClient::observeRegister(rrs_resource_observe_cb callback, void *user_data)
+{
+ int ret = IOTCON_ERROR_NONE;
+ __observecb = callback;
+ __observeData = user_data;
+
+ ret = iotcon_representation_create(&__eventRepr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_remote_resource_observe_register(__remoteResource, IOTCON_OBSERVE_IGNORE_OUT_OF_ORDER, NULL, ResourceClient::__on_observe, (void *) this);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_observe_register() Fail(%d)", ret);
+ return false;
+ }
+
+ __observeEnabled = true;
+
+ return true;
+}
+
+bool ResourceClient::observeUnregister()
+{
+ if (__observeEnabled == true) {
+ iotcon_representation_destroy(__eventRepr);
+
+ iotcon_remote_resource_observe_deregister(__remoteResource);
+ __observeEnabled = false;
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RESOURCE_CLIENT_H_
+#define _RESOURCE_CLIENT_H_
+
+#include "ResourceClient.h"
+#include <iotcon.h>
+#include "rrs.h"
+#include "schema.h"
+#include "services_common.h"
+
+class ResourceClient {
+public:
+ ResourceClient();
+ virtual ~ResourceClient();
+ bool setControlRepresentation(iotcon_representation_h *repr);
+ bool getControlRepresentation(const iotcon_representation_h repr);
+ bool getEventRepresentation(const iotcon_representation_h repr);
+ bool onResponseDelete(const iotcon_response_h response);
+ bool onResponsePut(const iotcon_response_h response);
+ bool onResponseGetControl(const iotcon_response_h response);
+ bool onResponseGetEvent(const iotcon_response_h response);
+ bool deleteResource(rrs_resource_destroy_cb callback, void *user_data);
+ bool putControlData(rrs_resource_send_control_cb callback, void *user_data);
+ bool getControlData(rrs_resource_monitor_control_cb callback, void *user_data);
+ bool getEventData(rrs_resource_receive_event_cb callback, void *user_data);
+ bool observeRegister(rrs_resource_observe_cb callback, void *user_data);
+ bool observeUnregister();
+
+ static void __on_observe(iotcon_remote_resource_h resource, iotcon_error_e err, int sequence_number, iotcon_response_h response, void *user_data);
+ static void __on_response(iotcon_remote_resource_h resource, iotcon_error_e err, iotcon_request_type_e request_type, iotcon_response_h response, void *user_data);
+ static bool __found_discovery_resource(iotcon_remote_resource_h resource, iotcon_error_e result, void *user_data);
+ static bool __found_resource(iotcon_remote_resource_h resource, iotcon_error_e result, void *user_data);
+
+ rrs_resource_found_cb __foundcb;
+ rrs_resource_found_cb __foundDiscoverycb;
+ rrs_resource_observe_cb __observecb;
+ rrs_resource_send_control_cb __sendControlcb;
+ rrs_resource_monitor_control_cb __monitorControlcb;
+ rrs_resource_receive_event_cb __receiveEventcb;
+ rrs_resource_destroy_cb __destroycb;
+ iotcon_remote_resource_h __remoteResource;
+ iotcon_resource_interfaces_h __interfaces;
+ iotcon_connectivity_type_e __connectivityType;
+ iotcon_representation_h __eventRepr;
+ void *__foundData;
+ void *__foundDiscoveryData;
+ void *__observeData;
+ void *__sendControlData;
+ void *__monitorControlData;
+ void *__receiveEventData;
+ void *__destroyData;
+ rrs_h __rrs;
+ rrs_resource_e __resourceType;
+ rrs_schema_h __controlSchema;
+ rrs_schema_h __eventSchema;
+ rrs_data_h __controlData;
+ rrs_data_h __eventData;
+ bool __observeEnabled;
+ bool __monitorControlEnabled;
+ bool __receiveEventEnabled;
+ char *__type;
+ char *__hostAddress;
+};
+
+#endif /* _ResourceClient_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "RrsManager.h"
+#include <stdlib.h>
+#include <glib.h>
+#include <string>
+#include "common.h"
+
+RrsManager::RrsManager()
+{
+}
+
+RrsManager::~RrsManager()
+{
+}
+
+void RrsManager::addResource(const rrs_resource_e res, FindResourceInfo info)
+{
+ rrs_manager_map::iterator it;
+
+ it = __manager_map.find(res);
+
+ if (it != __manager_map.end())
+ __manager_map.erase (it);
+
+ __manager_map.insert(std::pair<rrs_resource_e, FindResourceInfo>(res, info));
+}
+
+bool RrsManager::deleteResource(const rrs_resource_e res)
+{
+ rrs_manager_map::iterator it;
+
+ it = __manager_map.find(res);
+
+ if (it != __manager_map.end())
+ __manager_map.erase (it);
+
+ return true;
+}
+
+FindResourceInfo *RrsManager::getResourceInfo(const rrs_resource_e res)
+{
+ rrs_manager_map::iterator it;
+
+ it = __manager_map.find(res);
+
+ if (it == __manager_map.end())
+ return NULL;
+
+ return &(it->second);
+}
+
+RrsManager& RrsManager::__get_instance()
+{
+ static RrsManager inst;
+ return inst;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RRS_MANAGER_H_
+#define _RRS_MANAGER_H_
+
+#include <stdint.h>
+#include <map>
+#include "rrs.h"
+#include "FindResourceInfo.h"
+
+class RrsManager {
+public:
+ typedef std::map<rrs_resource_e, FindResourceInfo> rrs_manager_map;
+
+ static RrsManager& __get_instance();
+ void addResource(const rrs_resource_e res, FindResourceInfo info);
+ bool deleteResource(const rrs_resource_e res);
+ FindResourceInfo *getResourceInfo(const rrs_resource_e res);
+
+ rrs_manager_map __manager_map;
+private:
+ RrsManager();
+ virtual ~RrsManager();
+};
+
+#endif /* _RRS_MANAGER_H_ */
--- /dev/null
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}/bin
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: @CLIENT@
+Description: Remote Resource Service
+Version: @FULLVER@
+Requires:
+Libs: -L${libdir} -l@CLIENT@
+Cflags: -I${includedir}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "rrs.h"
+#include <glib.h>
+#include <string>
+#include "schema.h"
+#include "ResourceClient.h"
+#include "ClientManager.h"
+#include "RrsManager.h"
+
+extern bool __has_iot_privilege();
+
+#define INVALID_RESOURCE_HANDLE 0
+
+static Mutex rrs_manager_mutex;
+
+void rrs_type_to_name(const rrs_resource_e type, char **resource_name)
+{
+ switch(type) {
+ case RRS_RESOURCE_DISCOVERY:
+ *resource_name = strdup(DISCOVERY_RESOURCE_NAME);
+ break;
+ case RRS_RESOURCE_ACCELEROMETER:
+ *resource_name = strdup(ACCELEROMETER_RESOURCE_NAME);
+ break;
+ case RRS_RESOURCE_PROXIMITY:
+ *resource_name = strdup(PROXIMITY_RESOURCE_NAME);
+ break;
+ default :
+ ERR("Resource [%d] not supported!", type);
+ break;
+ }
+}
+
+EXPORT_API int rrs_resource_find(const rrs_h rrs, const rrs_resource_e type, rrs_resource_found_cb callback, void *user_data)
+{
+ char *resource_name;
+ FindResourceInfo info;
+ FindResourceInfo *info_ptr = NULL;
+ int ret = IOTCON_ERROR_NONE;
+
+ /* Check if RRS handle is valid */
+ if (rrs < 1 || rrs > MAX_RRS_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if ((type < RRS_RESOURCE_NONE)
+ || (type > RRS_RESOURCE_ALL)
+ || !callback)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ rrs_type_to_name(type, &resource_name);
+
+ info.__rrs = rrs;
+ info.__resourceType = type;
+ info.__foundcb = callback;
+ info.__foundData = user_data;
+
+ {
+ AUTOLOCK(rrs_manager_mutex);
+ RrsManager::__get_instance().addResource(type, info);
+ }
+
+ info_ptr = RrsManager::__get_instance().getResourceInfo(type);
+
+ if (type == RRS_RESOURCE_DISCOVERY) {
+ /* find discovery resource */
+ ret = iotcon_find_resource(IOTCON_MULTICAST_ADDRESS, IOTCON_CONNECTIVITY_IPV4, resource_name, false, ResourceClient::__found_discovery_resource, (void *)info_ptr);
+
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_find_resource() Fail(%d)", ret);
+ iotcon_deinitialize();
+ return false;
+ }
+
+ DBG("Find discovery Resource has been initiated!");
+ } else {
+ /* find resources */
+ ret = iotcon_find_resource(IOTCON_MULTICAST_ADDRESS, IOTCON_CONNECTIVITY_IPV4, resource_name, false, ResourceClient::__found_resource, (void *)info_ptr);
+
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_find_resource() Fail(%d)", ret);
+ iotcon_deinitialize();
+ return false;
+ }
+
+ DBG("Find Resource has been initiated!");
+ }
+
+ free(resource_name);
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_foreach_resource(const rrs_h rrs, const rrs_resource_e type, rrs_foreach_resource_cb callback, void *user_data)
+{
+ /* Check if RRS handle is valid */
+ if (rrs < 1 || rrs > MAX_RRS_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if ((type < RRS_RESOURCE_NONE)
+ || (type > RRS_RESOURCE_ALL)
+ || !callback)
+ return RRS_ERROR_INVALID_TYPE;
+
+ if (!ClientManager::__get_instance().iterateForEachResource(type, callback, user_data)) {
+ ERR("Error iterating over found handles for resource [%d]!", type);
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_destroy(const rrs_resource_h handle, rrs_resource_destroy_cb callback, void *user_data)
+{
+ ResourceClient *client = NULL;
+ rrs_resource_e *type = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (!client->deleteResource(callback, user_data)) {
+ ERR("Error deleting resource!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ *type = client->__resourceType;
+
+ {
+ AUTOLOCK(rrs_manager_mutex);
+ if (!RrsManager::__get_instance().deleteResource(*type)) {
+ ERR("Error deleting resource!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+ }
+
+ delete client;
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_get_count(const rrs_h rrs, const rrs_resource_e type, int *count)
+{
+ /* Check if RRS handle is valid */
+ if (rrs < 1 || rrs > MAX_RRS_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if ((type < RRS_RESOURCE_NONE)
+ || (type > RRS_RESOURCE_ALL))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ *count = ClientManager::__get_instance().getCount(type);
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_get_type(const rrs_resource_h handle, rrs_resource_e *type)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if RRS handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ *type = client->__resourceType;
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_get_device_name(const rrs_resource_h handle, char **device_name)
+{
+ ResourceClient *client = NULL;
+ char *deviceName = NULL;
+ int ret = IOTCON_ERROR_NONE;
+
+ /* Check if RRS handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ ret = iotcon_remote_resource_get_device_name(client->__remoteResource, &deviceName);
+ if (IOTCON_ERROR_NONE != ret) {
+ ERR("iotcon_remote_resource_get_device_name() Fail(%d)", ret);
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+ DBG("[%s] resource device name : %s", client->__uriPath, deviceName);
+ *device_name = strdup(deviceName);
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_get_device_id(const rrs_resource_h handle, char **device_id)
+{
+ ResourceClient *client = NULL;
+ char *deviceID = NULL;
+ int ret = IOTCON_ERROR_NONE;
+
+ /* Check if RRS handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ ret = iotcon_remote_resource_get_device_id(client->__remoteResource, &deviceID);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_get_device_id() Fail(%d)", ret);
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+ DBG("[%s] resource device id : %s", handle, deviceID);
+
+ *device_id = strdup(deviceID);
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_get_uri_path(const rrs_resource_h handle, char **uri_path)
+{
+ ResourceClient *client = NULL;
+ char *uriPath = NULL;
+ int ret = IOTCON_ERROR_NONE;
+
+ /* Check if RRS handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ ret = iotcon_remote_resource_get_uri_path(client->__remoteResource, &uriPath);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_remote_resource_get_uri_path() Fail(%d)", ret);
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ *uri_path = strdup(uriPath);
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_receive_event(const rrs_resource_h handle, rrs_resource_receive_event_cb callback, void *user_data)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (!client->getEventData(callback, user_data)) {
+ ERR("Error getting event data from remote resource!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_monitor_control(const rrs_resource_h handle, rrs_resource_monitor_control_cb callback, void *user_data)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (!client->getControlData(callback, user_data)) {
+ ERR("Error getting control data from remote resource!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_send_control(const rrs_resource_h handle, const rrs_control_data_h control_data, rrs_resource_send_control_cb callback, void *user_data)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!control_data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (control_data != client->__controlData) {
+ rrs_control_data_destroy(client->__controlData);
+ rrs_control_data_clone(control_data, &(client->__controlData));
+ }
+
+ if (!client->putControlData(callback, user_data)) {
+ ERR("Error sending control data from remote resource!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_subscribe_event(const rrs_resource_h handle, rrs_resource_observe_cb callback, void *user_data)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE) {
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ /* Check if parameters are valid */
+ if (!callback) {
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (!client->observeRegister(callback, user_data)) {
+ ERR("Error registering for observe functionality!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_resource_unsubscribe_event(const rrs_resource_h handle)
+{
+ ResourceClient *client = NULL;
+
+ /* Check if resource handle is valid */
+ if (handle == INVALID_RESOURCE_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ if (!ClientManager::__get_instance().getResourceFromHandle(handle, &client))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (!client->observeUnregister()) {
+ ERR("Error unregistering observe functionality!");
+ return RRS_ERROR_INVALID_OPERATION;
+ }
+
+ return RRS_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "BaseLock.h"
+#include <stdio.h>
+#include <pthread.h>
+#include <errno.h>
+#include <sys/time.h>
+#include "common.h"
+
+BaseLock::BaseLock()
+{
+ __historyMutex = PTHREAD_MUTEX_INITIALIZER;
+}
+
+BaseLock::~BaseLock()
+{
+ pthread_mutex_destroy(&__historyMutex);
+}
+
+void BaseLock::lock(LockType type, const char* expr, const char *module, const char *func, int line)
+{
+ int ret = 0;
+ char m_curent_info[OWNER_INFO_LEN];
+ struct timeval sv;
+ unsigned long long lock_waiting_start_time = 0;
+ unsigned long long lock_acquired_time = 0;
+ unsigned long long waiting_time = 0;
+
+ snprintf(m_curent_info, OWNER_INFO_LEN, "%s:%s(%d)", module, func, line);
+
+ if (type == LOCK_TYPE_MUTEX)
+ ret = tryLockImpl();
+ else if (type == LOCK_TYPE_READ)
+ ret = tryReadLockImpl();
+ else if (type == LOCK_TYPE_WRITE)
+ ret = tryWriteLockImpl();
+
+ if (ret == 0) {
+ pthread_mutex_lock(&__historyMutex);
+ snprintf(__ownerInfo, OWNER_INFO_LEN, "%s", m_curent_info);
+ pthread_mutex_unlock(&__historyMutex);
+ return;
+ }
+
+ gettimeofday(&sv, NULL);
+ lock_waiting_start_time = MICROSECONDS(sv);
+
+ pthread_mutex_lock(&__historyMutex);
+ INFO("%s is waiting for getting %s(0x%x) owned in %s",
+ m_curent_info, expr, this, __ownerInfo);
+ pthread_mutex_unlock(&__historyMutex);
+
+
+ if (type == LOCK_TYPE_MUTEX)
+ lockImpl();
+ else if (type == LOCK_TYPE_READ)
+ readLockImpl();
+ else if (type == LOCK_TYPE_WRITE)
+ writeLockImpl();
+
+ gettimeofday(&sv, NULL);
+ lock_acquired_time = MICROSECONDS(sv);
+
+ waiting_time = lock_acquired_time - lock_waiting_start_time;
+
+ pthread_mutex_lock(&__historyMutex);
+ INFO("%s acquires lock after waiting %lluus, %s(0x%x) was previously owned in %s",
+ m_curent_info, waiting_time, expr, this, __ownerInfo);
+ snprintf(__ownerInfo, OWNER_INFO_LEN, "%s", m_curent_info);
+ pthread_mutex_unlock(&__historyMutex);
+}
+
+
+void BaseLock::lock(LockType type)
+{
+ if (type == LOCK_TYPE_MUTEX)
+ lockImpl();
+ else if (type == LOCK_TYPE_READ)
+ readLockImpl();
+ else if (type == LOCK_TYPE_WRITE)
+ writeLockImpl();
+}
+
+void BaseLock::unlock(void)
+{
+ unlockImpl();
+}
+
+int BaseLock::lockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::readLockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::writeLockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::tryLockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::tryReadLockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::tryWriteLockImpl(void)
+{
+ return 0;
+}
+
+int BaseLock::unlockImpl(void)
+{
+ return 0;
+}
+
+Autolock::Autolock(BaseLock &m, LockType type, const char* expr, const char *module, const char *func, int line)
+: __lock(m)
+{
+ __lock.lock(type, expr, module, func, line);
+}
+
+Autolock::Autolock(BaseLock &m, LockType type)
+: __lock(m)
+{
+ __lock.lock(type);
+}
+
+Autolock::~Autolock()
+{
+ __lock.unlock();
+}
--- /dev/null
+/*
+ * IOT_Broker_Service
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#if !defined(_BASE_LOCK_H_)
+#define _BASE_LOCK_H_
+
+#include <pthread.h>
+
+enum LockType {
+ LOCK_TYPE_MUTEX,
+ LOCK_TYPE_READ,
+ LOCK_TYPE_WRITE,
+};
+
+#ifdef _LOCK_DEBUG
+#define AUTOLOCK(x) Autolock x##_autolock((x), LOCK_TYPE_MUTEX, #x, __MODULE__, __func__, __LINE__)
+#define AUTOLOCK_R(x) Autolock x##_autolock_r((x), LOCK_TYPE_READ, #x, __MODULE__, __func__, __LINE__)
+#define AUTOLOCK_W(x) Autolock x##_autolock_w((x), LOCK_TYPE_WRITE, #x, __MODULE__, __func__, __LINE__)
+#define LOCK(x) (x).lock(#x, __MODULE__, __func__, __LINE__)
+#define LOCK_R(x) (x).lock(LOCK_TYPE_READ, #x, __MODULE__, __func__, __LINE__)
+#define LOCK_W(x) (x).lock(LOCK_TYPE_WRITE, #x, __MODULE__, __func__, __LINE__)
+#define UNLOCK(x) (x).unlock()
+#else
+#define AUTOLOCK(x) Autolock x##_autolock((x), LOCK_TYPE_MUTEX)
+#define AUTOLOCK_R(x) Autolock x##_autolock_r((x), LOCK_TYPE_READ)
+#define AUTOLOCK_W(x) Autolock x##_autolock_w((x), LOCK_TYPE_WRITE)
+#define LOCK(x) (x).lock()
+#define LOCK_R(x) (x).lock(LOCK_TYPE_READ)
+#define LOCK_W(x) (x).lock(LOCK_TYPE_WRITE)
+#define UNLOCK(x) (x).unlock()
+#endif
+
+
+class BaseLock {
+public:
+ BaseLock();
+ virtual ~BaseLock();
+
+ void lock(LockType type, const char* expr, const char *module, const char *func, int line);
+ void lock(LockType type);
+ void unlock(void);
+
+protected:
+ virtual int lockImpl(void);
+ virtual int readLockImpl(void);
+ virtual int writeLockImpl(void);
+
+ virtual int tryLockImpl(void);
+ virtual int tryReadLockImpl(void);
+ virtual int tryWriteLockImpl(void);
+
+ virtual int unlockImpl(void);
+private:
+ pthread_mutex_t __historyMutex;
+ static const int OWNER_INFO_LEN = 256;
+ char __ownerInfo[OWNER_INFO_LEN];
+};
+
+class Autolock {
+public:
+ Autolock(BaseLock &m, LockType type, const char* expr, const char *module, const char *func, int line);
+ Autolock(BaseLock &m, LockType type);
+ ~Autolock();
+private:
+ BaseLock& __lock;
+};
+
+#endif
+// End of a file
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(rrs-common CXX)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(rrs-common-pkgs REQUIRED glib-2.0 dlog json-glib-1.0 iotcon cynara-client capi-system-info libtzplatform-config)
+
+INCLUDE_DIRECTORIES(include)
+FILE(GLOB rrs-common-srcs *.c *.cpp)
+
+FOREACH(flag ${rrs-common-pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${rrs-common-pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+add_library(${PROJECT_NAME} SHARED ${rrs-common-srcs} )
+
+target_link_libraries(${PROJECT_NAME} ${rrs-common-pkgs_LDFLAGS} "-lrt -ldl -pthread")
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"RRS-COMMON\"")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
+
+install(TARGETS ${PROJECT_NAME} DESTINATION lib)
+
+INSTALL(FILES schemas/rrsdiscovery.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/sensorcontrol.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/accelerometer.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/proximity.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/autorotation.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/geomagneticrotationvector.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/gravity.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/gyroscope.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/gyroscoperotationvector.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/hrm.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/hrmledgreen.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/hrmledir.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/hrmledred.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/humidity.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/light.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/linearacceleration.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/magnetometer.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/orientation.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/pressure.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/rotationvector.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/temperature.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/uncalibratedgyroscope.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/uncalibratedmagnetometer.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES schemas/uv.json DESTINATION /usr/lib/rrs/schemas)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/rrs-svr-db.dat DESTINATION /usr/share/rrs)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/rrs-svr-db.dat DESTINATION /root/share/rrs/)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/rrs-svr-db.dat DESTINATION /home/owner/share/rrs/)
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "IotconToRrs.h"
+#include <glib.h>
+#include "common.h"
+
+IotconToRrs::IotconToRrs(rrs_data_h d,
+ rrs_schema_h sch,
+ iotcon_attributes_h st)
+: __data(d)
+, __schema(sch)
+, __state(st)
+{
+}
+
+IotconToRrs::~IotconToRrs()
+{
+}
+
+bool IotconToRrs::__foreach_field_get_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *value,
+ void *user_data)
+{
+ if (!user_data)
+ return false;
+ IotconToRrs *obj = (IotconToRrs *)user_data;
+
+ (obj->__mutex).lock();
+ switch (type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ break;
+ case RRS_SCHEMA_TYPE_BOOL: {
+ bool b = false;
+ int ret = iotcon_attributes_get_bool(obj->__state, name, &b);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_get_bool() Fail(%d)", ret);
+ return false;
+ }
+ *((bool *)value) = b;
+ break;
+ }
+ case RRS_SCHEMA_TYPE_INT: {
+ int n = 0;
+ int ret = iotcon_attributes_get_int(obj->__state, name, &n);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_get_int() Fail(%d)", ret);
+ return false;
+ }
+ *((int *)value) = n;
+ break;
+ }
+ case RRS_SCHEMA_TYPE_DOUBLE: {
+ double d = .0;
+ int ret = iotcon_attributes_get_double(obj->__state, name, &d);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_get_double() Fail(%d)", ret);
+ return false;
+ }
+ *((double *)value) = d;
+ break;
+ }
+ case RRS_SCHEMA_TYPE_STR: {
+ char *c = NULL;
+ int ret = iotcon_attributes_get_str(obj->__state, name, &c);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_get_str() Fail(%d)", ret);
+ return false;
+ }
+ rrs_data_set_string(obj->__data, name, c);
+ break;
+ }
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ INFO("Converting of complex types are not supported yet");
+ break;
+ default:
+ ERR("Unsupported type");
+ break;
+ }
+ return true;
+}
+
+bool IotconToRrs::__foreach_field_set_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *value,
+ void *user_data)
+{
+ if (!user_data)
+ return false;
+ IotconToRrs *obj = (IotconToRrs *)user_data;
+
+ (obj->__mutex).lock();
+ switch (type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ break;
+ case RRS_SCHEMA_TYPE_BOOL: {
+ int ret = iotcon_attributes_add_bool(obj->__state, name, *((bool *)value));
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_add_bool() Fail(%d)", ret);
+ iotcon_attributes_destroy(obj->__state);
+ return false;
+ }
+ break;
+ }
+ case RRS_SCHEMA_TYPE_INT: {
+ int ret = iotcon_attributes_add_int(obj->__state, name, *((int *)value));
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_add_int() Fail(%d)", ret);
+ iotcon_attributes_destroy(obj->__state);
+ return false;
+ }
+ break;
+ }
+ case RRS_SCHEMA_TYPE_DOUBLE: {
+ int ret = iotcon_attributes_add_double(obj->__state, name, *((double *)value));
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_add_double() Fail(%d)", ret);
+ iotcon_attributes_destroy(obj->__state);
+ return false;
+ }
+ break;
+ }
+ case RRS_SCHEMA_TYPE_STR: {
+ int ret = iotcon_attributes_add_str(obj->__state, name, (char *)value);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_add_str() Fail(%d)", ret);
+ iotcon_attributes_destroy(obj->__state);
+ return false;
+ }
+ break;
+ }
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ INFO("Converting of complex types are not supported yet");
+ break;
+ default:
+ ERR("Unsupported type");
+ break;
+ }
+ return true;
+}
+
+void IotconToRrs::getFromIotcon()
+{
+ const int ret = rrs_data_foreach_field(__data,
+ __schema,
+ __foreach_field_get_cb,
+ this);
+
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_data_foreach_field() failed");
+ }
+}
+
+void IotconToRrs::setToIotcon()
+{
+ const int ret = rrs_data_foreach_field(__data,
+ __schema,
+ __foreach_field_set_cb,
+ this);
+
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_data_foreach_field() failed");
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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 _IOTCON_TO_RRS_H_
+#define _IOTCON_TO_RRS_H_
+
+#include <iotcon.h>
+#include "rrs.h"
+#include "schema.h"
+#include "Mutex.h"
+
+class IotconToRrs {
+public:
+ IotconToRrs(rrs_data_h data, rrs_schema_h schema, iotcon_attributes_h state);
+ ~IotconToRrs();
+
+ void getFromIotcon();
+ void setToIotcon();
+private:
+ static bool __foreach_field_get_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *value,
+ void *user_data);
+
+ static bool __foreach_field_set_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *value,
+ void *user_data);
+
+ rrs_data_h __data;
+ rrs_schema_h __schema;
+ iotcon_attributes_h __state;
+ Mutex __mutex;
+};
+
+#endif /*_IOTCON_TO_RRS_H_*/
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 "Json.h"
+#include <string>
+#include <sstream>
+#include <locale>
+#include <iomanip>
+#include <json-glib/json-glib.h>
+#include "schema_types_internal.h"
+
+#define PATH_DELIM '.'
+#define GVAR_VALUES "values"
+#define GVAR_TYPES "types"
+
+static double __string_to_double(const char* in)
+{
+ IF_FAIL_RETURN_TAG(in, 0, _E, "Parameter NULL");
+
+ // Locale-independent string-to-double conversion
+ double out;
+ std::istringstream istr(in);
+ istr.imbue(std::locale("C"));
+ istr >> out;
+ return out;
+}
+
+static std::string __double_to_string(double in, int prec)
+{
+ // Locale-independent double-to-string conversion
+ std::ostringstream ostr;
+ ostr.imbue(std::locale("C"));
+ ostr << std::setprecision(prec) << std::fixed << in;
+ return ostr.str();
+}
+
+Json::Json()
+ : __jsonNode(NULL)
+{
+ JsonObject *obj = json_object_new();
+ IF_FAIL_VOID_TAG(obj, _E, "Json object construction failed");
+
+ __jsonNode = json_node_new(JSON_NODE_OBJECT);
+ if (!__jsonNode) {
+ json_object_unref(obj);
+ _E("Json object construction failed");
+ }
+
+ json_node_set_object(__jsonNode, obj);
+ json_object_unref(obj);
+}
+
+Json::Json(const Json& j)
+ : __jsonNode(NULL)
+{
+ __jsonNode = json_node_copy(j.__jsonNode);
+ IF_FAIL_VOID_TAG(__jsonNode, _E, "Json object construction failed");
+}
+
+Json::Json(const char* s)
+ : __jsonNode(NULL)
+{
+ if (s) {
+ parse(s);
+ } else {
+ parse(EMPTY_JSON_OBJECT);
+ }
+}
+
+Json::Json(const std::string& s)
+ : __jsonNode(NULL)
+{
+ if (s.empty()) {
+ parse(EMPTY_JSON_OBJECT);
+ } else {
+ parse(s.c_str());
+ }
+}
+
+Json::~Json()
+{
+ release();
+}
+
+void Json::load(const char *file)
+{
+ gboolean result;
+ JsonParser *parser = NULL;
+ JsonNode *root = NULL;
+
+ parser = json_parser_new();
+ IF_FAIL_VOID_TAG(parser, _E, "Memory allocation failed");
+
+ /*result = json_parser_load_from_data(parser, s, -1, NULL);*/
+
+ result = json_parser_load_from_file(parser, file, NULL);
+ IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
+
+ root = json_parser_get_root(parser);
+ IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
+
+ __jsonNode = json_node_copy(root);
+ IF_FAIL_CATCH_TAG(__jsonNode, _E, "Copying failed");
+
+CATCH:
+ if (parser)
+ g_object_unref(parser);
+}
+
+void Json::parse(const char* s)
+{
+ gboolean result;
+ JsonParser *parser = NULL;
+ JsonNode *root = NULL;
+
+ parser = json_parser_new();
+ IF_FAIL_VOID_TAG(parser, _E, "Memory allocation failed");
+
+ result = json_parser_load_from_data(parser, s, -1, NULL);
+ IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
+
+ root = json_parser_get_root(parser);
+ IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
+
+ __jsonNode = json_node_copy(root);
+ IF_FAIL_CATCH_TAG(__jsonNode, _E, "Copying failed");
+
+CATCH:
+ if (parser)
+ g_object_unref(parser);
+}
+
+void Json::release()
+{
+ if (__jsonNode) {
+ json_node_free(__jsonNode);
+ __jsonNode = NULL;
+ }
+}
+
+Json& Json::operator=(const Json& j)
+{
+ release();
+ __jsonNode = json_node_copy(j.__jsonNode);
+ if (!__jsonNode) {
+ _E("Json object copy failed");
+ }
+ return *this;
+}
+
+Json& Json::operator=(const char* s)
+{
+ release();
+ if (s) {
+ parse(s);
+ } else {
+ parse(EMPTY_JSON_OBJECT);
+ }
+ return *this;
+}
+
+Json& Json::operator=(const std::string& s)
+{
+ release();
+ if (s.empty()) {
+ parse(EMPTY_JSON_OBJECT);
+ } else {
+ parse(s.c_str());
+ }
+ return *this;
+}
+
+bool Json::operator==(const Json& rhs)
+ {
+ return nodeEquals(__jsonNode, rhs.__jsonNode);
+}
+
+bool Json::operator!=(const Json& rhs)
+ {
+ return !operator==(rhs);
+}
+
+/* TODO
+bool Json::contains(const Json& subset) const
+{
+ return false;
+}
+*/
+
+char* Json::dupCStr()
+{
+ IF_FAIL_RETURN_TAG(__jsonNode, NULL, _E, "Json object not initialized");
+
+ JsonGenerator *jgen = NULL;
+ char *output = NULL;
+
+ jgen = json_generator_new();
+ IF_FAIL_CATCH(jgen);
+
+ json_generator_set_root(jgen, __jsonNode);
+ output = json_generator_to_data(jgen, NULL);
+ IF_FAIL_CATCH(output);
+
+ g_object_unref(jgen);
+ return output;
+
+CATCH:
+ if (jgen) {
+ g_object_unref(jgen);
+ }
+
+ _E("Memory allocation failed");
+ return NULL;
+}
+
+std::string Json::str()
+{
+ std::string output;
+ char *_s = dupCStr();
+ IF_FAIL_RETURN(_s, output = EMPTY_JSON_OBJECT);
+
+ output = _s;
+ g_free(_s);
+
+ return output;
+}
+
+static char** __tokenize_path(const char* path, int* length)
+{
+ //TODO: Re-implement this tokenizer using C++ stuff
+ char** tokens;
+ const char* pch;
+ const char* begin;
+ int i;
+ int j;
+ int len;
+
+ if (path == NULL || strlen(path) == 0) {
+ *length = 0;
+ return NULL;
+ }
+
+ *length = 1;
+
+ for (pch = path; *pch != '\0'; pch++) {
+ if (*pch == PATH_DELIM) {
+ *length = *length + 1;
+ }
+ }
+
+ tokens = static_cast<char**>(g_malloc((*length) * sizeof(char*)));
+ IF_FAIL_RETURN_TAG(tokens, NULL, _E, "Memory allocation failed");
+
+ begin = path;
+ i = 0;
+
+ for (pch = path; ; pch++) {
+ if (*pch == PATH_DELIM || *pch == '\0') {
+ len = pch - begin;
+ tokens[i] = static_cast<char*>(g_malloc((len+1) * sizeof(char)));
+ IF_FAIL_CATCH_TAG(tokens[i], _E, "Memory allocation failed");
+ strncpy(tokens[i], begin, len);
+ tokens[i][len] = '\0';
+ i++;
+ begin = pch + 1;
+ }
+
+ if (*pch == '\0') {
+ break;
+ }
+ }
+
+ return tokens;
+
+CATCH:
+ for (j=0; j < i; j++) {
+ g_free(tokens[j]);
+ }
+ g_free(tokens);
+ return NULL;
+}
+
+static void __free_tokenized_path(int length, char** tokens)
+{
+ int i;
+ if (tokens) {
+ for (i=0; i < length; i++) {
+ g_free(tokens[i]);
+ }
+ g_free(tokens);
+ }
+}
+
+static JsonObject* __traverse(JsonNode* jnode, const char* path, bool force)
+{
+ IF_FAIL_RETURN_TAG(jnode, NULL, _E, "Invalid parameter");
+
+ int length = 0;
+ int depth = 0;
+ char **path_token = NULL;
+ JsonObject *jobj = NULL;
+ JsonObject *child_obj = NULL;
+ JsonNode *child_node = NULL;
+
+ jobj = json_node_get_object(jnode);
+ IF_FAIL_RETURN(jobj, NULL);
+
+ if (path) {
+ path_token = __tokenize_path(path, &length);
+ IF_FAIL_RETURN_TAG(path_token, NULL, _E, "Invalid path");
+ }
+
+ for (depth=0; depth < length; depth++) {
+ if (!json_object_has_member(jobj, path_token[depth])) {
+ if (force) {
+ child_obj = json_object_new();
+ IF_FAIL_CATCH_TAG(child_obj, _E, "Memory allocation failed");
+ json_object_set_object_member(jobj, path_token[depth], child_obj);
+ } else {
+ goto CATCH;
+ }
+ }
+ child_node = json_object_get_member(jobj, path_token[depth]);
+ IF_FAIL_CATCH(child_node && json_node_get_node_type(child_node) == JSON_NODE_OBJECT);
+
+ jobj = json_node_get_object(child_node);
+ IF_FAIL_CATCH(jobj);
+ }
+
+ __free_tokenized_path(length, path_token);
+ return jobj;
+
+CATCH:
+ __free_tokenized_path(length, path_token);
+ return NULL;
+}
+
+bool Json::set(const char* path, const char* key, Json& val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key))
+ json_object_remove_member(jobj, key);
+
+ json_object_set_member(jobj, key, val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+bool Json::set(const char* path, const char* key, int val)
+{
+ return set(path, key, static_cast<int64_t>(val));
+}
+
+bool Json::set(const char* path, const char* key, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key))
+ json_object_remove_member(jobj, key);
+
+ json_object_set_int_member(jobj, key, val);
+ return true;
+}
+
+bool Json::set(const char* path, const char* key, double val, int prec)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key)) {
+ json_object_remove_member(jobj, key);
+ }
+
+ //NOTE: Json-glib causes a precision issue while handling double values
+ json_object_set_string_member(jobj, key, __double_to_string(val, prec).c_str());
+ return true;
+}
+
+bool Json::set(const char* path, const char* key, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = __traverse(__jsonNode, path, true);
+ IF_FAIL_RETURN(jobj, false);
+
+ if (json_object_has_member(jobj, key)) {
+ json_object_remove_member(jobj, key);
+ }
+
+ json_object_set_string_member(jobj, key, val.c_str());
+ return true;
+}
+
+bool Json::set(const char* path, const char* key, GVariant *val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ const gchar *type_str = g_variant_get_type_string(val);
+ IF_FAIL_RETURN_TAG(type_str, false, _E, "GVariant manipulation failed");
+
+ json_node_t *node = json_gvariant_serialize(val);
+ IF_FAIL_RETURN_TAG(node, false, _E, "GVariant manipulation failed");
+
+ Json gvar_json;
+ gvar_json.set(NULL, GVAR_TYPES, type_str);
+ json_object_set_member(json_node_get_object(gvar_json.__jsonNode), GVAR_VALUES, node);
+
+ return set(path, key, gvar_json);
+}
+
+bool Json::get(const char* path, const char* key, Json* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonObject *jobj = NULL;
+ JsonNode *node = NULL;
+
+ jobj = __traverse(__jsonNode, path, false);
+ IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), false);
+
+ node = json_object_dup_member(jobj, key);
+ IF_FAIL_RETURN_TAG(node, false, _E, "Memory allocation failed");
+
+ if (val->__jsonNode) {
+ json_node_free(val->__jsonNode);
+ }
+ val->__jsonNode = node;
+
+ return true;
+}
+
+static JsonNode* __search_value_node(JsonNode* jnode, const char* path, const char* key)
+{
+ JsonNode *node = NULL;
+ JsonObject *jobj = NULL;
+ JsonNodeType ntype;
+
+ jobj = __traverse(jnode, path, false);
+ IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), NULL);
+
+ node = json_object_get_member(jobj, key);
+ ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN(ntype == JSON_NODE_VALUE, NULL);
+
+ return node;
+}
+
+bool Json::get(const char* path, const char* key, int* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ int64_t v;
+
+ if (get(path, key, &v)) {
+ *val = v;
+ return true;
+ }
+
+ return false;
+}
+
+bool Json::get(const char* path, const char* key, int64_t* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ //TODO: if the string is not a number?
+ *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::get(const char* path, const char* key, double* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_DOUBLE) {
+ *val = json_node_get_double(node);
+ } else if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ //NOTE: Json-glib causes a precision issue while handling double values
+ *val = __string_to_double(json_node_get_string(node));
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::get(const char* path, const char* key, std::string* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_value_node(__jsonNode, path, key);
+ IF_FAIL_RETURN(node, false);
+
+ GType vtype = json_node_get_value_type(node);
+ IF_FAIL_RETURN(vtype == G_TYPE_STRING, false);
+
+ const char *str_val = json_node_get_string(node);
+ IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+ *val = str_val;
+ return true;
+}
+
+bool Json::get(const char* path, const char* key, GVariant **val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+ bool ret;
+ Json gvar_json;
+ ret = get(path, key, &gvar_json);
+ IF_FAIL_RETURN(ret, false);
+
+ std::string gvar_types;
+ ret = gvar_json.get(NULL, GVAR_TYPES, &gvar_types);
+ IF_FAIL_RETURN(ret, false);
+
+ Json gvar_values;
+ ret = gvar_json.get(NULL, GVAR_VALUES, &gvar_values);
+ IF_FAIL_RETURN(ret, false);
+
+ GError *gerr = NULL;
+ *val = json_gvariant_deserialize(gvar_values.__jsonNode, gvar_types.c_str(), &gerr);
+ HANDLE_GERROR(gerr);
+ IF_FAIL_RETURN(*val, false);
+
+ return true;
+}
+
+static JsonArray* __search_array(JsonNode* jnode, const char* path, const char* key, bool force)
+{
+ JsonNode *node = NULL;
+ JsonArray *arr = NULL;
+ JsonObject *jobj = NULL;
+
+ jobj = __traverse(jnode, path, force);
+ IF_FAIL_RETURN(jobj, NULL);
+
+ if (!json_object_has_member(jobj, key)) {
+ if (force) {
+ arr = json_array_new();
+ IF_FAIL_RETURN_TAG(arr, NULL, _E, "Memory allocation failed");
+ json_object_set_array_member(jobj, key, arr);
+ } else {
+ return NULL;
+ }
+ }
+ node = json_object_get_member(jobj, key);
+ IF_FAIL_RETURN_TAG(node && json_node_get_node_type(node) == JSON_NODE_ARRAY,
+ NULL, _W, "Type mismatched: %s", key);
+
+ return json_node_get_array(node);
+}
+
+int Json::arrayGetSize(const char* path, const char* key)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, -1, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, -1, _E, "Invalid parameter");
+
+ JsonArray *jarr = __search_array(__jsonNode, path, key, false);
+ IF_FAIL_RETURN_TAG(jarr, -1, _D, "Mismatched data type");
+
+ return json_array_get_length(jarr);
+}
+
+bool Json::arrayAppend(const char* path, const char* key, Json& val) {
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val.__jsonNode, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __search_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_element(arr, val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+bool Json::arrayAppend(const char* path, const char* key, int val)
+{
+ return arrayAppend(path, key, static_cast<int64_t>(val));
+}
+
+bool Json::arrayAppend(const char* path, const char* key, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __search_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_int_element(arr, val);
+ return true;
+}
+
+bool Json::arrayAppend(const char* path, const char* key, double val, int prec)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __search_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ //NOTE: Json-glib causes a precision issue while handling double values
+ json_array_add_string_element(arr, __double_to_string(val, prec).c_str());
+ return true;
+}
+
+bool Json::arrayAppend(const char* path, const char* key, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+ JsonArray *arr = __search_array(__jsonNode, path, key, true);
+ IF_FAIL_RETURN(arr, false);
+
+ json_array_add_string_element(arr, val.c_str());
+ return true;
+}
+
+static JsonNode* __search_array_elem(JsonNode* jnode, const char* path, const char* key, int index)
+{
+ JsonArray *jarr = __search_array(jnode, path, key, false);
+ IF_FAIL_RETURN_TAG(jarr, NULL, _W, "Mismatched data type");
+
+ int size = json_array_get_length(jarr);
+ IF_FAIL_RETURN(size > index, NULL);
+
+ JsonNode *node = json_array_get_element(jarr, index);
+ IF_FAIL_RETURN_TAG(node, NULL, _E, "Failed to get an array element");
+
+ return node;
+}
+
+bool Json::arraySetAt(const char* path, const char* key, int index, Json& val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(val.__jsonNode && key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+
+ JsonObject *obj = json_node_get_object(val.__jsonNode);
+ IF_FAIL_RETURN_TAG(obj, false, _E, "Getting object failed");
+
+ json_node_set_object(node, obj);
+ json_node_free(val.__jsonNode);
+ val.__jsonNode = NULL;
+ val = Json();
+
+ return true;
+}
+
+bool Json::arraySetAt(const char* path, const char* key, int index, int val)
+{
+ return arraySetAt(path, key, index, static_cast<int64_t>(val));
+}
+
+bool Json::arraySetAt(const char* path, const char* key, int index, int64_t val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+ IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+
+ json_node_set_int(node, val);
+ return true;
+}
+
+bool Json::arraySetAt(const char* path, const char* key, int index, double val, int prec)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+ IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+
+ json_node_set_string(node, __double_to_string(val, prec).c_str());
+ return true;
+}
+
+bool Json::arraySetAt(const char* path, const char* key, int index, std::string val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+ IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+
+ json_node_set_string(node, val.c_str());
+ return true;
+}
+
+bool Json::getArrayElem(const char* path, const char* key, int index, Json* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNode *node_copy = json_node_copy(node);
+ IF_FAIL_RETURN_TAG(node_copy, false, _E, "Memory allocation failed");
+
+ if (val->__jsonNode) {
+ json_node_free(val->__jsonNode);
+ }
+ val->__jsonNode = node_copy;
+
+ return true;
+}
+
+bool Json::getArrayElem(const char* path, const char* key, int index, int* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ int64_t v;
+ if (getArrayElem(path, key, index, &v)) {
+ *val = v;
+ return true;
+ }
+
+ return false;
+}
+
+bool Json::getArrayElem(const char* path, const char* key, int index, int64_t* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ *val = static_cast<int64_t>(__string_to_double(json_node_get_string(node)));
+ } else {
+ _E("Type mismatched: %s", key);
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::getArrayElem(const char* path, const char* key, int index, double* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ if (vtype == G_TYPE_DOUBLE) {
+ *val = json_node_get_double(node);
+ } else if (vtype == G_TYPE_INT64) {
+ *val = json_node_get_int(node);
+ } else if (vtype == G_TYPE_STRING) {
+ //NOTE: Json-glib causes a precision issue while handling double values
+ *val = __string_to_double(json_node_get_string(node));
+ } else {
+ _E("Type mismatched: %s", key);
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::getArrayElem(const char* path, const char* key, int index, std::string* val)
+{
+ IF_FAIL_RETURN_TAG(this->__jsonNode, false, _E, "Json object not initialized");
+ IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+ JsonNode *node = __search_array_elem(__jsonNode, path, key, index);
+ IF_FAIL_RETURN(node, false);
+
+ JsonNodeType ntype = json_node_get_node_type(node);
+ IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+ GType vtype = json_node_get_value_type(node);
+ IF_FAIL_RETURN_TAG(vtype == G_TYPE_STRING, false, _E, "Type mismatched: %s", key);
+
+ const char *str_val = json_node_get_string(node);
+ IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+ *val = str_val;
+ return true;
+}
+
+bool Json::getMemberList(json_node_t* node, std::list<std::string>& list)
+{
+ IF_FAIL_RETURN(node, false);
+ list.clear();
+
+ JsonObject *jobj = json_node_get_object(node);
+ IF_FAIL_RETURN_TAG(jobj, false, _E, "Getting Json object failed");
+
+ GList *members = json_object_get_members(jobj);
+ IF_FAIL_RETURN(members, true);
+
+ for (GList *it = g_list_first(members); it; it = g_list_next(it)) {
+ const char *key = static_cast<const char*>(it->data);
+ if (!key) {
+ list.clear();
+ g_list_free(members);
+ _E("Member list extraction failed");
+ return false;
+ }
+
+ list.push_back(key);
+ }
+
+ g_list_free(members);
+ return true;
+}
+
+bool Json::getKeys(std::list<std::string>* list)
+{
+ IF_FAIL_RETURN_TAG(list, false, _E, "Invalid parameter");
+ return getMemberList(__jsonNode, *list);
+}
+
+bool Json::nodeEquals(json_node_t* lhs, json_node_t* rhs)
+{
+ IF_FAIL_RETURN(lhs && rhs, false);
+
+ JsonNodeType ltype = json_node_get_node_type(lhs);
+ JsonNodeType rtype = json_node_get_node_type(rhs);
+ IF_FAIL_RETURN(ltype == rtype, false);
+
+ switch (ltype) {
+ case JSON_NODE_VALUE:
+ IF_FAIL_RETURN(valueEquals(lhs, rhs), false);
+ break;
+ case JSON_NODE_OBJECT:
+ IF_FAIL_RETURN(objectEquals(lhs, rhs), false);
+ break;
+ case JSON_NODE_ARRAY:
+ IF_FAIL_RETURN(arrayEquals(lhs, rhs), false);
+ break;
+ default:
+ _W("Unsupported type");
+ return false;
+ }
+
+ return true;
+}
+
+bool Json::valueEquals(json_node_t* lhs, json_node_t* rhs)
+{
+ GType ltype = json_node_get_value_type(lhs);
+ GType rtype = json_node_get_value_type(rhs);
+ IF_FAIL_RETURN(ltype == rtype, false);
+
+ switch (ltype) {
+ case G_TYPE_INT64:
+ return json_node_get_int(lhs) == json_node_get_int(rhs);
+ case G_TYPE_DOUBLE:
+ return json_node_get_double(lhs) == json_node_get_double(rhs);
+ case G_TYPE_STRING:
+ return STR_EQ(json_node_get_string(lhs), json_node_get_string(rhs));
+ default:
+ _W("Unsupported type");
+ return false;
+ }
+}
+
+bool Json::objectEquals(json_node_t* lhs, json_node_t* rhs)
+{
+ std::list<std::string> lm, rm;
+ IF_FAIL_RETURN(getMemberList(lhs, lm), false);
+ IF_FAIL_RETURN(getMemberList(rhs, rm), false);
+ IF_FAIL_RETURN(lm.size() == rm.size(), false);
+
+ lm.sort();
+ rm.sort();
+
+ std::list<std::string>::iterator lit, rit;
+ lit = lm.begin();
+ rit = rm.begin();
+
+ while (lit != lm.end()) {
+ IF_FAIL_RETURN(*lit == *rit, false);
+
+ json_node_t *lhs_child = json_object_get_member(json_node_get_object(lhs), (*lit).c_str());
+ json_node_t *rhs_child = json_object_get_member(json_node_get_object(rhs), (*rit).c_str());
+ IF_FAIL_RETURN(nodeEquals(lhs_child, rhs_child), false);
+
+ ++lit;
+ ++rit;
+ }
+
+ return true;
+}
+
+bool Json::arrayEquals(json_node_t* lhs, json_node_t* rhs)
+{
+ JsonArray *larr = json_node_get_array(lhs);
+ JsonArray *rarr = json_node_get_array(rhs);
+
+ int size = json_array_get_length(larr);
+ IF_FAIL_RETURN(size == static_cast<int>(json_array_get_length(rarr)), false);
+
+ for (int i=0; i < size; ++i) {
+ json_node_t *lhs_child = json_array_get_element(larr, i);
+ json_node_t *rhs_child = json_array_get_element(rarr, i);
+ IF_FAIL_RETURN(nodeEquals(lhs_child, rhs_child), false);
+ }
+
+ return true;
+}
+
+std::string Json::getStr(const char *key)
+{
+ if(!key)
+ return "";
+ std::string str_temp;
+ get(NULL, key, &str_temp);
+ return str_temp;
+}
+
+Json *Json::getJson(const char* key)
+{
+ if(!key)
+ return NULL;
+ Json *j = new Json();
+ if(get(NULL, key, j))
+ return j;
+ delete j;
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 __RRS_JSON_H__
+#define __RRS_JSON_H__
+
+#include <sys/types.h>
+#include <glib.h>
+#include <string>
+#include <list>
+
+#define _J(cmt, jobj) \
+do { \
+ _SD("%s: %s", (cmt), jobj.str().c_str()); \
+} while (0)
+
+#define EMPTY_JSON_OBJECT "{}"
+#define DEFAULT_PRECISION 3
+
+
+class Json {
+public:
+ Json();
+ Json(const char* s);
+ Json(const std::string& s);
+
+ /* This Json(const Json& j) only copies the reference to the underlying Json node.
+ * Therefore, changes applied to a Json object affect the other.
+ * If you need to create a 'real' copy of a Json, which can be manipulated separately,
+ * utilize the str() function, e.g., ctx::Json copy(original.str());
+ */
+ Json(const Json& j);
+
+ ~Json();
+
+ Json& operator=(const char* s);
+ Json& operator=(const std::string& s);
+
+ /* This operator=(const Json& j) only copies the reference to the underlying Json node.
+ * Therefore, changes applied to a Json object affect the other.
+ * If you need to create a 'real' copy of a Json, which can be manipulated separately,
+ * utilize the str() function, e.g., ctx::Json copy = original.str();
+ */
+ Json& operator=(const Json& j);
+
+ bool operator==(const Json& rhs);
+ bool operator!=(const Json& rhs);
+
+ void load(const char *file);
+
+ char* dupCStr();
+ std::string str();
+
+ bool getKeys(std::list<std::string>* list);
+
+ bool set(const char* path, const char* key, Json& val);
+ bool set(const char* path, const char* key, int val);
+ bool set(const char* path, const char* key, int64_t val);
+ bool set(const char* path, const char* key, double val, int prec = DEFAULT_PRECISION);
+ bool set(const char* path, const char* key, std::string val);
+ bool set(const char* path, const char* key, GVariant *val);
+
+ bool get(const char* path, const char* key, Json* val);
+ bool get(const char* path, const char* key, int* val);
+ bool get(const char* path, const char* key, int64_t* val);
+ bool get(const char* path, const char* key, double* val);
+ bool get(const char* path, const char* key, std::string* val);
+ bool get(const char* path, const char* key, GVariant **val);
+
+ int arrayGetSize(const char* path, const char* key);
+
+ bool arrayAppend(const char* path, const char* key, Json& val);
+ bool arrayAppend(const char* path, const char* key, int val);
+ bool arrayAppend(const char* path, const char* key, int64_t val);
+ bool arrayAppend(const char* path, const char* key, double val, int prec = DEFAULT_PRECISION);
+ bool arrayAppend(const char* path, const char* key, std::string val);
+
+ bool arraySetAt(const char* path, const char* key, int index, Json& val);
+ bool arraySetAt(const char* path, const char* key, int index, int val);
+ bool arraySetAt(const char* path, const char* key, int index, int64_t val);
+ bool arraySetAt(const char* path, const char* key, int index, double val, int prec = DEFAULT_PRECISION);
+ bool arraySetAt(const char* path, const char* key, int index, std::string val);
+
+ bool getArrayElem(const char* path, const char* key, int index, Json* val);
+ bool getArrayElem(const char* path, const char* key, int index, int* val);
+ bool getArrayElem(const char* path, const char* key, int index, int64_t* val);
+ bool getArrayElem(const char* path, const char* key, int index, double* val);
+ bool getArrayElem(const char* path, const char* key, int index, std::string* val);
+
+ std::string getStr(const char* key);
+ Json *getJson(const char* key);
+private:
+ typedef struct _JsonNode json_node_t;
+ json_node_t *__jsonNode;
+
+ void parse(const char* s);
+ void release();
+
+ /* For Json vs Json comparison */
+ bool getMemberList(json_node_t* node, std::list<std::string>& list);
+ bool nodeEquals(json_node_t* lhs, json_node_t* rhs);
+ bool valueEquals(json_node_t* lhs, json_node_t* rhs);
+ bool objectEquals(json_node_t* lhs, json_node_t* rhs);
+ bool arrayEquals(json_node_t* lhs, json_node_t* rhs);
+};
+
+
+#endif // __RRS_JSON_H__
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "Mutex.h"
+#include "common.h"
+
+Mutex::Mutex()
+{
+ pthread_mutexattr_t mutex_attr;
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&__mutex, &mutex_attr);
+ pthread_mutexattr_destroy(&mutex_attr);
+}
+
+Mutex::~Mutex()
+{
+ pthread_mutex_destroy(&__mutex);
+}
+
+void Mutex::lock()
+{
+#ifdef _LOCK_DEBUG
+ BaseLock::lock(LOCK_TYPE_MUTEX, "mutex", __MODULE__, __func__, __LINE__);
+#else
+ BaseLock::lock(LOCK_TYPE_MUTEX);
+#endif
+}
+
+void Mutex::lock(const char* expr, const char *module, const char *func, int line)
+{
+ BaseLock::lock(LOCK_TYPE_MUTEX, expr, module, func, line);
+}
+
+int Mutex::lockImpl(void)
+{
+ return pthread_mutex_lock(&__mutex);
+}
+
+int Mutex::tryLockImpl(void)
+{
+ return pthread_mutex_trylock(&__mutex);
+}
+
+int Mutex::unlockImpl()
+{
+ return pthread_mutex_unlock(&__mutex);
+}
--- /dev/null
+/*
+ * IOT_Broker_Service
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#if !defined(_RRS_MUTEX_H_)
+#define _RRS_MUTEX_H_
+
+#include "BaseLock.h"
+
+class Mutex : public BaseLock {
+public:
+ Mutex();
+ virtual ~Mutex();
+
+ void lock(void);
+ void lock(const char* expr, const char *module, const char *func, int line);
+
+protected:
+ int lockImpl(void);
+ int tryLockImpl(void);
+ int unlockImpl();
+private:
+ pthread_mutex_t __mutex;
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 <stdio.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <dlog.h>
+#include "common.h"
+
+#ifndef EXTAPI
+#define EXTAPI __attribute__((visibility("default")))
+#endif
+
+#define IOT_SERVER_MSG_LOG_FILE "/var/log/messages"
+#define FILE_LENGTH 255
+
+static int iot_debug_file_fd;
+static char iot_debug_file_buf[FILE_LENGTH];
+
+EXTAPI void iot_log(int type , int priority , const char *tag , const char *fmt , ...)
+{
+ va_list ap;
+ ssize_t len;
+ ssize_t total_sent_size = 0;
+ va_start(ap, fmt);
+
+ switch (type) {
+ case IOT_LOG_PRINT_FILE:
+ iot_debug_file_fd = open(IOT_SERVER_MSG_LOG_FILE, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ if (iot_debug_file_fd != -1) {
+ vsnprintf(iot_debug_file_buf, 255, fmt , ap);
+ do {
+ len = write(iot_debug_file_fd, iot_debug_file_buf, strlen(iot_debug_file_buf));
+ if (len >= 0) {
+ total_sent_size += len;
+ }
+ } while (total_sent_size < FILE_LENGTH);
+
+ close(iot_debug_file_fd);
+ }
+ break;
+
+ case IOT_LOG_SYSLOG:
+ int syslog_prio;
+ switch (priority) {
+ case IOT_LOG_ERR:
+ syslog_prio = LOG_ERR|LOG_DAEMON;
+ break;
+
+ case IOT_LOG_WARN:
+ syslog_prio = LOG_WARNING|LOG_DAEMON;
+ break;
+
+ case IOT_LOG_DBG:
+ syslog_prio = LOG_DEBUG|LOG_DAEMON;
+ break;
+
+ case IOT_LOG_INFO:
+ syslog_prio = LOG_INFO|LOG_DAEMON;
+ break;
+
+ default:
+ syslog_prio = priority;
+ break;
+ }
+
+ vsyslog(syslog_prio, fmt, ap);
+ break;
+
+ case IOT_LOG_DLOG:
+ if (tag) {
+ switch (priority) {
+ case IOT_LOG_ERR:
+ SLOG_VA(LOG_ERROR, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap);
+ break;
+
+ case IOT_LOG_WARN:
+ SLOG_VA(LOG_WARN, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap);
+ break;
+
+ case IOT_LOG_DBG:
+ SLOG_VA(LOG_DEBUG, tag ? tag : "NULL", fmt ? fmt : "NULL" , ap);
+ break;
+
+ case IOT_LOG_INFO:
+ SLOG_VA(LOG_INFO, tag ? tag : "NULL" , fmt ? fmt : "NULL" , ap);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ va_end(ap);
+}
+
+bool get_proc_name(pid_t pid, char *process_name)
+{
+ FILE *fp;
+ char buf[NAME_MAX];
+ char filename[PATH_MAX];
+
+ sprintf(filename, "/proc/%d/stat", pid);
+ fp = fopen(filename, "r");
+
+ if (fp == NULL)
+ return false;
+
+ if (fscanf(fp, "%*s (%[^)]", buf) < 1) {
+ fclose(fp);
+ return false;
+ }
+
+ strncpy(process_name, buf, NAME_MAX-1);
+ process_name[NAME_MAX-1] = '\0';
+ fclose(fp);
+
+ return true;
+}
+
+const char* get_client_name(void)
+{
+ const int pid_string_size = 10;
+ static pid_t pid = -1;
+ static char client_name[NAME_MAX + pid_string_size];
+ char proc_name[NAME_MAX];
+
+ if (pid == -1) {
+ pid = getpid();
+ get_proc_name(pid, proc_name);
+ snprintf(client_name, sizeof(client_name), "%s(%d)", proc_name, pid);
+ }
+
+ return client_name;
+}
--- /dev/null
+/*
+ * IOT_Broker_Service
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#if !defined(_COMMON_H_)
+#define _COMMON_H_
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif /* !__cplusplus */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#define MAX_RRS_HANDLE 1000
+
+/**
+ * @brief URI prefix for discovery resource
+ * @since_tizen 3.0
+ */
+#define DISCOVERY_RESOURCE_URI_PREFIX "/rrsdiscovery"
+
+/**
+ * @brief Name of discovery resource
+ * @since_tizen 3.0
+ */
+
+#define DISCOVERY_RESOURCE_NAME "x.org.tizen.rrsdiscovery"
+
+/**
+ * @brief URI prefix for accelerometer sensor
+ * @since_tizen 3.0
+ */
+#define ACCELEROMETER_RESOURCE_URI_PREFIX "/accelerometer"
+
+/**
+ * @brief Type of accelerometer sensor resource
+ * @since_tizen 3.0
+ */
+#define ACCELEROMETER_RESOURCE_NAME "x.org.tizen.accelerometer"
+
+/**
+ * @brief URI prefix for proximity sensor
+ * @since_tizen 3.0
+ */
+#define PROXIMITY_RESOURCE_URI_PREFIX "/proximity"
+
+/**
+ * @brief Type of proximity sensor resource
+ * @since_tizen 3.0
+ */
+#define PROXIMITY_RESOURCE_NAME "x.org.tizen.proximity"
+
+
+#if !defined(PATH_MAX)
+#define PATH_MAX 256
+#endif
+
+#if !defined(NAME_MAX)
+#define NAME_MAX 256
+#endif
+
+enum IotLogType {
+ IOT_LOG_PRINT_FILE = 1,
+ IOT_LOG_SYSLOG = 2,
+ IOT_LOG_DLOG = 3,
+};
+
+enum IotPriorityType {
+ IOT_LOG_ERR = 1,
+ IOT_LOG_DBG = 2,
+ IOT_LOG_INFO = 3,
+ IOT_LOG_WARN = 4,
+};
+
+void iot_log(int type , int priority , const char *tag , const char *fmt , ...);
+
+#define MICROSECONDS(tv) ((tv.tv_sec * 1000000ll) + tv.tv_usec)
+
+#ifndef __MODULE__
+#include <string.h>
+#define __MODULE__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+
+//for new log system - dlog
+#ifdef LOG_TAG
+ #undef LOG_TAG
+#endif
+#define LOG_TAG "REMOTE_RESOURCE_SERVICE"
+
+#if defined(_DEBUG) || defined(USE_FILE_DEBUG)
+
+#define DbgPrint(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , " [IOT_MSG_PRT][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+
+#endif
+
+#if defined(USE_SYSLOG_DEBUG)
+
+#define ERR(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define WARN(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define INFO(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define DBG(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+
+#define _E(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _W(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _I(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _D(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _T(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+
+
+#elif defined(_DEBUG) || defined(USE_DLOG_DEBUG)
+
+#define ERR(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define WARN(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define INFO(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define DBG(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+
+#define _E(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _W(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _I(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _D(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _T(fmt, arg...) do { iot_log(IOT_LOG_SYSLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+
+#elif defined(USE_FILE_DEBUG)
+
+#define ERR(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG, "[IOT_MSG_ERR][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define WARN(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG, "[IOT_MSG_WARN][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define DBG(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG, "[IOT_MSG_DBG][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define INFO(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG, "[IOT_MSG_INFO][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+
+#define _E(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , "[IOT_MSG_ERR][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define _W(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , "[IOT_MSG_WARN][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define _I(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , "[IOT_MSG_INFO][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define _D(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , "[IOT_MSG_DBG][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+#define _T(fmt, arg...) do { iot_log(IOT_LOG_PRINT_FILE, 0, LOG_TAG , "[IOT_MSG_TEMP][%s:%d] " fmt"\n", __MODULE__, __LINE__, ##arg); } while (0)
+
+#elif defined(USE_DLOG_LOG)
+
+#define ERR(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define WARN(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define INFO(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+
+#define DBG(...) do {} while (0)
+#define DbgPrint(...) do {} while (0)
+
+
+#define _E(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _W(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_WARN, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _I(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_INFO, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _D(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_DBG, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _T(...)
+
+#else
+#define ERR(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define WARN(...) do {} while (0)
+#define DbgPrint(...) do {} while (0)
+#define DBG(...) do {} while (0)
+#define INFO(...) do {} while (0)
+
+#define _E(fmt, arg...) do { iot_log(IOT_LOG_DLOG, IOT_LOG_ERR, LOG_TAG, "%s:%s(%d)> " fmt, __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define _W(...) do {} while (0)
+#define _I(...) do {} while (0)
+#define _D(...) do {} while (0)
+#define _T(...) do {} while (0)
+
+#endif
+
+
+#if defined(_DEBUG)
+# define WARN_IF(expr, fmt, arg...) do { \
+ if(expr) { \
+ DBG("(%s) -> " fmt, #expr, ##arg); \
+ } \
+ } while (0)
+# define RET_IF(expr) do { \
+ if(expr) { \
+ DBG("(%s) -> %s() return", #expr, __FUNCTION__); \
+ return; \
+ } \
+ } while (0)
+# define RETV_IF(expr, val) do { \
+ if(expr) { \
+ DBG("(%s) -> %s() return", #expr, __FUNCTION__); \
+ return (val); \
+ } \
+ } while (0)
+# define RETM_IF(expr, fmt, arg...) do { \
+ if(expr) { \
+ ERR(fmt, ##arg); \
+ DBG("(%s) -> %s() return", #expr, __FUNCTION__); \
+ return; \
+ } \
+ } while (0)
+# define RETVM_IF(expr, val, fmt, arg...) do { \
+ if(expr) { \
+ ERR(fmt, ##arg); \
+ DBG("(%s) -> %s() return", #expr, __FUNCTION__); \
+ return (val); \
+ } \
+ } while (0)
+
+#else
+# define WARN_IF(expr, fmt, arg...) do { \
+ if(expr) { \
+ ERR(fmt, ##arg); \
+ } \
+ } while (0)
+# define RET_IF(expr) do { \
+ if(expr) { \
+ return; \
+ } \
+ } while (0)
+# define RETV_IF(expr, val) do { \
+ if(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)
+
+#endif
+
+const char* get_client_name(void);
+bool get_proc_name(pid_t pid, char *process_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2016 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 <glib.h>
+#include "rrs.h"
+#include "Mutex.h"
+#include "common.h"
+#include "tzplatform_config.h"
+
+extern bool __has_iot_privilege();
+
+static bool handle_array[MAX_RRS_HANDLE] = {false};
+static Mutex m_mutex;
+
+#define RRS_SECURITY_FILEPATH tzplatform_mkpath(TZ_USER_SHARE, "rrs/rrs-svr-db.dat")
+
+EXPORT_API int rrs_create(rrs_h *rrs)
+{
+ int ret;
+ int value = 1;
+
+ /* Check if parameters are valid */
+ if (!rrs)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ {
+ AUTOLOCK(m_mutex);
+ while (handle_array[value] == true)
+ value++;
+
+ *rrs = value;
+ handle_array[value] = true;
+ }
+
+ if (*rrs > MAX_RRS_HANDLE) {
+ ERR("Maximum limit for RRS handles reached");
+ return RRS_ERROR_SERVICE_NOT_AVAILABLE;
+ }
+
+ INFO("Path: %s", RRS_SECURITY_FILEPATH);
+
+ /* connect iotcon */
+ ret = iotcon_initialize(RRS_SECURITY_FILEPATH);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_initialize() Fail(%d)", ret);
+ return RRS_ERROR_SERVICE_NOT_AVAILABLE;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_destroy(const rrs_h rrs)
+{
+ /* Check if RRS handle is valid */
+ if (rrs < 1 || rrs > MAX_RRS_HANDLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if privileges enough */
+ if (!__has_iot_privilege())
+ return RRS_ERROR_PERMISSION_DENIED;
+
+ {
+ AUTOLOCK(m_mutex);
+ handle_array[rrs] = false;
+ }
+
+ /* disconnect iotcon */
+ iotcon_deinitialize();
+
+ return RRS_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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 <glib.h>
+#include <string>
+#include "rrs.h"
+#include <cynara-client.h>
+#include <cynara-error.h>
+
+#define SMACK_LABEL_LEN 255
+static const char *RRS_PRIVILEGE_HEALTH_INFO = "http://tizen.org/privilege/healthinfo";
+
+bool __has_iot_privilege()
+{
+ static int has_health_info_permission = -1;
+
+ if (has_health_info_permission == -1) {
+ int ret;
+ char smack_label[SMACK_LABEL_LEN + 1] = {0};
+ char uid[10];
+ FILE *fd;
+ cynara *cynara_h;
+
+ ret = cynara_initialize(&cynara_h, NULL);
+ if (CYNARA_API_SUCCESS != ret) {
+ ERR("cynara_initialize() Fail(%d)", ret);
+ return false;
+ }
+
+ fd = fopen("/proc/self/attr/current", "r");
+ if (NULL == fd) {
+ ERR("fopen() Fail(%d)", errno);
+ return false;
+ }
+
+ ret = fread(smack_label, sizeof(smack_label), 1, fd);
+ fclose(fd);
+ if (ret < 0) {
+ ERR("fread() Fail(%d)", ret);
+ return 0;
+ }
+
+ snprintf(uid, sizeof(uid), "%d", getuid());
+
+ ret = cynara_check(cynara_h, smack_label, "", uid, RRS_PRIVILEGE_HEALTH_INFO);
+ if (CYNARA_API_ACCESS_ALLOWED == ret)
+ has_health_info_permission = 1;
+ else
+ has_health_info_permission = 0;
+
+ cynara_finish(cynara_h);
+ }
+
+ if (has_health_info_permission != 1) {
+ ERR("Don't have http://tizen.org/privilege/healthinfo");
+ return false;
+ }
+
+ return true;
+}
+
+std::string _rrs_get_schema_system_folder()
+{
+ return "/usr/lib/rrs/schemas/";
+}
+
+void _rrs_get_discovery_schema_system_path(const rrs_resource_e resource_id, std::string &discovery_schema)
+{
+ static std::string base_path = _rrs_get_schema_system_folder();
+ switch(resource_id) {
+ case RRS_RESOURCE_DISCOVERY:
+ discovery_schema = base_path + "rrsdiscovery.json";
+ break;
+ default: /* TODO */
+ discovery_schema = "";
+ }
+}
+
+void _rrs_get_schema_system_path(const rrs_resource_e resource_id, std::string &service_schema, std::string &resource_schema)
+{
+ static std::string base_path = _rrs_get_schema_system_folder();
+ switch(resource_id) {
+ case RRS_RESOURCE_ACCELEROMETER:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "accelerometer.json";
+ break;
+ case RRS_RESOURCE_PROXIMITY:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "proximity.json";
+ break;
+ case RRS_RESOURCE_AUTO_ROTATION:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "autorotation.json";
+ break;
+ case RRS_RESOURCE_HRM:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "hrm.json";
+ break;
+ case RRS_RESOURCE_HRM_LED_GREEN:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "hrmledgreen.json";
+ break;
+ case RRS_RESOURCE_HRM_LED_RED:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "hrmledred.json";
+ break;
+ case RRS_RESOURCE_HRM_LED_IR:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "hrmledir.json";
+ break;
+ case RRS_RESOURCE_GYROSCOPE:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "gyroscope.json";
+ break;
+ case RRS_RESOURCE_MAGNETOMETER:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "magnetometer.json";
+ break;
+ case RRS_RESOURCE_LIGHT:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "light.json";
+ break;
+ case RRS_RESOURCE_PRESSURE:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "pressure.json";
+ break;
+ case RRS_RESOURCE_TEMPERATURE:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "temperature.json";
+ break;
+ case RRS_RESOURCE_HUMIDITY:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "humidity.json";
+ break;
+ case RRS_RESOURCE_UV:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "uv.json";
+ break;
+ case RRS_RESOURCE_ORIENTATION:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "orientation.json";
+ break;
+ case RRS_RESOURCE_GRAVITY:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "gravity.json";
+ break;
+ case RRS_RESOURCE_LINEAR_ACCELERATION:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "linearacceleration.json";
+ break;
+ case RRS_RESOURCE_ROTATION_VECTOR:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "rotationvector.json";
+ break;
+ case RRS_RESOURCE_GYROSCOPE_ROTATION_VECTOR:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "gyroscoperotationvector.json";
+ break;
+ case RRS_RESOURCE_GEOMAGNETIC_ROTATION_VECTOR:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "geomagneticrotationvector.json";
+ break;
+ case RRS_RESOURCE_UNCALIBRATED_GYROSCOPE:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "uncalibratedgyroscope.json";
+ break;
+ case RRS_RESOURCE_UNCALIBRATED_MAGNETOMETER:
+ service_schema = base_path + "sensorcontrol.json";
+ resource_schema = base_path + "uncalibratedmagnetometer.json";
+ break;
+ default:
+ service_schema = "";
+ resource_schema = "";
+ }
+}
+
+std::string _rrs_get_schema_custom_path(const char *schema_name)
+{
+ static std::string base_path = _rrs_get_schema_system_folder();
+ return base_path + schema_name;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "rrs.h"
+#include <glib.h>
+#include <unordered_map>
+#include <memory>
+#include "schema.h"
+#include "Json.h"
+
+EXPORT_API int rrs_control_data_create(const rrs_resource_e type,
+ rrs_control_data_h *data)
+{
+ rrs_schema_h control_schema;
+ if (type != RRS_RESOURCE_DISCOVERY) {
+ rrs_schema_h event_schema;
+ if (rrs_schema_load(type, &control_schema, &event_schema) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_load() failed");
+ return RRS_ERROR_INVALID_TYPE;
+ }
+
+ if (rrs_schema_destroy(event_schema)) {
+ ERR("rrs_schema_destroy() Fail(%d)");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ if (rrs_discovery_schema_load(type, &control_schema) != RRS_ERROR_NONE) {
+ ERR("rrs_discovery_schema_load() failed");
+ return RRS_ERROR_INVALID_TYPE;
+ }
+ }
+
+ if (rrs_schema_create_data(control_schema, data) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() Fail(%d)");
+ rrs_schema_destroy(control_schema);
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (rrs_schema_destroy(control_schema)) {
+ ERR("rrs_schema_destroy() Fail(%d)");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_destroy(rrs_control_data_h data)
+{
+ /* Check if data handle is valid */
+ if (data)
+ rrs_data_destroy(data);
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_clone(const rrs_control_data_h origin, rrs_control_data_h *cloned)
+{
+ if (rrs_data_clone(origin, cloned) != RRS_ERROR_NONE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_set_bool(rrs_control_data_h data, const char *name, const bool value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_bool(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_control_data_set_int(rrs_control_data_h data, const char *name, const int value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_int(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_set_double(rrs_control_data_h data, const char *name, const double value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_double(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_set_string(rrs_control_data_h data, const char *name, const char *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_string(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_get_bool(rrs_control_data_h data, const char *name, bool *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_bool(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_get_int(rrs_control_data_h data, const char *name, int *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_int(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_get_double(rrs_control_data_h data, const char *name, double *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_double(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_control_data_get_string(rrs_control_data_h data, const char *name, char **value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_string(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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 "rrs.h"
+#include <glib.h>
+#include <unordered_map>
+#include <memory>
+#include "schema.h"
+#include "Json.h"
+
+EXPORT_API int rrs_event_data_create(const rrs_resource_e type,
+ rrs_event_data_h *data)
+{
+ rrs_schema_h control_schema = NULL;
+ rrs_schema_h event_schema = NULL;
+
+ if (rrs_schema_load(type, &control_schema, &event_schema) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_load() failed");
+ return RRS_ERROR_INVALID_TYPE;
+ }
+
+ if (rrs_schema_create_data(event_schema, data) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() Fail(%d)");
+ rrs_schema_destroy(event_schema);
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (rrs_schema_destroy(control_schema)) {
+ ERR("rrs_schema_destroy() Fail(%d)");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ if (rrs_schema_destroy(event_schema)) {
+ ERR("rrs_schema_destroy() Fail(%d)");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_destroy(rrs_event_data_h data)
+{
+ /* Check if data handle is valid */
+ if (data)
+ rrs_data_destroy(data);
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_clone(const rrs_event_data_h origin, rrs_event_data_h *cloned)
+{
+ if (rrs_data_clone(origin, cloned) != RRS_ERROR_NONE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_set_bool(rrs_event_data_h data, const char *name, const bool value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_bool(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+EXPORT_API int rrs_event_data_set_int(rrs_event_data_h data, const char *name, const int value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_int(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_set_double(rrs_event_data_h data, const char *name, const double value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_double(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_set_string(rrs_event_data_h data, const char *name, const char *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_set_string(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_get_bool(rrs_event_data_h data, const char *name, bool *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_bool(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_get_int(rrs_event_data_h data, const char *name, int *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_int(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_get_double(rrs_event_data_h data, const char *name, double *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_double(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
+
+
+EXPORT_API int rrs_event_data_get_string(rrs_event_data_h data, const char *name, char **value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ if (rrs_data_get_string(data, name, value))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ return RRS_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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 <glib.h>
+#include <unordered_map>
+#include <memory>
+#include "rrs.h"
+#include "schema.h"
+#include "Json.h"
+
+extern bool __has_iot_privilege();
+
+extern void _rrs_get_schema_system_path(const rrs_resource_e resource_id, std::string &service_schema, std::string &resource_schema);
+extern void _rrs_get_discovery_schema_system_path(const rrs_resource_e resource_id, std::string &discovery_schema);
+extern std::string _rrs_get_schema_custom_path(const char *schema_name);
+static int _rrs_schema_clone(const rrs_schema_h origin, rrs_schema_h *cloned);
+
+/*----------------------------------------------------------------------------*/
+
+typedef struct _rrs_schema_field_s {
+ RrsSchemaType type;
+ RrsSchemaAccess access;
+ bool required;
+ rrs_schema_h complex_schema;
+} rrs_schema_field_s;
+
+static rrs_schema_field_s *__rrs_schema_field_create()
+{
+ return g_new0(rrs_schema_field_s, 1);
+}
+
+static void __rrs_schema_field_destroy(gpointer data)
+{
+ rrs_schema_field_s *f = (rrs_schema_field_s *)data;
+ if(f && f->complex_schema)
+ rrs_schema_destroy(f->complex_schema);
+ g_free(data);
+}
+
+static rrs_schema_field_s *__rrs_schema_field_create_complete(
+ RrsSchemaType type,
+ RrsSchemaAccess access,
+ bool required,
+ rrs_schema_h complex_schema)
+{
+ rrs_schema_field_s *f = __rrs_schema_field_create();
+ f->type = type;
+ f->access = access;
+ f->required = required;
+ f->complex_schema = complex_schema;
+ return f;
+}
+
+static rrs_schema_field_s *__rrs_schema_field_clone(rrs_schema_field_s *origin)
+{
+ if (!origin)
+ return NULL;
+ rrs_schema_h complex_schema = NULL;
+ if(origin->complex_schema)
+ _rrs_schema_clone(origin->complex_schema, &complex_schema);
+ return __rrs_schema_field_create_complete(origin->type,
+ origin->access,
+ origin->required,
+ complex_schema);
+}
+
+static GHashTable *__rrs_create_schema_field_table()
+{
+ return g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ g_free,
+ __rrs_schema_field_destroy);
+}
+
+static void __rrs_destroy_schema_field_table(GHashTable *t)
+{
+ g_hash_table_unref(t);
+}
+
+static void __rrs_clone_schema_field_table(GHashTable *origin,
+ GHashTable **cloned)
+{
+ if(!origin || !cloned)
+ return;
+
+ if(*cloned)
+ __rrs_destroy_schema_field_table(*cloned);
+ *cloned = __rrs_create_schema_field_table();
+
+ GHashTableIter iter;
+ gpointer key = NULL;
+ gpointer value = NULL;
+ g_hash_table_iter_init(&iter, origin);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (!value)
+ continue;
+ g_hash_table_insert(*cloned, g_strdup((char*)key),
+ __rrs_schema_field_clone((rrs_schema_field_s *)value));
+ }
+}
+
+/*----------------------------------------------------------------------------*/
+
+typedef struct _rrs_value_item_s {
+ RrsSchemaType type;
+ void *item;
+} rrs_value_item_s;
+
+static rrs_value_item_s *__rrs_value_item_create(const RrsSchemaType type,
+ void *item);
+static void __rrs_value_item_destroy(gpointer data);
+
+static void *__rrs_value_alloc(const RrsSchemaType type)
+{
+ switch (type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ return NULL;
+ case RRS_SCHEMA_TYPE_BOOL:
+ return g_slice_new0(bool);
+ case RRS_SCHEMA_TYPE_INT:
+ return g_slice_new0(int);
+ case RRS_SCHEMA_TYPE_DOUBLE:
+ return g_slice_new0(double);
+ case RRS_SCHEMA_TYPE_STR:
+ return g_slice_new0(char *);
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ return __rrs_value_item_create(type, NULL); /* TODO: add hierarchy */
+ default:
+ return NULL;
+ }
+}
+
+static void __rrs_value_free(const RrsSchemaType type, void *ptr)
+{
+ switch (type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ break;
+ case RRS_SCHEMA_TYPE_BOOL:
+ g_slice_free(bool, ptr);
+ break;
+ case RRS_SCHEMA_TYPE_INT:
+ g_slice_free(int, ptr);
+ break;
+ case RRS_SCHEMA_TYPE_DOUBLE:
+ g_slice_free(double, ptr);
+ break;
+ case RRS_SCHEMA_TYPE_STR:
+ g_slice_free(char *, ptr);
+ break;
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ __rrs_value_item_destroy(ptr);
+ break;
+ default:
+ break;
+ }
+}
+
+static rrs_value_item_s *__rrs_value_item_create(const RrsSchemaType type,
+ void *item)
+{
+ rrs_value_item_s *i = g_new0(rrs_value_item_s, 1);
+ i->type = type;
+ i->item = item;
+ return i;
+}
+
+static void __rrs_value_item_destroy(gpointer data)
+{
+ rrs_value_item_s *i = (rrs_value_item_s *)data;
+ if (i && i->item) {
+ if(i->type == RRS_SCHEMA_TYPE_COMPLEX)
+ __rrs_value_item_destroy(i->item);
+ else
+ __rrs_value_free(i->type, i->item);
+ }
+ g_free(i);
+}
+
+static rrs_value_item_s *__rrs_value_item_clone(rrs_value_item_s *origin)
+{
+ if (!origin)
+ return NULL;
+
+ rrs_value_item_s *clone = __rrs_value_item_create(origin->type,
+ __rrs_value_alloc(origin->type));
+ switch(origin->type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ break;
+ case RRS_SCHEMA_TYPE_BOOL:
+ *((bool *)clone->item) = *((bool *)origin->item);
+ break;
+ case RRS_SCHEMA_TYPE_INT:
+ *((int *)clone->item) = *((int *)origin->item);
+ break;
+ case RRS_SCHEMA_TYPE_DOUBLE:
+ *((double *)clone->item) = *((double *)origin->item);
+ break;
+ case RRS_SCHEMA_TYPE_STR:
+ clone->item = g_strdup((char *)origin->item);
+ break;
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ /* TODO: support complex hierarchical type */
+ break;
+ default:
+ ERR("Undefined type while clonning");
+ break;
+ }
+ return clone;
+}
+
+static GHashTable *__rrs_create_value_table()
+{
+ return g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ g_free,
+ __rrs_value_item_destroy);
+}
+
+static void __rrs_destroy_value_table(GHashTable *t)
+{
+ g_hash_table_unref(t);
+}
+
+static bool __rrs_value_has_field(rrs_data_h data,
+ const char *field_name)
+{
+ GHashTable *t = (GHashTable *)data;
+ return g_hash_table_contains(t, field_name);
+}
+
+static rrs_value_item_s *__rrs_value_lookup_field(rrs_data_h data,
+ const char *field_name)
+{
+ GHashTable *t = (GHashTable *)data;
+ return (rrs_value_item_s *)g_hash_table_lookup(t, field_name);
+}
+
+/*----------------------------------------------------------------------------*/
+
+
+typedef struct _rrs_schema_s {
+ rrs_resource_e resource;
+ char *name;
+ char *title;
+ char *file;
+ GHashTable *fields;
+} rrs_schema_s;
+
+const gsize _RRS_SCHEMA_NAME_MAX_LENGTH = 128;
+const gsize _RRS_SCHEMA_TITLE_MAX_LENGTH = 128;
+const gsize _RRS_SCHEMA_FILE_MAX_LENGTH = 128;
+
+
+
+RrsSchemaType _rrs_schema_get_type(const std::string &t)
+{
+ if(t == "bool")
+ return RRS_SCHEMA_TYPE_BOOL;
+ if(t == "integer")
+ return RRS_SCHEMA_TYPE_INT;
+ if(t == "double")
+ return RRS_SCHEMA_TYPE_DOUBLE;
+ if(t == "string")
+ return RRS_SCHEMA_TYPE_STR;
+ if(t == "object")
+ return RRS_SCHEMA_TYPE_COMPLEX;
+
+ /* TODO: WARNING: unsupported type */
+ /*_E("Unknown schema field type");*/
+ return RRS_SCHEMA_TYPE_NONE;
+}
+
+RrsSchemaAccess _rrs_schema_get_access(const std::string &a)
+{
+ if(a == "R")
+ return RRS_SCHEMA_ACCESS_READ;
+ if(a == "W")
+ return RRS_SCHEMA_ACCESS_WRITE;
+ if(a == "RW")
+ return RRS_SCHEMA_ACCESS_READ_WRITE;
+
+ /* TODO: WARNING: unsupported access */
+ /*_E("Unknown schema field access");*/
+ return RRS_SCHEMA_ACCESS_NONE;
+}
+
+/*--------------------------------------------------------------------------=-*/
+
+static bool __rrs_schema_trace_foreach_field_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ const rrs_schema_h schema,
+ void *user_data)
+{
+ std::string s_type;
+ switch(type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ s_type = "NONE";
+ break;
+ case RRS_SCHEMA_TYPE_BOOL:
+ s_type = "BOOL";
+ break;
+ case RRS_SCHEMA_TYPE_INT:
+ s_type = "INT";
+ break;
+ case RRS_SCHEMA_TYPE_DOUBLE:
+ s_type = "DOUBLE";
+ break;
+ case RRS_SCHEMA_TYPE_STR:
+ s_type = "STR";
+ break;
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ s_type = "COMPLEX";
+ break;
+ default:
+ s_type = "UNKNOWN";
+ break;
+ }
+
+ std::string s_access;
+ switch(access) {
+ case RRS_SCHEMA_ACCESS_NONE:
+ s_access = "NONE";
+ break;
+ case RRS_SCHEMA_ACCESS_READ:
+ s_access = "R";
+ break;
+ case RRS_SCHEMA_ACCESS_WRITE:
+ s_access = "W";
+ break;
+ case RRS_SCHEMA_ACCESS_READ_WRITE:
+ s_access = "RW";
+ break;
+ default:
+ s_access = "UNKNOWN";
+ break;
+ }
+
+ std::string s_required = (required) ? "required" : "not required";
+
+ _I("[%d/%d] %s:%s:%s:%s", index, total,
+ name, s_type.c_str(), s_access.c_str(), s_required.c_str());
+ return true;
+}
+
+void _dbg_trace_schema(const rrs_schema_h schema)
+{
+ _I("\n\nTracing schema %p [idx/total] name:type:access:required\n\n",
+ schema);
+ rrs_schema_foreach_field(schema,
+ __rrs_schema_trace_foreach_field_cb,
+ NULL);
+ _I("\n---------------------------------------\n\n");
+}
+
+static bool __rrs_data_trace_foreach_field_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *value,
+ void *user_data)
+{
+ switch(type) {
+ case RRS_SCHEMA_TYPE_NONE:
+ _I("[%d/%d] %s:NONE:NONE", index, total, name);
+ break;
+ case RRS_SCHEMA_TYPE_BOOL: {
+ bool *b = (bool *)value;
+ std::string s = (*b) ? "true" : "false";
+ _I("[%d/%d] %s:BOOL:%s", index, total, name, s.c_str());
+ break;
+ }
+ case RRS_SCHEMA_TYPE_INT: {
+ int *i = (int *)value;
+ char *s = g_strdup_printf("%i", *i);
+ _I("[%d/%d] %s:INT:%s", index, total, name, s);
+ free(s);
+ break;
+ }
+ case RRS_SCHEMA_TYPE_DOUBLE: {
+ double *d = (double *)value;
+ char *s = g_strdup_printf("%f", *d);
+ _I("[%d/%d] %s:DOUBLE:%s", index, total, name, s);
+ free(s);
+ break;
+ }
+ case RRS_SCHEMA_TYPE_STR: {
+ char *s = (char *)value;
+ _I("[%d/%d] %s:STRING:%s", index, total, name, s);
+ break;
+ }
+ case RRS_SCHEMA_TYPE_COMPLEX:
+ _I("[%d/%d] %s:COMPLEX:%p", index, total, name, value);
+ break;
+ default:
+ _I("[%d/%d] %s:UNKNOWN:%p", index, total, name, value);
+ break;
+ }
+
+ return true;
+}
+
+void _dbg_trace_data(const rrs_data_h data, const rrs_schema_h schema)
+{
+ _I("\n\nTracing data %p [idx/total] name:type:value\n\n",
+ data);
+ rrs_data_foreach_field(data,
+ schema,
+ __rrs_data_trace_foreach_field_cb,
+ NULL);
+ _I("\n---------------------------------------\n\n");
+}
+
+void _dbg_trace_data_content(const rrs_data_h data)
+{
+ GHashTable *t = (GHashTable *)data;
+ GHashTableIter iter;
+ gpointer key = NULL;
+ gpointer value = NULL;
+ const int total = g_hash_table_size(t);
+ int index = 0;
+ g_hash_table_iter_init(&iter, t);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (!key || !value)
+ continue;
+
+ const char *fld_name = (const char *)key;
+ rrs_schema_field_s *field = (rrs_schema_field_s *)value;
+
+ if (!__rrs_value_has_field(data, fld_name))
+ continue;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, fld_name);
+ if (!i)
+ continue;
+ _I("%d/%d: %s, %d, %d, %d, %p",
+ index ++, total,
+ fld_name,
+ field->type,
+ field->access,
+ field->required,
+ i->item);
+ }
+}
+/*--------------------------------------------------------------------------=-*/
+
+int rrs_schema_create(const char *name,
+ rrs_schema_h *schema)
+{
+ /* Check if parameters are valid */
+ if (!schema || !name)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ *schema = (rrs_schema_h) g_slice_new0(rrs_schema_s);
+
+ if (*schema == NULL) {
+ ERR("Out of memory");
+ return RRS_ERROR_OUT_OF_MEMORY;
+ }
+
+ /* Initialize schema data */
+ rrs_schema_s *s = (rrs_schema_s *)(*schema);
+ s->resource = RRS_RESOURCE_NONE;
+ s->name = g_strndup(name, _RRS_SCHEMA_NAME_MAX_LENGTH);
+ s->fields = __rrs_create_schema_field_table();
+
+ /* TODO: register in RRS */
+
+ return RRS_ERROR_NONE;
+}
+
+
+rrs_schema_h _rrs_schema_init_from_json(Json *j)
+{
+ /* Instantiate schema */
+ /* TODO: check if schema with this ID already exists */
+ rrs_schema_h schema = NULL;
+ rrs_schema_create(j->getStr("id").c_str(), &schema);
+ rrs_schema_s *s = (rrs_schema_s *)schema;
+ if(!s)
+ return NULL;
+
+ do {
+ /* Get json-schema ver */
+ if(j->getStr("$schema").empty())
+ break;
+
+ /* Get the resource schema title */
+ s->title = g_strdup(j->getStr("title").c_str());
+
+ /* Get names of required fields */
+ const int req_amount = j->arrayGetSize(NULL, "required");
+ std::unordered_map<std::string, bool> req_fields;
+ for(int i = 0; i < req_amount; i ++) {
+ std::string fld_name;
+ j->getArrayElem(NULL, "required", i, &fld_name);
+ req_fields[fld_name] = true;
+ }
+
+
+ /* Get field definitions */
+ std::unique_ptr<Json> defs(j->getJson("definitions"));
+ if(!defs)
+ break;
+ std::list<std::string> def_list;
+ defs->getKeys(&def_list);
+
+ for(std::list<std::string>::iterator it = def_list.begin();
+ it != def_list.end(); it++) {
+ const std::string def_name = *it;
+ std::unique_ptr<Json> def(
+ defs->getJson(def_name.c_str()));
+ if(!def)
+ continue;
+
+ /* TODO: Can it be something else, not object? */
+ if(def->getStr("type") != "object")
+ break;
+
+ std::unique_ptr<Json> props(
+ def->getJson("properties"));
+ if(!props)
+ break;
+
+ std::list<std::string> prop_list;
+ props->getKeys(&prop_list);
+
+ /* Get fields */
+ for(std::list<std::string>::iterator pit =
+ prop_list.begin(); pit != prop_list.end(); ++pit) {
+ std::string fld_name = *pit;
+ std::unique_ptr<Json> f(
+ props->getJson(fld_name.c_str()));
+ if(!f)
+ continue;
+
+ /* TODO: add description to the field struct */
+ /*std::string fld_descr =
+ f->get_str("description");*/
+
+ rrs_schema_add_field(schema,
+ fld_name.c_str(),
+ _rrs_schema_get_type(f->getStr("type")),
+ _rrs_schema_get_access(f->getStr("access")),
+ req_fields[fld_name], NULL);
+ /* TODO: hierarchical fields */
+ }
+ }
+
+ /* Trace loaded schema */
+ /*_dbg_trace_schema(schema);*/
+
+ return schema;
+ } while (false);
+
+ /* Failed to init the schema */
+ rrs_schema_destroy(schema);
+ return NULL;
+}
+
+
+int rrs_schema_create_from_json(const char *json_schema,
+ rrs_schema_h *schema)
+{
+ /* Check if parameters are valid */
+ if (!json_schema || !schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Parse the schema */
+ std::unique_ptr<Json> j(new Json(json_schema));
+ *schema = _rrs_schema_init_from_json(j.get());
+
+ return ((*schema) ? RRS_ERROR_NONE : RRS_ERROR_INVALID_PARAMETER);
+}
+
+
+int rrs_schema_create_from_simple_json(const char *schema_name,
+ const char *json_simplified,
+ rrs_schema_h *schema)
+{
+ /* Check if schema handle is valid */
+
+ /* Check if parameters are valid */
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_schema_data_create_from_json(const char *schema_name,
+ const char *json_simplified,
+ rrs_schema_h *schema,
+ rrs_data_h *data)
+{
+ /* Check if schema handle is valid */
+
+ /* Check if parameters are valid */
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_schema_load(const rrs_resource_e resource_id,
+ rrs_schema_h *control_schema,
+ rrs_schema_h *event_schema)
+{
+ std::string service_schema_name, resource_schema_name;
+
+ /* Check if parameters are valid */
+ if ((resource_id < RRS_RESOURCE_NONE)
+ || (resource_id > RRS_RESOURCE_ALL)
+ || !event_schema || !control_schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Parse the schema */
+ std::unique_ptr<Json> control_json(new Json);
+ std::unique_ptr<Json> event_json(new Json);
+
+ _rrs_get_schema_system_path(resource_id, service_schema_name, resource_schema_name);
+
+ event_json->load(resource_schema_name.c_str());
+ control_json->load(service_schema_name.c_str());
+
+ *control_schema = _rrs_schema_init_from_json(control_json.get());
+ *event_schema = _rrs_schema_init_from_json(event_json.get());
+
+
+ if (*control_schema == NULL || *event_schema == NULL)
+ return RRS_ERROR_INVALID_PARAMETER;
+ else
+ return RRS_ERROR_NONE;
+}
+
+int rrs_discovery_schema_load(const rrs_resource_e resource_id,
+ rrs_schema_h *control_schema)
+{
+ std::string discovery_schema_name;
+
+ /* Check if parameters are valid */
+ if ((resource_id < RRS_RESOURCE_NONE)
+ || (resource_id > RRS_RESOURCE_ALL)
+ || !control_schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Parse the schema */
+ std::unique_ptr<Json> control_json(new Json);
+
+ _rrs_get_discovery_schema_system_path(resource_id, discovery_schema_name);
+
+ control_json->load(discovery_schema_name.c_str());
+
+ *control_schema = _rrs_schema_init_from_json(control_json.get());
+
+ if (*control_schema == NULL)
+ return RRS_ERROR_INVALID_PARAMETER;
+ else
+ return RRS_ERROR_NONE;
+}
+
+int rrs_schema_load_custom(const char *schema_name,
+ rrs_schema_h *schema)
+{
+ /* Check if parameters are valid */
+ if (!schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Parse the schema */
+ std::unique_ptr<Json> j(new Json);
+ j->load(_rrs_get_schema_custom_path(schema_name).c_str());
+ *schema = _rrs_schema_init_from_json(j.get());
+
+ return (*schema) ? RRS_ERROR_NONE : RRS_ERROR_INVALID_PARAMETER;
+}
+
+
+int rrs_schema_save_to_storage(const rrs_schema_h schema)
+{
+ /* Check if schema handle is valid */
+
+ /* Check if parameters are valid */
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_schema_delete_from_storage(const char *schema_name)
+{
+ /* Check if schema handle is valid */
+
+ /* Check if parameters are valid */
+
+ return RRS_ERROR_NONE;
+}
+
+
+static int _rrs_schema_clone(const rrs_schema_h origin, rrs_schema_h *cloned)
+{
+ /* Check if schema handle is valid */
+ if (!origin)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if(!cloned)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Clonning the schema */
+ int error = RRS_ERROR_NONE;
+ do {
+ rrs_schema_s *s = (rrs_schema_s *) origin;
+
+ error = rrs_schema_create(s->name, cloned);
+ if (!(*cloned) || (error != RRS_ERROR_NONE))
+ break;
+
+ /* Cloning data */
+ rrs_schema_s *cl = (rrs_schema_s *) (*cloned);
+
+ cl->resource = s->resource;
+
+ if (s->title) {
+ cl->title = g_strndup(s->title,
+ _RRS_SCHEMA_TITLE_MAX_LENGTH);
+ error = (cl->title) ? error : RRS_ERROR_OUT_OF_MEMORY;
+ if (error != RRS_ERROR_NONE)
+ break;
+ }
+
+ if (s->file) {
+ cl->file = g_strndup(s->file,
+ _RRS_SCHEMA_FILE_MAX_LENGTH);
+ error = (cl->file) ? error : RRS_ERROR_OUT_OF_MEMORY;
+ if (error != RRS_ERROR_NONE)
+ break;
+ }
+ if (s->fields)
+ __rrs_clone_schema_field_table(s->fields, &cl->fields);
+
+ return RRS_ERROR_NONE;
+ } while (false);
+
+ rrs_schema_destroy(*cloned);
+ *cloned = NULL;
+ return error;
+}
+
+int rrs_schema_destroy(rrs_schema_h schema)
+{
+ /* Check if schema handle is valid */
+ if (!schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Release schema data */
+ rrs_schema_s *s = (rrs_schema_s *)schema;
+ if(s->name)
+ g_free(s->name);
+ if(s->title)
+ g_free(s->title);
+ if(s->file)
+ g_free(s->file);
+ __rrs_destroy_schema_field_table(s->fields);
+
+ /* TODO: de-register in RRS */
+
+
+ g_slice_free(rrs_schema_s, s);
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_schema_add_field(rrs_schema_h schema,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ const rrs_schema_h complex_schema)
+{
+ /* Check if schema handle is valid */
+ if (!schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if this API feature available */
+
+ /* Check if parameters are valid */
+ if (!name
+ || (type < RRS_SCHEMA_TYPE_NONE)
+ || (type > RRS_SCHEMA_TYPE_COMPLEX)
+ || (access < RRS_SCHEMA_ACCESS_NONE)
+ || (access > RRS_SCHEMA_ACCESS_READ_WRITE))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Add field */
+ rrs_schema_s *s = (rrs_schema_s *)schema;
+ if (g_hash_table_contains(s->fields, name))
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ g_hash_table_insert(s->fields, g_strdup(name),
+ __rrs_schema_field_create_complete(
+ type, access, required, complex_schema));
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_schema_foreach_field(rrs_schema_h schema,
+ rrs_schema_foreach_field_cb callback,
+ void *user_data)
+{
+ /* Check if schema handle is valid */
+ if (!schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!callback)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Iterate through all fields */
+ rrs_schema_s *s = (rrs_schema_s *)schema;
+
+ GHashTableIter iter;
+ gpointer key, value;
+ const int total = g_hash_table_size(s->fields);
+ int index = 0;
+ g_hash_table_iter_init(&iter, s->fields);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (!value)
+ continue;
+
+ rrs_schema_field_s *f = (rrs_schema_field_s *)value;
+
+ if (!callback(index++, total,
+ (char *)key, f->type, f->access, f->required,
+ f->complex_schema, user_data))
+ break;
+ }
+
+ return RRS_ERROR_NONE;
+}
+
+static bool __rrs_schema_create_data_cb(int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ const rrs_schema_h schema,
+ void *user_data)
+{
+ rrs_data_h data = (rrs_data_h) user_data;
+ GHashTable *t = (GHashTable *)data;
+
+ /* Check if the field doesn't exist yet */
+ if (g_hash_table_contains(t, name))
+ return true;
+
+ /* Add new field */
+ g_hash_table_insert(t, g_strdup(name),
+ __rrs_value_item_create(type,
+ __rrs_value_alloc(type)));
+
+ return true;
+}
+
+
+int rrs_schema_create_data(const rrs_schema_h schema,
+ rrs_data_h *data)
+{
+ /* Check if schema handle is valid */
+ if (!schema)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ *data = __rrs_create_value_table();
+ if (!data) {
+ ERR("Out of memory");
+ return RRS_ERROR_OUT_OF_MEMORY;
+ }
+
+ rrs_schema_foreach_field(schema, __rrs_schema_create_data_cb, *data);
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_destroy(rrs_data_h data)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ __rrs_destroy_value_table((GHashTable *)data);
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_clone(const rrs_data_h origin, rrs_data_h *cloned)
+{
+ /* Check if schema handle is valid */
+ if (!origin)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if(!cloned)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+
+ /* Clonning the schema */
+ int error = RRS_ERROR_NONE;
+ do {
+ *cloned = __rrs_create_value_table();
+ if (!(*cloned)) {
+ ERR("Out of memory");
+ error = RRS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+
+ /* Cloning data */
+ GHashTable *t = (GHashTable *)origin;
+ GHashTable *t_cl = (GHashTable *)(*cloned);
+
+ GHashTableIter iter;
+ gpointer key, value;
+ g_hash_table_iter_init(&iter, t);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (!value)
+ continue;
+
+ rrs_value_item_s *i = (rrs_value_item_s *)value;
+ g_hash_table_insert(t_cl, g_strdup((char *)key),
+ __rrs_value_item_clone(i));
+ }
+
+ return RRS_ERROR_NONE;
+ } while (false);
+
+ rrs_data_destroy(*cloned);
+ *cloned = NULL;
+ return error;
+}
+
+int rrs_convert_control_to_event_data(const rrs_data_h control_data, rrs_data_h *event_data)
+{
+ /* Check if schema handle is valid */
+ if (!control_data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if(!event_data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+
+ int error = RRS_ERROR_NONE;
+ do {
+ GHashTable *t_ev = (GHashTable *)(*event_data);
+
+ GHashTableIter iter;
+ gpointer key, value;
+ g_hash_table_iter_init(&iter, t_ev);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ rrs_value_item_s *i = __rrs_value_lookup_field(control_data, (char *)key);
+ g_hash_table_insert(t_ev, g_strdup((char *)key), __rrs_value_item_clone(i));
+ }
+
+ return RRS_ERROR_NONE;
+ } while (false);
+
+ return error;
+}
+
+int rrs_data_set_bool(rrs_data_h data,
+ const char *name,
+ const bool value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_BOOL)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* TODO: check if access is WRITE or READ_WRITE */
+
+ /* Update field value */
+ bool *ptr = (bool *)i->item;
+ *ptr = value;
+
+ return RRS_ERROR_NONE;
+}
+
+int rrs_data_set_int(rrs_data_h data,
+ const char *name,
+ const int value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_INT)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ int *ptr = (int *)i->item;
+ *ptr = value;
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_set_double(rrs_data_h data,
+ const char *name,
+ const double value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_DOUBLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ double *ptr = (double *)i->item;
+ *ptr = value;
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_set_string(rrs_data_h data,
+ const char *name,
+ const char *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_STR)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ char *ptr = (char *)i->item;
+ g_stpcpy(ptr, value);
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_get_bool(const rrs_data_h data,
+ const char *name,
+ bool *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_BOOL)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ bool *ptr = (bool *)i->item;
+ *value = *ptr;
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_get_int(const rrs_data_h data,
+ const char *name,
+ int *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_INT)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ int *ptr = (int *)i->item;
+ *value = *ptr;
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_get_double(const rrs_data_h data,
+ const char *name,
+ double *value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_DOUBLE)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ double *ptr = (double *)i->item;
+ *value = *ptr;
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_get_string(const rrs_data_h data,
+ const char *name,
+ char **value)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!name || !value)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Look up for the field */
+ if (!__rrs_value_has_field(data, name))
+ return RRS_ERROR_NOT_FOUND;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, name);
+ if(!i)
+ return RRS_ERROR_NOT_FOUND;
+
+ /* Check field type */
+ if(i->type != RRS_SCHEMA_TYPE_STR)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Update field value */
+ char *ptr = (char *)i->item;
+ *value = g_strdup(ptr);
+
+ return RRS_ERROR_NONE;
+}
+
+
+int rrs_data_foreach_field(const rrs_data_h data,
+ const rrs_schema_h schema,
+ rrs_data_foreach_field_cb callback,
+ void *user_data)
+{
+ /* Check if data handle is valid */
+ if (!data)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ /* Check if parameters are valid */
+ if (!schema || !callback)
+ return RRS_ERROR_INVALID_PARAMETER;
+
+ rrs_schema_s *s = (rrs_schema_s *)schema;
+ GHashTableIter iter;
+ gpointer key = NULL;
+ gpointer value = NULL;
+ const int total = g_hash_table_size(s->fields);
+ int index = 0;
+ g_hash_table_iter_init(&iter, s->fields);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ if (!key || !value)
+ continue;
+
+ const char *fld_name = (const char *)key;
+ rrs_schema_field_s *field = (rrs_schema_field_s *)value;
+
+ if (!__rrs_value_has_field(data, fld_name))
+ continue;
+
+ rrs_value_item_s *i = __rrs_value_lookup_field(data, fld_name);
+ if (!i)
+ continue;
+
+ if (!callback (index ++, total,
+ fld_name,
+ field->type,
+ field->access,
+ field->required,
+ i->item,
+ user_data))
+ break;
+ }
+
+ return RRS_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 _SCHEMA_H_
+#define _SCHEMA_H_
+
+#include "rrs_error.h"
+#include "rrs_main.h"
+
+/**
+ * @ingroup CAPI_RRS_MODULE
+ * @defgroup CAPI_RRS_SCHEMA_MODULE Schema and data
+ *
+ * @file rrs_schema.h
+ * @brief This file contains the RRS Schema API
+ * @addtogroup CAPI_RRS_SCHEMA_MODULE
+ * @{
+ * @brief This provides APIs related to resource schema and data
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Handle of the resource schema.
+ * @details The schema handle can be created or loaded from the schema storage.
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_schema_destroy().
+ *
+ * @par Example
+ * @code
+ * @endcode
+ *
+ * @see rrs_schema_create()
+ * @see rrs_schema_create_from_json()
+ * @see rrs_schema_create_from_simple_json()
+ * @see rrs_schema_data_create_from_json()
+ * @see rrs_schema_load()
+ * @see rrs_schema_load_custom()
+ */
+typedef void *rrs_schema_h;
+
+
+/**
+ * @brief Handle of the resource schema.
+ * @details The schema handle can be created or loaded from the schema storage.
+ * @since_tizen 3.0
+ *
+ * @remarks To release the handle use rrs_schema_destroy().
+ *
+ * @par Example
+ * @code
+ * @endcode
+ *
+ * @see rrs_schema_create_data()
+ * @see rrs_data_destroy()
+ */
+typedef void *rrs_data_h;
+
+
+/**
+ * @brief Enumerations of schemas field types, supported by RRS
+ * @since_tizen 3.0
+ */
+typedef enum _rrs_schema_type_e {
+ RRS_SCHEMA_TYPE_NONE, /**< Indicates no type */
+ RRS_SCHEMA_TYPE_BOOL, /**< Indicates boolean type */
+ RRS_SCHEMA_TYPE_INT, /**< Indicates integer type */
+ RRS_SCHEMA_TYPE_DOUBLE, /**< Indicates floating point type */
+ RRS_SCHEMA_TYPE_STR, /**< Indicates string type */
+ RRS_SCHEMA_TYPE_COMPLEX /**< Indicates complex type */
+} RrsSchemaType;
+
+
+/**
+ * @brief Enumerations of schema field access types, supported by RRS
+ * @since_tizen 3.0
+ */
+typedef enum _rrs_schema_access_e {
+ RRS_SCHEMA_ACCESS_NONE = 0, /**< Indicates no access */
+ RRS_SCHEMA_ACCESS_READ = 1, /**< Indicates read only access */
+ RRS_SCHEMA_ACCESS_WRITE = 2, /**< Indicates write only acccess */
+ RRS_SCHEMA_ACCESS_READ_WRITE = 4, /**< Indicates read-write access */
+ RRS_SCHEMA_ACCESS_ALL = 8 /**< Indicates all access */
+} RrsSchemaAccess;
+
+
+
+/**
+ * @brief Called when requesting fields of schema.
+ * @details This callback is invoked while iterating through the list of
+ * fields of the schema.
+ * @since_tizen 3.0
+ *
+ * @remarks @a name must not be released using free().
+ *
+ * @param[in] index The current index of the field
+ * @param[in] total The total amount of the fields
+ * @param[in] name The name of the field
+ * @param[in] type The type of the field
+ * @param[in] access The type of the field access, read, write,
+ * read-write
+ * @param[in] required The value is required
+ * @param[in] user_data The user data passed from
+ * rrs_schema_foreach_field()
+ * @return @c true to continue with the next iteration of the loop, \n @c
+ * false to break out of the loop
+ *
+ * @pre rrs_schema_foreach_field() will invoke this callback.
+ *
+ * @see rrs_schema_foreach_field()
+ */
+typedef bool (*rrs_schema_foreach_field_cb) (int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ const rrs_schema_h schema,
+ void *user_data);
+
+
+/**
+ * @brief Called when requesting fields of data.
+ * @details This callback is invoked while iterating through the list of
+ * fields of the data.
+ * @since_tizen 3.0
+ *
+ * @remarks @a name must not be released using free().
+ * \n @a field must be released using free().
+ *
+ * @param[in] index The current index of the field
+ * @param[in] total The total amount of the fields
+ * @param[in] name The name of the field
+ * @param[in] type The type of the field
+ * @param[in] access The type of the field access, read, write,
+ * read-write
+ * @param[in] required The value is required
+ * @param[in] v The value the field
+ * @param[in] user_data The user data passed from
+ * rrs_data_foreach_field()
+ * @return @c true to continue with the next iteration of the loop, \n @c
+ * false to break out of the loop
+ *
+ * @pre rrs_data_foreach_field() will invoke this callback.
+ *
+ * @see rrs_data_foreach_field()
+ */
+typedef bool (*rrs_data_foreach_field_cb) (int index,
+ int total,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ void *v,
+ void *user_data);
+
+
+/**
+ * @brief Creates an empty resource schema.
+ * @details This function creates an empty resource schema and issues a new
+ * handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] name The schema name
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_create(const char *name, rrs_schema_h *schema);
+
+
+/**
+ * @brief Creates a resource schema handle from complete Json string.
+ * @details This function creates a resource schema from a complete Json schema
+ * definition and issues a new handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] json_schema The complete OIC-compatible json-formatted
+ * definition of schema
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_create_from_json(const char *json_schema, rrs_schema_h *schema);
+
+
+/**
+ * @brief Creates a resource schema from simplified json string.
+ * @details This function creates a resource schema from simplified json string
+ * and issues a new handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] schema_name The schema name
+ * @param[in] json_simplified The simplified json-formatted
+ * definition of schema
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_create_from_simple_json(const char *schema_name,
+ const char *json_simplified,
+ rrs_schema_h *schema);
+
+
+/**
+ * @brief Creates both resource schema and data from simplified json
+ * string.
+ * @details This function creates both resource schema and data from simplified
+ * json-formatted string and issues new handles for results.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] schema_name The schema name
+ * @param[in] json_simplified The simplified json-formatted
+ * definition of schema
+ * @param[out] schema The handle of the newly created schema
+ * @param[out] data The handle of the newly created data
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_data_create_from_json(const char *schema_name,
+ const char *json_simplified,
+ rrs_schema_h *schema,
+ rrs_data_h *data);
+
+
+/**
+ * @brief Loads a resource schema by specified schema id.
+ * @details This function loads a resource schema by specified schema id and
+ * issues a new handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] resource_id The predefined resource id
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_load(const rrs_resource_e resource_id,
+ rrs_schema_h *control_schema,
+ rrs_schema_h *event_schema);
+
+
+/**
+ * @brief Loads a resource schema by specified schema id.
+ * @details This function loads a resource schema by specified schema id and
+ * issues a new handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] resource_id The predefined resource id
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_discovery_schema_load(const rrs_resource_e resource_id,
+ rrs_schema_h *control_schema);
+
+/**
+ * @brief Loads a custom resource schema by schema name.
+ * @details This function loads a custom resource schema by specified schema
+ * name and issues a new handle for it.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] rrs The RRS handle
+ * @param[in] schema_name The custom schema name
+ * @param[out] schema The handle of the newly created schema
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_load_custom(const char *schema_name,
+ rrs_schema_h *schema);
+
+
+/**
+ * @brief Saves a custom resource schema in permanent schema storage.
+ * @details This function saves a custom resource schema in a permanent
+ * system-wide schema storage.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] schema The custom schema handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_save_to_storage(const rrs_schema_h schema);
+
+
+/**
+ * @brief Removes a custom resource schema from permanent schema storage.
+ * @details This function removes a custom resource schema from a permanent
+ * system-wide schema storage.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @remarks @a schema handle must be released using rrs_schema_destroy().
+ *
+ * @param[in] schema_name The custom schema name
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_schema_destroy()
+ */
+int rrs_schema_delete_from_storage(const char *schema_name);
+
+
+
+/**
+ * @brief Destroys the schema handle.
+ * @details This function releases the resource schema handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] schema The resource schema handle to destroy
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a schema handle is created with one of create or load functions.
+ *
+ * @see rrs_schema_create()
+ */
+int rrs_schema_destroy(rrs_schema_h schema);
+
+
+/**
+ * @brief Adds new field to the schema.
+ * @details This function adds a new field to the schema.
+ * @since_tizen 3.0
+ *
+ * @param[in] schema The schema handle
+ * @param[in] name The name of the added field
+ * @param[in] type The type of the added field
+ * @param[in] access The type of the field access, read, write,
+ * read-write
+ * @param[in] required The value is required
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a schema handle is created with one of create or load functions.
+ *
+ * @see rrs_schema_create()
+ * @see #RrsSchemaType
+ */
+int rrs_schema_add_field(rrs_schema_h schema,
+ const char *name,
+ const RrsSchemaType type,
+ const RrsSchemaAccess access,
+ const bool required,
+ const rrs_schema_h complex_schema);
+
+
+/**
+ * @brief Retrieves all fields in schema.
+ * @details This function retrieves all fields in the schema.
+ * @since_tizen 3.0
+ * @remarks The fields will be delivered via rrs_schema_foreach_field_cb().
+ *
+ * @param[in] schema The schema handle
+ * @param[in] callback The callback function to retrieve fields
+ * @param[in] user_data The user data to be passed to the
+ * callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post This function invokes rrs_schema_foreach_field_cb()
+ * repeatedly to retrieve each field.
+ *
+ * @see rrs_schema_foreach_field_cb()
+ */
+int rrs_schema_foreach_field(rrs_schema_h schema,
+ rrs_schema_foreach_field_cb callback,
+ void *user_data);
+
+
+/**
+ * @brief Creates an instance of structured resource data.
+ * @details This function creates an instance of structured resource data and
+ * issues a new handle for it.
+ * @since_tizen 3.0
+ *
+ * @remarks @a data handle must be released using rrs_data_destroy().
+ *
+ * @param[in] schema The handle of schema, defining the data
+ * @param[out] data The handle of newly created data instance
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_PERMISSION_DENIED Permission Denied
+ *
+ * @see rrs_data_destroy()
+ */
+int rrs_schema_create_data(const rrs_schema_h schema, rrs_data_h *data);
+
+
+/**
+ * @brief Destroys the data handle.
+ * @details This function releases the data handle.
+ * @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/healthinfo
+ *
+ * @param[in] data The data handle to destroy
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_destroy(rrs_data_h data);
+
+
+/**
+ * @brief Clones the data handle.
+ * @details This function clones the structured data handle @a origin.
+ * @since_tizen 3.0
+ *
+ * @remarks @a cloned must be released using rrs_data_destroy().
+ *
+ * @param[in] origin The original data handle
+ * @param[out] cloned A cloned data handle
+ * @return 0 on success, otherwise a negative error data
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @see rrs_data_destroy()
+ */
+int rrs_data_clone(const rrs_data_h origin, rrs_data_h *cloned);
+
+
+/**
+ * @brief Extracts event data from resource state data.
+ * @details This function extracts the event data from the remote resource state data.
+ * @since_tizen 3.0
+ */
+int rrs_convert_control_to_event_data(const rrs_data_h control_data, rrs_data_h *event_data);
+
+
+/**
+ * @brief Set boolean field value.
+ * @details This function set the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_set_bool(rrs_data_h data,
+ const char *name,
+ const bool v);
+
+
+/**
+ * @brief Set integer field value.
+ * @details This function set the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_set_int(rrs_data_h data,
+ const char *name,
+ const int v);
+
+
+/**
+ * @brief Set floating point field value.
+ * @details This function set the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_set_double(rrs_data_h data,
+ const char *name,
+ const double v);
+
+
+/**
+ * @brief Set string field value.
+ * @details This function set the string field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_set_string(rrs_data_h data,
+ const char *name,
+ const char *v);
+
+
+/**
+ * @brief Get boolean field value.
+ * @details This function get the boolean field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The pointer to bool in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_get_bool(const rrs_data_h data,
+ const char *name,
+ bool *v);
+
+
+/**
+ * @brief Get integer field value.
+ * @details This function get the integer field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The pointer to int in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_get_int(const rrs_data_h data,
+ const char *name,
+ int *v);
+
+
+/**
+ * @brief Get floating point field value.
+ * @details This function get the floating point field value.
+ * @since_tizen 3.0
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The pointer to double in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_get_double(const rrs_data_h data,
+ const char *name,
+ double *v);
+
+
+/**
+ * @brief Get string field value.
+ * @details This function get the sting field value.
+ * @since_tizen 3.0
+ *
+ * @remarks Release the value @a v using free.
+ *
+ * @param[in] data The data handle
+ * @param[in] name The name of the field
+ * @param[in] v The pointer to char * in which to store the
+ * value of the field
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @pre @a data handle is created with rrs_schema_create_data() functions.
+ *
+ * @see rrs_schema_create_data()
+ */
+int rrs_data_get_string(const rrs_data_h data,
+ const char *name,
+ char **v);
+
+
+/**
+ * @brief Retrieves all fields of structured data.
+ * @details This function retrieves all fields of the structured data.
+ * @since_tizen 3.0
+ *
+ * @remarks The fields will be delivered via rrs_data_foreach_field_cb().
+ *
+ * @param[in] data The data handle
+ * @param[in] callback The callback function to retrieve fields
+ * @param[in] user_data The user data to be passed to the
+ * callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #RRS_ERROR_NONE Successful
+ * @retval #RRS_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RRS_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @post This function invokes rrs_data_foreach_field_cb()
+ * repeatedly to retrieve each field.
+ *
+ * @see rrs_data_foreach_field_cb()
+ */
+int rrs_data_foreach_field(const rrs_data_h data,
+ const rrs_schema_h schema,
+ rrs_data_foreach_field_cb callback,
+ void *user_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * @}
+ */
+#endif /* _SCHEMA_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 __SCHEMA_TYPES_INTERNAL_H__
+#define __SCHEMA_TYPES_INTERNAL_H__
+
+#include <tizen_error.h>
+#include <dlog.h>
+#include "common.h"
+
+/* Color code for dlog */
+#define RED(X) "\033[0;31m" X "\033[0m"
+#define GREEN(X) "\033[0;32m" X "\033[0m"
+#define YELLOW(X) "\033[0;33m" X "\033[0m"
+#define BLUE(X) "\033[0;34m" X "\033[0m"
+#define PURPLE(X) "\033[0;35m" X "\033[0m"
+#define CYAN(X) "\033[0;36m" X "\033[0m"
+
+#define REPLACE_NULL(X) ((X) ? (X) : "")
+#define STR_EQ(X, Y) (g_strcmp0((X), (Y)) == 0)
+
+#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0)
+
+#define IF_FAIL_RETURN(cond, ret) \
+ do { if (!(cond)) { return ret; } } while (0)
+
+#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0)
+
+#define IF_FAIL_VOID(cond) \
+ do { if (!(cond)) { return; } } while (0)
+
+#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \
+ do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0)
+
+#define IF_FAIL_CATCH(cond) \
+ do { if (!(cond)) { goto CATCH; } } while (0)
+
+#define IS_FAILED(X) ((X) != ERR_NONE)
+
+#define ASSERT_ALLOC(X) IF_FAIL_RETURN_TAG(X, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X) IF_FAIL_RETURN_TAG(X, ERR_INVALID_PARAMETER, _E, "Parameter null")
+
+#define HANDLE_GERROR(Err) \
+ do { if ((Err)) { _E("GError: %s", Err->message); g_error_free(Err); Err = NULL; } } while (0)
+
+#endif /* __SCHEMA_TYPES_INTERNAL_H__ */
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.accelerometer",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"Accelerometer",
+ "definitions":{
+ "x.org.tizen.accelerometer":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.accelerometer"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.autorotation",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"autorotation",
+ "definitions":{
+ "x.org.tizen.autorotation":{
+ "type":"object",
+ "properties":{
+ "state":{
+ "type":"integer",
+ "description":"auto rotation state",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.autorotation"
+ }
+ ],
+ "required":["state"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.geomagneticrotationvector",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"geomagneticrotationvector",
+ "definitions":{
+ "x.org.tizen.geomagneticrotationvector":{
+ "type":"object",
+ "properties":{
+ "w":{
+ "type":"double",
+ "description":"W-axis component",
+ "access":"R"
+ },
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.geomagneticrotationvector"
+ }
+ ],
+ "required":["w", "x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.gravity",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"gravity",
+ "definitions":{
+ "x.org.tizen.gravity":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.gravity"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.gyroscope",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"gyroscope",
+ "definitions":{
+ "x.org.tizen.gyroscope":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.gyroscope"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.gyroscoperotationvector",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"gyroscoperotationvector",
+ "definitions":{
+ "x.org.tizen.gyroscoperotationvector":{
+ "type":"object",
+ "properties":{
+ "w":{
+ "type":"double",
+ "description":"W-axis component",
+ "access":"R"
+ },
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.gyroscoperotationvector"
+ }
+ ],
+ "required":["w", "x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.hrm",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"hrm",
+ "definitions":{
+ "x.org.tizen.hrm":{
+ "type":"object",
+ "properties":{
+ "beats":{
+ "type":"integer",
+ "description":"heart beats per minute",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.hrm"
+ }
+ ],
+ "required":["beats"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.hrmledgreen",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"hrmledgreen",
+ "definitions":{
+ "x.org.tizen.hrmledgreen":{
+ "type":"object",
+ "properties":{
+ "value":{
+ "type":"integer",
+ "description":"Amount of green light reflected from persons blood vessel",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.hrmledgreen"
+ }
+ ],
+ "required":["value"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.hrmledir",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"hrmledir",
+ "definitions":{
+ "x.org.tizen.hrmledir":{
+ "type":"object",
+ "properties":{
+ "value":{
+ "type":"integer",
+ "description":"Amount of Infra-red light reflected from persons blood vessel",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.hrmledir"
+ }
+ ],
+ "required":["value"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.hrmledred",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"hrmledred",
+ "definitions":{
+ "x.org.tizen.hrmledred":{
+ "type":"object",
+ "properties":{
+ "value":{
+ "type":"integer",
+ "description":"Amount of red light reflected from persons blood vessel",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.hrmledred"
+ }
+ ],
+ "required":["value"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.humidity",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"humidity",
+ "definitions":{
+ "x.org.tizen.humidity":{
+ "type":"object",
+ "properties":{
+ "humidity":{
+ "type":"integer",
+ "description":"Ambient room humidity in %",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.humidity"
+ }
+ ],
+ "required":["humidity"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.light",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"light",
+ "definitions":{
+ "x.org.tizen.light":{
+ "type":"object",
+ "properties":{
+ "brightness":{
+ "type":"integer",
+ "description":"brightness of measured light in Lux",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.light"
+ }
+ ],
+ "required":["brightness"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.linearacceleration",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"linearacceleration",
+ "definitions":{
+ "x.org.tizen.linearacceleration":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.linearacceleration"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.magnetometer",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"magnetometer",
+ "definitions":{
+ "x.org.tizen.magnetometer":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.magnetometer"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.orientation",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"orientation",
+ "definitions":{
+ "x.org.tizen.orientation":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis coordinate",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis coordinate",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis coordinate",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.orientation"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.pressure",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"pressure",
+ "definitions":{
+ "x.org.tizen.pressure":{
+ "type":"object",
+ "properties":{
+ "pressure":{
+ "type":"integer",
+ "description":"Atmospheric Pressure in hPa",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.pressure"
+ }
+ ],
+ "required":["pressure"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.proximity",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"proximity",
+ "definitions":{
+ "x.org.tizen.proximity":{
+ "type":"object",
+ "properties":{
+ "state":{
+ "type":"integer",
+ "description":"Proximity State",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.proximity"
+ }
+ ],
+ "required":["state"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.rotationvector",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"rotationvector",
+ "definitions":{
+ "x.org.tizen.rotationvector":{
+ "type":"object",
+ "properties":{
+ "w":{
+ "type":"double",
+ "description":"W-axis component",
+ "access":"R"
+ },
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.rotationvector"
+ }
+ ],
+ "required":["w", "x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.rrsdiscovery",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"rrsdiscovery",
+ "definitions":{
+ "x.org.tizen.rrsdiscovery":{
+ "type":"object",
+ "properties":{
+ "accelerometer":{
+ "type":"integer",
+ "description":"count of accelerometer sensors",
+ "access":"RW"
+ },
+ "proximity":{
+ "type":"integer",
+ "description":"count of proximity sensors",
+ "access":"RW"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.rrsdiscovery"
+ }
+ ],
+ "required":["accelerometer", "proximity"]
+}
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.sensorcontrol",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"sensorcontrol",
+ "definitions":{
+ "x.org.tizen.sensorcontrol":{
+ "type":"object",
+ "properties":{
+ "connect_sensor":{
+ "type":"bool",
+ "description":"Connect sensor",
+ "access":"RW"
+ },
+ "disconnect_sensor":{
+ "type":"bool",
+ "description":"Disconnect sensor",
+ "access":"RW"
+ },
+ "interval":{
+ "type":"integer",
+ "description":"Interval",
+ "access":"RW"
+ },
+ "max_batch_latency":{
+ "type":"integer",
+ "description":"Max batch latency",
+ "access":"RW"
+ },
+ "register_event":{
+ "type":"bool",
+ "description":"Register event",
+ "access":"RW"
+ },
+ "unregister_event":{
+ "type":"bool",
+ "description":"Unregister event",
+ "access":"RW"
+ },
+ "get_data":{
+ "type":"bool",
+ "description":"Get data",
+ "access":"RW"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.sensorcontrol"
+ }
+ ],
+ "required":["connect_sensor", "disconnect_sensor", "interval", "max_batch_latency", "register_event", "unregister_event", "get_data"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.temperature",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"temperature",
+ "definitions":{
+ "x.org.tizen.temperature":{
+ "type":"object",
+ "properties":{
+ "temperature":{
+ "type":"integer",
+ "description":"Ambient temperature",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.temperature"
+ }
+ ],
+ "required":["temperature"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.uncalibratedgyroscope",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"uncalibratedgyroscope",
+ "definitions":{
+ "x.org.tizen.uncalibratedgyroscope":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.uncalibratedgyroscope"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.uncalibratedmagnetometer",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"uncalibratedmagnetometer",
+ "definitions":{
+ "x.org.tizen.uncalibratedmagnetometer":{
+ "type":"object",
+ "properties":{
+ "x":{
+ "type":"double",
+ "description":"X-axis component",
+ "access":"R"
+ },
+ "y":{
+ "type":"double",
+ "description":"Y-axis component",
+ "access":"R"
+ },
+ "z":{
+ "type":"double",
+ "description":"Z-axis component",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.uncalibratedmagnetometer"
+ }
+ ],
+ "required":["x", "y", "z"]
+}
+
+
--- /dev/null
+{
+ "id":"http://openinterconnect.org/schemas/x.org.tizen.uv",
+ "$schema":"http://json-schema.org/draft-04/schema#",
+ "title":"uv",
+ "definitions":{
+ "x.org.tizen.uv":{
+ "type":"object",
+ "properties":{
+ "index":{
+ "type":"integer",
+ "description":"Uv index of uv rays being exposed on device",
+ "access":"R"
+ }
+ }
+ }
+ },
+ "type":"object",
+ "allOf":[
+ {
+ "$ref":"oic.core.json#/definitions/oic.core"
+ },
+ {
+ "$ref":"oic.baseResource.json#/definitions/oic.r.baseresource"
+ },
+ {
+ "$ref":"#/definitions/x.org.tizen.uv"
+ }
+ ],
+ "required":["index"]
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _SERVICES_COMMON_H_
+#define _SERVICES_COMMON_H_
+
+#include <vector>
+#include "rrs_main.h"
+#include "Mutex.h"
+
+#define MAX_HANDLE 100
+#define MAX_HANDLE_REACHED -1
+
+#define MODULE_OFFSET 24
+#define RESOURCE_OFFSET 14
+#define EVENT_OFFSET 0
+#define COMMAND_OFFSET 0
+
+#define MODULE_TYPE_MASK (0xFF << MODULE_OFFSET)
+#define RESOURCE_TYPE_MASK (0xFF << RESOURCE_OFFSET)
+#define EVENT_TYPE_MASK (0xFF << EVENT_OFFSET)
+#define COMMAND_TYPE_MASK (0xFF << COMMAND_OFFSET)
+
+#define SUCCESS true
+#define FAILURE false
+
+typedef enum _rrs_service_e {
+ ALL_SERVICES = -1,
+ UNKNOWN_SERVICE = 0,
+ SENSOR_FRAMEWORK
+} RrsService;
+
+typedef struct IotTizenModule {
+ std::vector<void*> modules;
+} IotTizenModule;
+
+typedef IotTizenModule* (*create_t)(void);
+
+typedef struct BrokerResource {
+ RrsService service_type;
+ rrs_resource_e resource_type;
+ unsigned char resource_index;
+ int handle;
+ void *data;
+} BrokerResource;
+
+#endif /* _SERVICES_COMMON_H_ */
--- /dev/null
+add_subdirectory(daemon)
\ No newline at end of file
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(rrs-server CXX)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(rrs-server-pkgs REQUIRED vconf glib-2.0 dlog sensor iotcon)
+
+add_definitions(${rrs-server-defs})
+
+INCLUDE_DIRECTORIES(include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+FILE(GLOB rrs-server-srcs *.c *.cpp)
+
+FOREACH(flag ${rrs-server-pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${rrs-server-pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+include_directories(${CMAKE_SOURCE_DIR}/src/brokers/sensor_framework)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrt -ldl -pthread -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
+
+add_executable(${PROJECT_NAME} ${rrs-server-srcs})
+
+target_link_libraries(${PROJECT_NAME} ${rrs-server-pkgs_LDFLAGS}
+ "rrs-common"
+ "sensor-framework-broker"
+ )
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"RRS-SERVER\"")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
+
+INSTALL(FILES ../../../packaging/remote-resource-service.service DESTINATION /usr/lib/systemd/system)
+INSTALL(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib/rrs
+)
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "PluginLoader.h"
+#include <dlfcn.h>
+#include <dirent.h>
+#include <unordered_set>
+#include <algorithm>
+#include "ServiceManager.h"
+#include "common.h"
+
+using std::make_pair;
+using std::equal;
+using std::unordered_set;
+using std::pair;
+using std::vector;
+using std::string;
+using std::shared_ptr;
+using std::static_pointer_cast;
+
+#define ROOT_ELEMENT "SERVICE"
+#define PATH_ATTR "path"
+
+#define SENSOR_BROKER_DIR_PATH "/usr/lib/rrs/libsensor-framework-broker.so"
+
+PluginLoader::PluginLoader()
+{
+}
+
+PluginLoader::~PluginLoader()
+{
+}
+
+PluginLoader& PluginLoader::__get_instance()
+{
+ static PluginLoader inst;
+ return inst;
+}
+
+bool PluginLoader::loadModule(const string &path, vector<void*> &tizen_modules, void* &handle)
+{
+ void *_handle = dlopen(path.c_str(), RTLD_NOW);
+
+ if (!_handle) {
+ ERR("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
+ return false;
+ }
+
+ dlerror();
+
+ create_t create_module = (create_t) dlsym(_handle, "create");
+
+ if (!create_module) {
+ ERR("Failed to find symbols in %s", path.c_str());
+ dlclose(_handle);
+ return false;
+ }
+
+ IotTizenModule *plugin = create_module();
+
+ if (!plugin) {
+ ERR("Failed to create module, path is %s\n", path.c_str());
+ dlclose(_handle);
+ return false;
+ }
+
+ tizen_modules.clear();
+ tizen_modules.swap(plugin->modules);
+
+ delete plugin;
+ handle = _handle;
+
+ return true;
+}
+
+bool PluginLoader::insertModule(const string &path)
+{
+ DBG("Insert Service Brokers [%s]", path.c_str());
+
+ std::vector<void *> tizen_modules;
+ void *handle;
+
+ if (!loadModule(path, tizen_modules, handle))
+ return false;
+
+ shared_ptr<ServiceManager> tizen_module;
+
+ for (unsigned int i = 0; i < tizen_modules.size(); ++i) {
+ tizen_module.reset(static_cast<ServiceManager *>(tizen_modules[i]));
+ RrsService service_type = tizen_module->getType();
+ __services.insert(make_pair(service_type, tizen_module));
+ }
+
+ if (!tizen_module->init()) {
+ ERR("Failed to init [%s] module\n", tizen_module->getName());
+ }
+
+ tizen_module->start();
+
+ return true;
+}
+
+bool PluginLoader::loadPlugins(void)
+{
+ insertModule(SENSOR_BROKER_DIR_PATH);
+
+ showTizenModuleInfo();
+
+ return true;
+}
+
+void PluginLoader::showTizenModuleInfo(void)
+{
+ INFO("========== Successfully Loaded Tizen Modules ==========\n");
+
+ int index = 0;
+
+ auto it = __services.begin();
+
+ while (it != __services.end()) {
+ shared_ptr<ServiceManager> tizen_module = it->second;
+ INFO("No:%d [%s]\n", ++index, tizen_module->getName());
+ it++;
+ }
+
+ INFO("========================================================\n");
+}
+
+ServiceManager* PluginLoader::getTizenModule(RrsService type)
+{
+ auto it_plugins = __services.find(type);
+
+ if (it_plugins == __services.end())
+ return NULL;
+
+ return it_plugins->second.get();
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#if !defined(_PLUGIN_LOADER_H_)
+#define _PLUGIN_LOADER_H_
+
+#include <string>
+#include <vector>
+#include <map>
+#include <memory>
+#include "services_common.h"
+#include "ServiceManager.h"
+
+class PluginLoader {
+public:
+ static PluginLoader& __get_instance();
+ bool loadPlugins(void);
+ ServiceManager* getTizenModule(RrsService type);
+ bool destroy();
+private:
+ typedef std::multimap<RrsService, std::shared_ptr<ServiceManager>> tizen_services;
+
+ PluginLoader();
+ virtual ~PluginLoader();
+ bool loadModule(const std::string &path, std::vector<void*> &tizen_modules, void* &handle);
+ bool insertModule(const std::string &path);
+ void showTizenModuleInfo(void);
+ bool getPathsFromDir(const std::string &dir_path, std::vector<std::string> &tizen_module_paths);
+ bool getPathsFromConfig(const std::string &config_path, std::vector<std::string> &tizen_module_paths);
+
+ tizen_services __services;
+};
+#endif /* _PLUGIN_LOADER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "ResourceQueue.h"
+#include "common.h"
+
+ResourceQueue::ResourceQueue()
+{
+}
+
+ResourceQueue::~ResourceQueue()
+{
+}
+
+ResourceQueue& ResourceQueue::__transmit_control_instance()
+{
+ static ResourceQueue transmit_control_inst;
+ return transmit_control_inst;
+}
+
+ResourceQueue& ResourceQueue::__receive_control_instance()
+{
+ static ResourceQueue receive_control_inst;
+ return receive_control_inst;
+}
+
+ResourceQueue& ResourceQueue::__receive_event_instance()
+{
+ static ResourceQueue receive_event_inst;
+ return receive_event_inst;
+}
+void ResourceQueue::push(BrokerResource const &cmd)
+{
+ BrokerResource *new_cmd = new(std::nothrow) BrokerResource;
+ RETM_IF(!new_cmd, "Failed to allocate memory");
+ *new_cmd = cmd;
+
+ pushInternal(new_cmd);
+}
+
+void ResourceQueue::pushInternal(void *cmd)
+{
+ lock l(__mutex);
+ bool wake = __queue.empty();
+
+ if (__queue.size() >= QUEUE_FULL_SIZE) {
+ ERR("Queue is full, drop it!");
+ delete (BrokerResource *)cmd;
+ } else {
+ __queue.push(cmd);
+ }
+
+ if (wake)
+ __condVar.notify_one();
+}
+
+void* ResourceQueue::pop(void)
+{
+ ulock u(__mutex);
+
+ while (__queue.empty())
+ __condVar.wait(u);
+
+ void* cmd = __queue.front();
+ __queue.pop();
+
+ return cmd;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RESOURCE_QUEUE_H_
+#define _RESOURCE_QUEUE_H_
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+#include "services_common.h"
+
+class ResourceQueue {
+public:
+ ResourceQueue();
+ ~ResourceQueue();
+ ResourceQueue(const ResourceQueue &) {};
+ ResourceQueue& operator=(const ResourceQueue &);
+ void push(BrokerResource const &cmd);
+ void* pop(void);
+
+ static ResourceQueue& __transmit_control_instance();
+ static ResourceQueue& __receive_control_instance();
+ static ResourceQueue& __receive_event_instance();
+private:
+ void pushInternal(void *event);
+
+ static const unsigned int QUEUE_FULL_SIZE = 1000;
+
+ std::queue<void*> __queue;
+ std::mutex __mutex;
+ std::condition_variable __condVar;
+
+ typedef std::lock_guard<std::mutex> lock;
+ typedef std::unique_lock<std::mutex> ulock;
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "ResourceServer.h"
+#include <string>
+#include "common.h"
+#include "SensorFrameworkBroker.h"
+#include "Server.h"
+#include "IotconToRrs.h"
+
+using std::string;
+
+ResourceServer::ResourceServer()
+: __rrs()
+, __controlSchema(NULL)
+, __eventSchema(NULL)
+, __controlData(NULL)
+, __eventData(NULL)
+, __resourceType(RRS_RESOURCE_NONE)
+, __serviceType(UNKNOWN_SERVICE)
+, __resourceIndex(0)
+, __uriPath(NULL)
+, __name(NULL)
+, __interfaces(NULL)
+, __properties(0)
+, __handle(NULL)
+, __observers(NULL)
+{
+}
+
+ResourceServer::~ResourceServer()
+{
+ if (__controlData)
+ rrs_data_destroy(__controlData);
+ __controlData = NULL;
+
+ if (__eventData)
+ rrs_data_destroy(__eventData);
+ __eventData = NULL;
+
+ if (__controlSchema)
+ rrs_schema_destroy(__controlSchema);
+ __controlSchema = NULL;
+
+ if (__eventSchema)
+ rrs_schema_destroy(__eventSchema);
+ __eventSchema = NULL;
+}
+
+void *ResourceServer::__notify_observers(void *user_data)
+{
+ int ret;
+ iotcon_representation_h repr;
+ ResourceServer *res_inst;
+ Server *server_main = (Server *) user_data;
+
+ ret = iotcon_representation_create(&repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_create() Fail(%d)", ret);
+ return false;
+ }
+
+ INFO("Started function to notify server resource observers");
+
+ do {
+ BrokerResource *broker_resource = (BrokerResource *) ResourceQueue::__receive_event_instance().pop();
+
+ res_inst = server_main->getResourceInfo(broker_resource->resource_type, broker_resource->resource_index);
+
+ if (broker_resource->resource_type == res_inst->__resourceType) {
+ rrs_data_destroy(res_inst->__eventData);
+ if (rrs_event_data_clone(broker_resource->data, &(res_inst->__eventData)) != RRS_ERROR_NONE) {
+ ERR("rrs_data_clone() failed");
+ return false;
+ }
+
+ rrs_data_destroy(broker_resource->data);
+
+ res_inst->setEventRepresentation(&repr);
+
+ ret = iotcon_resource_notify(res_inst->__handle, repr, res_inst->__observers, IOTCON_QOS_HIGH);
+ if (ret != IOTCON_ERROR_NONE) {
+ INFO("No More observers, stopping notifications");
+ iotcon_representation_destroy(repr);
+ return NULL;
+ }
+ }
+ } while (res_inst->__observers != NULL);
+
+ iotcon_representation_destroy(repr);
+ return NULL;
+}
+
+void ResourceServer::__request_handler(const iotcon_resource_h resource, const iotcon_request_h request, void *user_data)
+{
+ Server *server_main = (Server *) user_data;
+ int ret, observe_id;
+ bool retval = true;
+ iotcon_request_type_e type;
+ iotcon_observe_type_e observe_type;
+ char *host_address;
+ BrokerResource broker_resource;
+ ResourceServer *res_inst;
+ iotcon_connectivity_type_e connectivity_type;
+
+ res_inst = server_main->getResourceInfo(resource);
+
+ broker_resource.service_type = res_inst->__serviceType;
+ broker_resource.resource_type = res_inst->__resourceType;
+ broker_resource.resource_index = res_inst->__resourceIndex;
+
+ ret = iotcon_request_get_host_address(request, &host_address);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_host_address() Fail(%d)", ret);
+ res_inst->sendResponse(request, NULL, IOTCON_RESPONSE_ERROR);
+ return;
+ }
+
+ INFO("Handling Resource Client with host_address : %s", host_address);
+
+ ret = iotcon_request_get_connectivity_type(request, &connectivity_type);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_connectivity_type() Fail(%d)", ret);
+ res_inst->sendResponse(request, NULL, IOTCON_RESPONSE_ERROR);
+ return;
+ }
+
+ INFO("Handling Resource Client with connectivity type : %d", connectivity_type);
+
+ ret = iotcon_request_get_request_type(request, &type);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_types() Fail(%d)", ret);
+ res_inst->sendResponse(request, NULL, IOTCON_RESPONSE_ERROR);
+ return;
+ }
+
+ if (type == IOTCON_REQUEST_GET) {
+ retval = res_inst->requestHandlerGet(request);
+ } else if (type == IOTCON_REQUEST_PUT) {
+ retval = res_inst->requestHandlerPut(request, broker_resource);
+ } else if (type == IOTCON_REQUEST_DELETE) {
+ retval = res_inst->requestHandlerDelete(request);
+ }
+ if (!retval) {
+ res_inst->sendResponse(request, NULL, IOTCON_RESPONSE_ERROR);
+ return;
+ }
+
+ ret = iotcon_request_get_observe_type(request, &observe_type);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_observe_type() Fail(%d)", ret);
+ return;
+ }
+
+ if (observe_type == IOTCON_OBSERVE_REGISTER) {
+ ret = iotcon_request_get_observe_id(request, &observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_observe_id() Fail(%d)", ret);
+ return;
+ }
+
+ ret = iotcon_observers_add(res_inst->__observers, observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_observers_add() Fail(%d)", ret);
+ return;
+ }
+
+ pthread_t threadId;
+
+ pthread_create(&threadId, NULL, __notify_observers, user_data);
+
+ INFO("Client with host_address : %s, added as observer", host_address);
+
+ } else if (observe_type == IOTCON_OBSERVE_DEREGISTER) {
+ ret = iotcon_request_get_observe_id(request, &observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_observe_id() Fail(%d)", ret);
+ return;
+ }
+ ret = iotcon_observers_remove(res_inst->__observers, observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_observers_remove() Fail(%d)", ret);
+ return;
+ }
+
+ INFO("Client with host_address : %s, removed as observer", host_address);
+ }
+
+ return;
+}
+
+ResourceServer::ResourceServer(const ResourceServer &obj)
+{
+ __rrs = obj.__rrs;
+ __controlSchema = obj.__controlSchema;
+ __eventSchema = obj.__eventSchema;
+ __controlData = obj.__controlData;
+ __eventData = obj.__eventData;
+ __resourceType = obj.__resourceType;
+ __serviceType = obj.__serviceType;
+ __resourceIndex = obj.__resourceIndex;
+ __uriPath = obj.__uriPath;
+ __name = obj.__name;
+ __interfaces = obj.__interfaces;
+ __properties = obj.__properties;
+ __handle = obj.__handle;
+ __observers = obj.__observers;
+}
+
+ResourceServer& ResourceServer::operator= (const ResourceServer &obj)
+{
+ if (this != &obj) {
+ __rrs = obj.__rrs;
+ __controlSchema = obj.__controlSchema;
+ __eventSchema = obj.__eventSchema;
+ __controlData = obj.__controlData;
+ __eventData = obj.__eventData;
+ __resourceType = obj.__resourceType;
+ __serviceType = obj.__serviceType;
+ __resourceIndex = obj.__resourceIndex;
+ __uriPath = obj.__uriPath;
+ __name = obj.__name;
+ __interfaces = obj.__interfaces;
+ __properties = obj.__properties;
+ __handle = obj.__handle;
+ __observers = obj.__observers;
+ }
+
+ return *this;
+}
+
+bool ResourceServer::setControlRepresentation(iotcon_representation_h *repr)
+{
+ int ret = RRS_ERROR_NONE;
+ iotcon_attributes_h state;
+
+ ret = iotcon_attributes_create(&state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_representation_set_uri_path(*repr, __uriPath);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_set_uri_path() Fail(%d)", ret);
+ iotcon_attributes_destroy(state);
+ return false;
+ }
+
+ IotconToRrs converter(__controlData, __controlSchema, state);
+ converter.setToIotcon();
+
+ ret = iotcon_representation_set_attributes(*repr, state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_set_attributes() Fail(%d)", ret);
+ iotcon_attributes_destroy(state);
+ return false;
+ }
+
+ iotcon_attributes_destroy(state);
+
+ return true;
+}
+
+bool ResourceServer::setEventRepresentation(iotcon_representation_h *repr)
+{
+ int ret = RRS_ERROR_NONE;
+ iotcon_attributes_h state = NULL;
+
+ ret = iotcon_attributes_create(&state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_attributes_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_representation_set_uri_path(*repr, __uriPath);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_set_uri_path() Fail(%d)", ret);
+ iotcon_attributes_destroy(state);
+ return false;
+ }
+
+ IotconToRrs converter(__eventData, __eventSchema, state);
+ converter.setToIotcon();
+
+ ret = iotcon_representation_set_attributes(*repr, state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_set_attributes() Fail(%d)", ret);
+ iotcon_attributes_destroy(state);
+ return false;
+ }
+
+ iotcon_attributes_destroy(state);
+
+ return true;
+}
+
+bool ResourceServer::getControlRepresentation(const iotcon_representation_h repr)
+{
+ iotcon_attributes_h state = NULL;
+
+ const int ret = iotcon_representation_get_attributes(repr, &state);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_get_attributes() Fail(%d)", ret);
+ return false;
+ }
+
+ IotconToRrs converter(__controlData, __controlSchema, state);
+ converter.getFromIotcon();
+
+ return true;
+}
+
+bool ResourceServer::sendResponse(const iotcon_request_h request, const iotcon_representation_h repr, const iotcon_response_result_e result)
+{
+ int ret;
+ iotcon_response_h response;
+
+ ret = iotcon_response_create(request, &response);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_response_set_result(response, result);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_set_result() Fail(%d)", ret);
+ iotcon_response_destroy(response);
+ return false;
+ }
+
+ ret = iotcon_response_set_representation(response, repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_set_representation() Fail(%d)", ret);
+ iotcon_response_destroy(response);
+ return false;
+ }
+
+ ret = iotcon_response_send(response);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_response_send() Fail(%d)", ret);
+ iotcon_response_destroy(response);
+ return false;
+ }
+
+ iotcon_response_destroy(response);
+
+ return true;
+}
+
+bool ResourceServer::createDiscoveryResource(const char *uri, const unsigned char index, const char *resource_name, void *user_data)
+{
+ int ret;
+ iotcon_resource_types_h resource_types;
+ char index_char = (char)index + '0';
+ __resourceIndex = index;
+
+ string uri_temp = string(uri) + "/" + index_char;
+
+ INFO("\n uri_temp = %s", uri_temp.c_str());
+
+ if (rrs_discovery_schema_load(__resourceType, &__controlSchema) != RRS_ERROR_NONE) {
+ ERR("rrs_discovery_schema_load() failed");
+ return false;
+ }
+
+ if (rrs_schema_create_data(__controlSchema, &__controlData) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() failed");
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_create(&__interfaces);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_add(__interfaces, IOTCON_INTERFACE_DEFAULT);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_add() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_add(__interfaces, IOTCON_INTERFACE_BATCH);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_add() Fail(%d)", ret);
+ return false;
+ }
+
+ __properties = IOTCON_RESOURCE_DISCOVERABLE;
+ __properties |= IOTCON_RESOURCE_OBSERVABLE;
+
+ ret = iotcon_resource_types_create(&resource_types);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_types_create() Fail(%d)", ret);
+ free(__uriPath);
+ return false;
+ }
+
+ ret = iotcon_resource_types_add(resource_types, resource_name);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_types_add() Fail(%d)", ret);
+ iotcon_resource_types_destroy(resource_types);
+ free(__uriPath);
+ return false;
+ }
+
+ __uriPath = strdup(uri_temp.c_str());
+ if (__uriPath == NULL) {
+ ERR("strdup(%s) Fail", uri);
+ return false;
+ }
+
+ __name = strdup(resource_name);
+ if (__name == NULL) {
+ ERR("strdup(%s) Fail", __name);
+ return false;
+ }
+
+ INFO("%s Discovery Resource Creation initiated!", __uriPath);
+
+ ret = iotcon_resource_create(__uriPath, resource_types, __interfaces, __properties, __request_handler, user_data, &__handle);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_create() Fail");
+ free(__uriPath);
+ iotcon_resource_types_destroy(resource_types);
+ return false;
+ }
+
+ iotcon_resource_types_destroy(resource_types);
+
+ return true;
+}
+
+bool ResourceServer::createResource(const char *uri, const unsigned char index, const char *resource_name, void *user_data)
+{
+ int ret;
+ iotcon_resource_types_h resource_types;
+ char index_char = (char)index + '0';
+ __resourceIndex = index;
+
+ string uri_temp = string(uri) + "/" + index_char;
+
+ INFO("\n uri_temp = %s", uri_temp.c_str());
+
+ if (rrs_schema_load(__resourceType, &__controlSchema, &__eventSchema) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_load() failed");
+ return false;
+ }
+
+ if (rrs_schema_create_data(__controlSchema, &__controlData) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() failed");
+ return false;
+ }
+
+ if (rrs_schema_create_data(__eventSchema, &__eventData) != RRS_ERROR_NONE) {
+ ERR("rrs_schema_create_data() failed");
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_create(&__interfaces);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_add(__interfaces, IOTCON_INTERFACE_DEFAULT);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_add() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_resource_interfaces_add(__interfaces, IOTCON_INTERFACE_BATCH);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_interfaces_add() Fail(%d)", ret);
+ return false;
+ }
+
+ __properties = IOTCON_RESOURCE_DISCOVERABLE;
+ __properties |= IOTCON_RESOURCE_OBSERVABLE;
+
+ ret = iotcon_observers_create(&__observers);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_observers_create() Fail");
+ return false;
+ }
+
+ ret = iotcon_resource_types_create(&resource_types);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_types_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_resource_types_add(resource_types, resource_name);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_types_add() Fail(%d)", ret);
+ iotcon_resource_types_destroy(resource_types);
+ return false;
+ }
+
+ __uriPath = strdup(uri_temp.c_str());
+ if (__uriPath == NULL) {
+ ERR("strdup(%s) Fail", uri);
+ return false;
+ }
+
+ __name = strdup(resource_name);
+ if (__name == NULL) {
+ ERR("strdup(%s) Fail", __name);
+ free(__uriPath);
+ return false;
+ }
+
+ INFO("%s Resource Creation initiated!", __uriPath);
+
+ ret = iotcon_resource_create(__uriPath, resource_types, __interfaces, __properties, __request_handler, user_data, &__handle);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_resource_create() Fail");
+ free(__uriPath);
+ free(__name);
+ iotcon_resource_types_destroy(resource_types);
+ return false;
+ }
+
+ iotcon_resource_types_destroy(resource_types);
+
+ return true;
+}
+
+void ResourceServer::freeResource()
+{
+ iotcon_observers_destroy(__observers);
+ iotcon_resource_interfaces_destroy(__interfaces);
+ free(__name);
+ free(__uriPath);
+}
+
+bool ResourceServer::requestHandlerGet(const iotcon_request_h request)
+{
+ iotcon_representation_h repr;
+
+ DBG("Handling a GET Control request");
+
+ if (iotcon_representation_create(&repr) != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_create() Fail");
+ return false;
+ }
+
+ rrs_control_data_set_int(__controlData, "accelerometer", Server::__get_instance().getResourceCount(RRS_RESOURCE_ACCELEROMETER));
+ rrs_control_data_set_int(__controlData, "proximity", Server::__get_instance().getResourceCount(RRS_RESOURCE_PROXIMITY));
+
+ setControlRepresentation(&repr);
+ if (repr == NULL) {
+ ERR("set_representation() Fail");
+ return false;
+ }
+
+ if (!sendResponse(request, repr, IOTCON_RESPONSE_OK)) {
+ ERR("send_response() Fail");
+ iotcon_representation_destroy(repr);
+ return false;
+ }
+
+ iotcon_representation_destroy(repr);
+
+ return true;
+}
+
+bool ResourceServer::requestHandlerPut(const iotcon_request_h request, BrokerResource &broker_resource)
+{
+ int ret;
+ iotcon_representation_h repr;
+
+ DBG("Handling a PUT control request");
+
+ ret = iotcon_representation_create(&repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_representation_create() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_request_get_representation(request, &repr);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_representation() Fail(%d)", ret);
+ return false;
+ }
+
+ if (!getControlRepresentation(repr)) {
+ ERR("get_representation() Fail(%d)", ret);
+ return false;
+ }
+
+ rrs_data_clone(__controlData, &(broker_resource.data));
+
+ ResourceQueue::__transmit_control_instance().push(broker_resource);
+
+ if (!sendResponse(request, repr, IOTCON_RESPONSE_OK)) {
+ ERR("send_response() Fail(%d)", ret);
+ return false;
+ }
+
+ iotcon_representation_destroy(repr);
+
+ return true;
+}
+
+bool ResourceServer::requestHandlerDelete(const iotcon_request_h request)
+{
+ int ret, observe_id;
+ DBG("Handling a DELETE request");
+
+ // Remove only observers when resource client is deleted. Deleting static Tizen resources in not allowed
+ ret = iotcon_request_get_observe_id(request, &observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_request_get_observe_id() Fail(%d)", ret);
+ return false;
+ }
+
+ ret = iotcon_observers_remove(__observers, observe_id);
+ if (ret != IOTCON_ERROR_NONE) {
+ ERR("iotcon_observers_remove() Fail(%d)", ret);
+ return false;
+ }
+
+ if (!sendResponse(request, NULL, IOTCON_RESPONSE_RESOURCE_DELETED)) {
+ ERR("send_response() Fail(%d)", ret);
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _RESOURCE_SERVER_H_
+#define _RESOURCE_SERVER_H_
+
+#include "rrs.h"
+#include "services_common.h"
+#include "schema.h"
+
+class ResourceServer {
+public:
+ ResourceServer();
+ virtual ~ResourceServer();
+ ResourceServer(const ResourceServer &obj);
+ ResourceServer& operator= (const ResourceServer &obj);
+ bool createDiscoveryResource(const char *uri, const unsigned char index, const char *type, void *user_data);
+ bool createResource(const char *uri, const unsigned char index, const char *type, void *user_data);
+ void freeResource();
+ bool sendResponse(const iotcon_request_h request, const iotcon_representation_h repr, const iotcon_response_result_e result);
+ bool setControlRepresentation(iotcon_representation_h *repr);
+ bool setEventRepresentation(iotcon_representation_h *repr);
+ bool getControlRepresentation(const iotcon_representation_h repr);
+ bool requestHandlerGet(const iotcon_request_h request);
+ bool requestHandlerPut(const iotcon_request_h request, BrokerResource &broker_resource);
+ bool requestHandlerDelete(const iotcon_request_h request);
+
+ static void __request_handler(const iotcon_resource_h resource, const iotcon_request_h request, void *user_data);
+ static void *__notify_observers(void *param);
+
+ rrs_h __rrs;
+ rrs_schema_h __controlSchema;
+ rrs_schema_h __eventSchema;
+ rrs_data_h __controlData;
+ rrs_data_h __eventData;
+ rrs_resource_e __resourceType;
+ RrsService __serviceType;
+ unsigned char __resourceIndex;
+ char *__uriPath;
+ char *__name;
+ iotcon_resource_interfaces_h __interfaces;
+ int __properties;
+ iotcon_resource_h __handle;
+ iotcon_observers_h __observers;
+};
+
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "Server.h"
+#include <thread>
+#include <vconf.h>
+#include "rrs.h"
+#include "ResourceServer.h"
+#include "common.h"
+
+
+using std::thread;
+
+Server::Server()
+{
+ __mainLoop = NULL;
+ /* Create RRS */
+ int ret = rrs_create(&__rrs);
+ if (ret != RRS_ERROR_NONE) {
+ ERR("rrs_create() Fail(%d)", ret);
+ return;
+ }
+}
+
+Server::~Server()
+{
+ stop();
+ rrs_destroy(__rrs);
+}
+
+std::string Server::get_device_name()
+{
+ static std::string g_device_name;
+
+ if(g_device_name.empty()) {
+ char* device_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
+ if (device_name == NULL) {
+ g_device_name = "Tizen";
+ } else {
+ g_device_name = device_name;
+ }
+ DBG("device_name: %s", g_device_name.c_str());
+ }
+
+ return g_device_name;
+}
+
+void Server::run(void)
+{
+ GMainLoop *loop;
+ ResourceServer server_temp;
+ ResourceServer *discovery = NULL, *accel = NULL, *proxi = NULL;
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ discovery = new ResourceServer;
+ accel = new ResourceServer;
+ proxi = new ResourceServer;
+
+ if (rrs_create(&(discovery->__rrs)) != RRS_ERROR_NONE) {
+ ERR("Error Creating RRS Handle!\n");
+ return;
+ }
+
+ if (rrs_create(&(accel->__rrs)) != RRS_ERROR_NONE) {
+ ERR("Error Creating RRS Handle!\n");
+ return;
+ }
+
+ if (rrs_create(&(proxi->__rrs)) != RRS_ERROR_NONE) {
+ ERR("Error Creating RRS Handle!\n");
+ return;
+ }
+
+ iotcon_set_device_name(get_device_name().c_str());
+
+ proxi->__serviceType = SENSOR_FRAMEWORK;
+ proxi->__resourceType = RRS_RESOURCE_PROXIMITY;
+ proxi->__resourceIndex = 1;
+
+ __serverInfo.insert(std::make_pair(proxi->__resourceType, proxi));
+
+ if (!proxi->createResource(PROXIMITY_RESOURCE_URI_PREFIX, proxi->__resourceIndex, PROXIMITY_RESOURCE_NAME, (void *) this)) {
+ ERR("Error Creating Resource!\n");
+ return;
+ }
+
+ accel->__serviceType = SENSOR_FRAMEWORK;
+ accel->__resourceType = RRS_RESOURCE_ACCELEROMETER;
+ accel->__resourceIndex = 1;
+
+ __serverInfo.insert(std::make_pair(accel->__resourceType, accel));
+
+ if (!accel->createResource(ACCELEROMETER_RESOURCE_URI_PREFIX, accel->__resourceIndex, ACCELEROMETER_RESOURCE_NAME, (void *) this)) {
+ ERR("Error creating resource!\n");
+ return;
+ }
+
+ discovery->__serviceType = ALL_SERVICES;
+ discovery->__resourceType = RRS_RESOURCE_DISCOVERY;
+ discovery->__resourceIndex = 1;
+
+ __serverInfo.insert(std::make_pair(discovery->__resourceType, discovery));
+
+ if (!discovery->createDiscoveryResource(DISCOVERY_RESOURCE_URI_PREFIX, discovery->__resourceIndex, DISCOVERY_RESOURCE_NAME, (void *) this)) {
+ ERR("Error Creating Resource!\n");
+ return;
+ }
+
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+
+ discovery->freeResource();
+ iotcon_resource_destroy(discovery->__handle);
+ deleteResource(RRS_RESOURCE_DISCOVERY, 1);
+
+ accel->freeResource();
+ iotcon_resource_destroy(accel->__handle);
+ deleteResource(RRS_RESOURCE_ACCELEROMETER, 1);
+
+ proxi->freeResource();
+ iotcon_resource_destroy(proxi->__handle);
+ deleteResource(RRS_RESOURCE_PROXIMITY, 1);
+
+ if (rrs_destroy(discovery->__rrs) != RRS_ERROR_NONE) {
+ ERR("Error Destroying RRS Handle!\n");
+ }
+
+ if (rrs_destroy(accel->__rrs) != RRS_ERROR_NONE) {
+ ERR("Error Destroying RRS Handle!\n");
+ }
+
+ if (rrs_destroy(proxi->__rrs) != RRS_ERROR_NONE) {
+ ERR("Error Destroying RRS Handle!\n");
+ }
+
+ delete discovery;
+ delete accel;
+ delete proxi;
+
+ return;
+}
+
+void Server::stop(void)
+{
+}
+
+void Server::addResource(const rrs_resource_e resource_type, ResourceServer *info)
+{
+ __serverInfo.insert(std::pair<unsigned int, ResourceServer *>((unsigned int)resource_type, info));
+}
+
+bool Server::deleteResource(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ server_info_iterator it = __serverInfo.find(resource_type);
+
+ if (it == __serverInfo.end()) {
+ ERR("Resource[%d] with index [%d] is not found", resource_type, resource_index);
+ return false;
+ }
+
+ for (it = __serverInfo.begin(); it != __serverInfo.end(); ++it) {
+ if ((it->second)->__resourceIndex == resource_index) {
+ __serverInfo.erase(it);
+ }
+ }
+
+ return true;
+}
+
+ResourceServer *Server::getResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ server_info_iterator it;
+
+ for (it = __serverInfo.begin(); it != __serverInfo.end(); ++it) {
+ if ((it->second)->__resourceType == resource_type) {
+ if ((it->second)->__resourceIndex == resource_index) {
+ return it->second;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+int Server::getResourceCount(const rrs_resource_e resource_type)
+{
+ int count = 0;
+ server_info_iterator it;
+
+ for (it = __serverInfo.begin(); it != __serverInfo.end(); ++it) {
+ if ((it->second)->__resourceType == resource_type) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+ResourceServer *Server::getResourceInfo(const iotcon_resource_h handle)
+{
+ server_info_iterator it;
+
+ for (it = __serverInfo.begin(); it != __serverInfo.end(); ++it) {
+ if ((it->second)->__handle == handle) {
+ return it->second;
+ }
+ }
+
+ return NULL;
+}
+
+
+Server& Server::__get_instance()
+{
+ static Server inst;
+ return inst;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _SERVER_H_
+#define _SERVER_H_
+
+#include <glib.h>
+#include <map>
+#include <string>
+#include "rrs.h"
+#include "ResourceServer.h"
+
+typedef std::multimap<unsigned int, ResourceServer *> server_info_map;
+typedef server_info_map::iterator server_info_iterator;
+
+class Server {
+public:
+ void run(void);
+ void stop(void);
+ static Server& __get_instance(void);
+
+ // resource_index is used in case there are multiple resources of same type on a device
+ void addResource(const rrs_resource_e resource_type, ResourceServer *info);
+ bool deleteResource(const rrs_resource_e resource_type, const unsigned char resource_index);
+ ResourceServer *getResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index);
+ int getResourceCount(const rrs_resource_e resource_type);
+ ResourceServer *getResourceInfo(const iotcon_resource_h handle);
+ std::string get_device_name(void);
+private:
+ Server();
+ ~Server();
+ bool createResource(const unsigned int resource);
+
+ GMainLoop *__mainLoop;
+ server_info_map __serverInfo;
+ rrs_h __rrs;
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "ServiceManager.h"
+#include <algorithm>
+#include "common.h"
+
+ServiceManager::ServiceManager()
+: __client(0)
+, __started(false)
+{
+}
+
+ServiceManager::~ServiceManager()
+{
+}
+
+bool ServiceManager::start()
+{
+ AUTOLOCK(__mutex);
+ AUTOLOCK(__clientMutex);
+
+ ++__client;
+
+ if (__client == 1) {
+ if (!onStart()) {
+ return false;
+ }
+
+ __started = true;
+ }
+
+ return true;
+}
+
+bool ServiceManager::stop(void)
+{
+ AUTOLOCK(__mutex);
+ AUTOLOCK(__clientMutex);
+
+ --__client;
+
+ if (__client == 0)
+ __started = false;
+
+ return true;
+}
+
+void ServiceManager::addControlResource(const rrs_resource_e resource_type, BrokerResource *info)
+{
+ __controlBrokerInfo.insert(std::make_pair((unsigned int)resource_type, info));
+}
+
+bool ServiceManager::deleteControlResource(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ control_broker_info::iterator it;
+ std::pair <control_broker_info::iterator, control_broker_info::iterator> range;
+
+ range = __controlBrokerInfo.equal_range(resource_type);
+ for (it = range.first; it != range.second; ++it) {
+ if (((*it).second)->resource_index == resource_index) {
+ __controlBrokerInfo.erase(it);
+ }
+ }
+
+ return true;
+}
+
+BrokerResource *ServiceManager::getControlResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ control_broker_info::iterator it;
+ std::pair <control_broker_info::iterator, control_broker_info::iterator> range;
+
+ range = __controlBrokerInfo.equal_range(resource_type);
+ for (it = range.first; it != range.second; ++it) {
+ if (((*it).second)->resource_index == resource_index) {
+ return ((*it).second);
+ }
+ }
+
+ return NULL;
+}
+
+void ServiceManager::addEventResource(const rrs_resource_e resource_type, BrokerResource *info)
+{
+ __eventBrokerInfo.insert(std::make_pair((unsigned int)resource_type, info));
+}
+
+bool ServiceManager::deleteEventResource(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ event_broker_info::iterator it;
+ std::pair <event_broker_info::iterator, event_broker_info::iterator> range;
+
+ range = __eventBrokerInfo.equal_range(resource_type);
+ for (it = range.first; it != range.second; ++it) {
+ if (((*it).second)->resource_index == resource_index) {
+ __eventBrokerInfo.erase(it);
+ }
+ }
+
+ return true;
+}
+
+BrokerResource *ServiceManager::getEventResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index)
+{
+ event_broker_info::iterator it;
+ std::pair <event_broker_info::iterator, event_broker_info::iterator> range;
+
+ range = __eventBrokerInfo.equal_range(resource_type);
+ for (it = range.first; it != range.second; ++it) {
+ if (((*it).second)->resource_index == resource_index) {
+ return ((*it).second);
+ }
+ }
+
+ return NULL;
+}
+
+bool ServiceManager::isStarted(void)
+{
+ bool ret_val;
+ AUTOLOCK(__mutex);
+ AUTOLOCK(__clientMutex);
+
+ ret_val = (__started == true) ? true : false;
+
+ return ret_val;
+}
+
+bool ServiceManager::addClient(const rrs_resource_e resource_type)
+{
+ if (!isSupported(resource_type)) {
+ ERR("Invalid resource type: 0x%x", resource_type);
+ return false;
+ }
+
+ AUTOLOCK(__clientInfoMutex);
+
+ ++(__clientInfo[resource_type]);
+ return true;
+}
+
+bool ServiceManager::deleteClient(const rrs_resource_e resource_type)
+{
+ if (!isSupported(resource_type)) {
+ ERR("Invalid resource type: 0x%x", resource_type);
+ return false;
+ }
+
+ AUTOLOCK(__clientInfoMutex);
+
+ auto iter = __clientInfo.find(resource_type);
+
+ if (iter == __clientInfo.end())
+ return false;
+
+ if (iter->second == 0)
+ return false;
+
+ --(iter->second);
+
+ return true;
+}
+
+unsigned int ServiceManager::getClientCnt(const rrs_resource_e resource_type)
+{
+ AUTOLOCK(__clientInfoMutex);
+
+ auto iter = __clientInfo.find(resource_type);
+
+ if (iter == __clientInfo.end())
+ return 0;
+
+ return iter->second;
+}
+
+bool ServiceManager::isSupported(const rrs_resource_e resource_type)
+{
+ //TO DO
+
+ return true;
+}
+
+void ServiceManager::setThread(working_func_t func, void *arg)
+{
+ __serviceThread.setContext(arg);
+ __serviceThread.setWorking(func);
+}
+
+
+bool ServiceManager::startThread(void)
+{
+ return __serviceThread.start();
+}
+
+bool ServiceManager::stopThread(void)
+{
+ return __serviceThread.pause();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _SERVICE_MANAGER_H_
+#define _SERVICE_MANAGER_H_
+
+#include <list>
+#include <map>
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include "services_common.h"
+#include "WorkerThread.h"
+#include "ResourceQueue.h"
+
+class ServiceManager {
+public:
+ typedef std::unordered_map<unsigned int, unsigned int> client_info;
+ typedef std::multimap<unsigned int, BrokerResource *> event_broker_info;
+ typedef std::multimap<unsigned int, BrokerResource *> control_broker_info;
+ typedef WorkerThread::trans_func_t working_func_t;
+
+ ServiceManager();
+ virtual ~ServiceManager();
+
+ bool start(void);
+ bool stop(void);
+ bool isStarted(void);
+ bool addClient(const rrs_resource_e resource_type);
+ bool deleteClient(const rrs_resource_e resource_type);
+ // resource_index is used in case there are multiple resources of same type on a device
+ void addControlResource(const rrs_resource_e resource_type, BrokerResource *info);
+ bool deleteControlResource(const rrs_resource_e resource_type, const unsigned char resource_index = 1);
+ BrokerResource *getControlResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index = 1);
+ void addEventResource(const rrs_resource_e resource_type, BrokerResource *info);
+ bool deleteEventResource(const rrs_resource_e resource_type, const unsigned char resource_index = 1);
+ BrokerResource *getEventResourceInfo(const rrs_resource_e resource_type, const unsigned char resource_index = 1);
+ bool isSupported(const rrs_resource_e resource_type);
+
+ virtual bool init(void) {return true;}
+ virtual RrsService getType(void) {return UNKNOWN_SERVICE;}
+ virtual bool processEvent(BrokerResource &packet) {return true;}
+ virtual bool processCommand(void) {return true;}
+ virtual const char* getName(void) {return NULL;}
+protected:
+ void setThread(working_func_t func, void *arg);
+ bool startThread(void);
+ bool stopThread(void);
+ unsigned int getClientCnt(const rrs_resource_e resource_type);
+
+ virtual bool onStart(void) {return true;}
+ virtual bool onStop(void) {return true;}
+
+ Mutex __mutex;
+ Mutex __clientMutex;
+ unsigned int __client;
+ client_info __clientInfo;
+ control_broker_info __controlBrokerInfo;
+ event_broker_info __eventBrokerInfo;
+ Mutex __clientInfoMutex;
+ bool __started;
+private:
+ WorkerThread __serviceThread;
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "WorkerThread.h"
+#include <thread>
+#include "common.h"
+
+using std::thread;
+
+WorkerThread::WorkerThread()
+: __state(WORKER_STATE_INITIAL)
+, __context(NULL)
+, __threadCreated(false)
+{
+ for (int i = 0; i < TRANS_FUNC_CNT; ++i)
+ __transFunc[i] = NULL;
+}
+
+WorkerThread::~WorkerThread()
+{
+ stop();
+}
+
+bool WorkerThread::transitionFunction(trans_func_index index)
+{
+ if (__transFunc[index] != NULL) {
+ if(!__transFunc[index](__context)) {
+ _T("Transition[%d] function returning false", index);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+WorkerThread::worker_state_t WorkerThread::getState(void)
+{
+ lock l(__mutex);
+ return __state;
+}
+
+
+bool WorkerThread::start(void)
+{
+ lock l(__mutex);
+
+ if (__state == WORKER_STATE_WORKING) {
+ _T("Worker thread is already working");
+ return true;
+ }
+
+ if ((__state == WORKER_STATE_INITIAL) || (__state == WORKER_STATE_STOPPED)) {
+ __state = WORKER_STATE_WORKING;
+
+ if (!__threadCreated) {
+ thread th(&WorkerThread::main, this);
+ th.detach();
+ }
+ return true;
+ } else if (__state == WORKER_STATE_PAUSED) {
+ __state = WORKER_STATE_WORKING;
+ __condWorking.notify_one();
+ return true;
+ }
+
+ _T("Failed to start, because current state(%d) is not for START", __state);
+
+ return false;
+}
+
+bool WorkerThread::stop(void)
+{
+ lock l(__mutex);
+
+ if (__state == WORKER_STATE_STOPPED) {
+ _T("Worker thread is already stopped");
+ return true;
+ }
+
+ if ((__state == WORKER_STATE_WORKING) || (__state == WORKER_STATE_PAUSED)) {
+ if (__state == WORKER_STATE_PAUSED)
+ __condWorking.notify_one();
+
+ __state = WORKER_STATE_STOPPED;
+ return true;
+ }
+
+ _T("Failed to stop, because current state(%d) is not for STOP", __state);
+ return false;
+}
+
+bool WorkerThread::pause(void)
+{
+ lock l(__mutex);
+
+ if (__state == WORKER_STATE_PAUSED) {
+ _T("Worker thread is already paused");
+ return true;
+ }
+
+ if (__state == WORKER_STATE_WORKING) {
+ __state = WORKER_STATE_PAUSED;
+ return true;
+ }
+
+ _T("Failed to pause, because current state(%d) is not for PAUSE", __state);
+
+ return false;
+}
+
+bool WorkerThread::resume(void)
+{
+ lock l(__mutex);
+
+ if (__state == WORKER_STATE_WORKING) {
+ _T("Worker thread is already working");
+ return true;
+ }
+
+ if (__state == WORKER_STATE_PAUSED) {
+ __state = WORKER_STATE_WORKING;
+ __condWorking.notify_one();
+ return true;
+ }
+
+ _T("Failed to resume, because current state(%d) is not for RESUME", __state);
+ return false;
+}
+
+
+/*
+ * After state changed to STOPPED, it should not access member fields,
+ because some transition funciton of STOPPED delete this pointer
+ */
+
+void WorkerThread::main(void)
+{
+ _T("Worker thread(0x%x) is created", std::this_thread::get_id());
+
+ transitionFunction(STARTED);
+
+ while (true) {
+ worker_state_t state;
+ state = getState();
+
+ if (state == WORKER_STATE_WORKING) {
+ if (!transitionFunction(WORKING)) {
+ __state = WORKER_STATE_STOPPED;
+ _T("Worker thread(0x%x) exits from working state", std::this_thread::get_id());
+ __threadCreated = false;
+ transitionFunction(STOPPED);
+ break;
+ }
+ continue;
+ }
+
+ ulock u(__mutex);
+
+ if (__state == WORKER_STATE_PAUSED) {
+ transitionFunction(PAUSED);
+
+ _T("Worker thread(0x%x) is paused", std::this_thread::get_id());
+ __condWorking.wait(u);
+
+ if (__state == WORKER_STATE_WORKING) {
+ transitionFunction(RESUMED);
+ _T("Worker thread(0x%x) is resumed", std::this_thread::get_id());
+ } else if (__state == WORKER_STATE_STOPPED) {
+ __threadCreated = false;
+ transitionFunction(STOPPED);
+ break;
+ }
+ } else if (__state == WORKER_STATE_STOPPED) {
+ __threadCreated = false;
+ transitionFunction(STOPPED);
+ break;
+ }
+ }
+ _T("Worker thread(0x%x)'s main is terminated", std::this_thread::get_id());
+}
+
+void WorkerThread::setStarted(trans_func_t func)
+{
+ __transFunc[STARTED] = func;
+}
+
+void WorkerThread::setStopped(trans_func_t func)
+{
+ __transFunc[STOPPED] = func;
+}
+
+void WorkerThread::setPaused(trans_func_t func)
+{
+ __transFunc[PAUSED] = func;
+}
+
+void WorkerThread::setResumed(trans_func_t func)
+{
+ __transFunc[RESUMED] = func;
+}
+
+void WorkerThread::setWorking(trans_func_t func)
+{
+ __transFunc[WORKING] = func;
+}
+
+void WorkerThread::setContext(void *ctx)
+{
+ __context = ctx;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 _WORKER_THREAD_H_
+#define _WORKER_THREAD_H_
+
+#include <mutex>
+#include <condition_variable>
+
+class WorkerThread {
+public:
+ enum worker_state_t {
+ WORKER_STATE_INITIAL,
+ WORKER_STATE_WORKING,
+ WORKER_STATE_PAUSED,
+ WORKER_STATE_STOPPED,
+ };
+
+ typedef bool(*trans_func_t)(void *data);
+
+ WorkerThread();
+ virtual ~WorkerThread();
+
+ bool start(void);
+ bool stop(void);
+ bool pause(void);
+ bool resume(void);
+ worker_state_t getState(void);
+ void setStarted(trans_func_t func);
+ void setStopped(trans_func_t func);
+ void setPaused(trans_func_t func);
+ void setResumed(trans_func_t func);
+ void setWorking(trans_func_t func);
+ void setContext(void *ctx);
+
+private:
+ enum trans_func_index {
+ STARTED = 0,
+ STOPPED,
+ PAUSED,
+ RESUMED,
+ WORKING,
+ TRANS_FUNC_CNT,
+ };
+
+ typedef std::lock_guard<std::mutex> lock;
+ typedef std::unique_lock<std::mutex> ulock;
+
+ bool transitionFunction(trans_func_index index);
+ void main(void);
+
+ worker_state_t __state;
+ void *__context;
+ std::mutex __mutex;
+ std::condition_variable __condWorking;
+ bool __threadCreated;
+ trans_func_t __transFunc[TRANS_FUNC_CNT];
+};
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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 "rrs.h"
+#include <signal.h>
+#include <fstream>
+#include "common.h"
+#include "Server.h"
+#include "PluginLoader.h"
+
+using std::fstream;
+
+bool get_proc_name(pid_t pid, char *process_name)
+{
+ FILE *fp;
+ char buf[NAME_MAX];
+ char filename[PATH_MAX];
+
+ sprintf(filename, "/proc/%d/stat", pid);
+ fp = fopen(filename, "r");
+
+ if (fp == NULL)
+ return false;
+
+ if (fscanf(fp, "%*s (%[^)]", buf) < 1) {
+ fclose(fp);
+ return false;
+ }
+
+ strncpy(process_name, buf, NAME_MAX-1);
+ process_name[NAME_MAX-1] = '\0';
+ fclose(fp);
+
+ return true;
+}
+
+static void sig_term_handler(int signo, siginfo_t *info, void *data)
+{
+ char proc_name[NAME_MAX];
+
+ get_proc_name(info->si_pid, proc_name);
+
+ ERR("Received SIGTERM(%d) from %s(%d)\n", signo, proc_name, info->si_pid);
+ exit(EXIT_SUCCESS);
+}
+
+static void signal_init(void)
+{
+ struct sigaction sig_act;
+ memset(&sig_act, 0, sizeof(struct sigaction));
+
+ sig_act.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sig_act, NULL);
+ sigaction(SIGPIPE, &sig_act, NULL);
+
+ sig_act.sa_handler = NULL;
+ sig_act.sa_sigaction = sig_term_handler;
+ sig_act.sa_flags = SA_SIGINFO;
+ sigaction(SIGTERM, &sig_act, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ INFO("Remote Resource Service started");
+
+ signal_init();
+
+ PluginLoader::__get_instance().loadPlugins();
+
+ Server::__get_instance().run();
+
+ Server::__get_instance().stop();
+
+ INFO("Remote Resource Service terminated");
+ return 0;
+}
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(rrs-test CXX)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(rrs-test-pkgs REQUIRED glib-2.0 dlog sensor iotcon)
+
+INCLUDE_DIRECTORIES(include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+FILE(GLOB rrs-test-srcs *.c *.cpp)
+
+FOREACH(flag ${rrs-test-pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${rrs-test-pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/client)
+include_directories(${CMAKE_SOURCE_DIR}/src/common)
+include_directories(${CMAKE_SOURCE_DIR}/src/server)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lrt -ldl -pthread -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
+
+add_executable(${PROJECT_NAME} ${rrs-test-srcs})
+
+target_link_libraries(${PROJECT_NAME} ${rrs-test-pkgs_LDFLAGS}
+ "rrs-common"
+ "rrs-client"
+ )
+
+install(TARGETS ${PROJECT_NAME} DESTINATION bin)
--- /dev/null
+/*
+ * 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 "rrs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <tizen_type.h>
+#include "common.h"
+
+#define DEFAULT_INTERVAL 100 //ms
+
+void _discovery_handler_cb(rrs_error_e result, rrs_resource_h resource, rrs_control_data_h control_data, void *user_data);
+void _observe_accel_cb(rrs_error_e result, rrs_event_data_h event_data, void *user_data);
+void _observe_proxi_cb(rrs_error_e result, rrs_event_data_h event_data, void *user_data);
+bool _found_discovery_cb(rrs_error_e result, rrs_resource_h resource, void *user_data);
+bool _found_accel_cb(rrs_error_e result, rrs_resource_h resource, void *user_data);
+bool _found_proxi_cb(rrs_error_e result, rrs_resource_h resource, void *user_data);
+
+rrs_h rrs;
+rrs_resource_h accel_resource;
+rrs_resource_h proxi_resource;
+
+void _observe_accel_cb(rrs_error_e result, rrs_event_data_h event_data, void *user_data)
+{
+ static int counter = 0;
+ rrs_resource_e *resource_type = (rrs_resource_e *) user_data;
+
+ if (*resource_type == RRS_RESOURCE_ACCELEROMETER) {
+ double x = .0;
+ double y = .0;
+ double z = .0;
+ rrs_event_data_get_double(event_data, "x", &x);
+ rrs_event_data_get_double(event_data, "y", &y);
+ rrs_event_data_get_double(event_data, "z", &z);
+
+ INFO("Accelerometer Event X=%f, Y=%f, Z=%f", x, y, z);
+ if(++counter == 20) {
+ rrs_control_data_h control_data;
+
+ rrs_control_data_create(RRS_RESOURCE_ACCELEROMETER, &control_data);
+
+ rrs_control_data_set_bool(control_data, "connect_sensor", false);
+ rrs_control_data_set_bool(control_data, "disconnect_sensor", true);
+ rrs_control_data_set_int(control_data, "interval", 0);
+ rrs_control_data_set_int(control_data, "max_batch_latency", 0);
+ rrs_control_data_set_bool(control_data, "register_event", false);
+ rrs_control_data_set_bool(control_data, "unregister_event", true);
+ rrs_control_data_set_bool(control_data, "get_data", false);
+
+ if(rrs_resource_send_control(accel_resource, control_data, NULL, NULL) != RRS_ERROR_NONE)
+ return;
+
+ rrs_control_data_destroy(control_data);
+
+ rrs_resource_unsubscribe_event(accel_resource);
+ }
+ }
+}
+
+void _observe_proxi_cb(rrs_error_e result, rrs_event_data_h event_data, void *user_data)
+{
+ static int counter = 0;
+ rrs_resource_e *resource_type = (rrs_resource_e *) user_data;
+
+ if (*resource_type == RRS_RESOURCE_PROXIMITY) {
+ int state = 0;
+ rrs_event_data_get_int(event_data, "state", &state);
+
+ if (state == 0)
+ INFO("Proximity ON");
+ else if (state == 5)
+ INFO("Proximity OFF");
+
+ if(++counter == 20) {
+ rrs_control_data_h control_data;
+
+ rrs_control_data_create(RRS_RESOURCE_PROXIMITY, &control_data);
+
+ rrs_control_data_set_bool(control_data, "connect_sensor", false);
+ rrs_control_data_set_bool(control_data, "disconnect_sensor", true);
+ rrs_control_data_set_int(control_data, "interval", 0);
+ rrs_control_data_set_int(control_data, "max_batch_latency", 0);
+ rrs_control_data_set_bool(control_data, "register_event", false);
+ rrs_control_data_set_bool(control_data, "unregister_event", true);
+ rrs_control_data_set_bool(control_data, "get_data", false);
+
+ if(rrs_resource_send_control(proxi_resource, control_data, NULL, NULL) != RRS_ERROR_NONE)
+ return;
+
+ rrs_control_data_destroy(control_data);
+
+ rrs_resource_unsubscribe_event(proxi_resource);
+ }
+ }
+}
+
+bool _found_accel_cb(rrs_error_e result, rrs_resource_h resource, void *user_data)
+{
+ rrs_control_data_h control_data;
+ INFO("Registering for accelerometer observe mode");
+
+ accel_resource = resource;
+
+ rrs_resource_e *resource_type = (rrs_resource_e *) user_data;
+
+ if (*resource_type == RRS_RESOURCE_ACCELEROMETER) {
+ rrs_control_data_create(RRS_RESOURCE_ACCELEROMETER, &control_data);
+ if(rrs_resource_subscribe_event(resource, _observe_accel_cb, user_data) != RRS_ERROR_NONE)
+ return false;
+ } else {
+ ERR("Wrong callback triggered - Error in RRS library!");
+ return false;
+ }
+
+ rrs_control_data_set_bool(control_data, "connect_sensor", true);
+ rrs_control_data_set_bool(control_data, "disconnect_sensor", false);
+ rrs_control_data_set_int(control_data, "interval", 1000);
+ rrs_control_data_set_int(control_data, "max_batch_latency", 0);
+ rrs_control_data_set_bool(control_data, "register_event", true);
+ rrs_control_data_set_bool(control_data, "unregister_event", false);
+ rrs_control_data_set_bool(control_data, "get_data", false);
+
+ INFO("Sending initial control data for accelerometer resource");
+
+ if(rrs_resource_send_control(resource, control_data, NULL, NULL) != RRS_ERROR_NONE)
+ return false;
+
+ rrs_control_data_destroy(control_data);
+
+ return true;
+}
+
+bool _found_proxi_cb(rrs_error_e result, rrs_resource_h resource, void *user_data)
+{
+ rrs_control_data_h control_data;
+ INFO("Registering for proximity observe mode");
+ proxi_resource = resource;
+
+ rrs_resource_e *resource_type = (rrs_resource_e *) user_data;
+
+ if (*resource_type == RRS_RESOURCE_PROXIMITY) {
+ rrs_control_data_create(RRS_RESOURCE_PROXIMITY, &control_data);
+ if(rrs_resource_subscribe_event(resource, _observe_proxi_cb, user_data) != RRS_ERROR_NONE)
+ return false;
+ } else {
+ ERR("Wrong callback triggered - Error in RRS library!");
+ return false;
+ }
+
+ rrs_control_data_set_bool(control_data, "connect_sensor", true);
+ rrs_control_data_set_bool(control_data, "disconnect_sensor", false);
+ rrs_control_data_set_int(control_data, "interval", 0);
+ rrs_control_data_set_int(control_data, "max_batch_latency", 0);
+ rrs_control_data_set_bool(control_data, "register_event", true);
+ rrs_control_data_set_bool(control_data, "unregister_event", false);
+ rrs_control_data_set_bool(control_data, "get_data", false);
+
+ INFO("Sending initial control data for proximity resource");
+
+ if(rrs_resource_send_control(resource, control_data, NULL, NULL) != RRS_ERROR_NONE)
+ return false;
+
+ rrs_control_data_destroy(control_data);
+
+ return true;
+}
+
+void _discovery_handler_cb(rrs_error_e result, rrs_resource_h resource, rrs_control_data_h control_data, void *user_data)
+{
+ int accel_count = 0;
+ int proxi_count = 0;
+ char *device_id;
+
+ INFO("Receiving control data");
+
+ rrs_h *rrs_temp = (rrs_h *) user_data;
+
+ rrs_control_data_get_int(control_data, "accelerometer", &accel_count);
+ rrs_control_data_get_int(control_data, "proximity", &proxi_count);
+
+ INFO("Discovery Information: Accelerometer Count = %d, Proximity Sensor Count = %d", accel_count, proxi_count);
+
+ if (accel_count > 0) {
+ rrs_resource_e *accel_type = (rrs_resource_e *) malloc(sizeof(rrs_resource_e));
+
+ *accel_type = RRS_RESOURCE_ACCELEROMETER;
+ rrs_resource_find(*rrs_temp, *accel_type, _found_accel_cb, (void *) accel_type);
+ }
+
+ if (proxi_count > 0) {
+ rrs_resource_e *proxi_type = (rrs_resource_e *) malloc(sizeof(rrs_resource_e));
+
+ *proxi_type = RRS_RESOURCE_PROXIMITY;
+ rrs_resource_find(*rrs_temp, *proxi_type, _found_proxi_cb, (void *) proxi_type);
+ }
+
+ rrs_resource_get_device_id(resource, &device_id);
+
+ INFO("_discovery_handler_cb device_id - %s", device_id);
+}
+
+bool _found_discovery_cb(rrs_error_e result, rrs_resource_h resource, void *user_data)
+{
+ char *device_id;
+ INFO("Getting discovery resource information");
+
+ if(rrs_resource_monitor_control(resource, _discovery_handler_cb, user_data) != RRS_ERROR_NONE) {
+ ERR("Error receiving discovery information from Server!");
+ return false;
+ }
+
+ rrs_resource_get_device_id(resource, &device_id);
+
+ INFO("_found_discovery_cb device_id - %s", device_id);
+
+ return true;
+}
+
+int main(int argc, char **argv)
+{
+ GMainLoop *loop;
+
+ rrs_resource_e *discovery_resource_type = (rrs_resource_e *) malloc(sizeof(rrs_resource_e));
+
+ *discovery_resource_type = RRS_RESOURCE_DISCOVERY;
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ if (rrs_create(&rrs) != RRS_ERROR_NONE) {
+ printf("Error Creating RRS Handle!\n");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ rrs_resource_find(rrs, *discovery_resource_type, _found_discovery_cb, (void *) &rrs);
+
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+
+ free(discovery_resource_type);
+ //free(proxi_type);
+ //free(accel_type);
+
+ if (rrs_destroy(rrs) != RRS_ERROR_NONE) {
+ printf("Error Destroying RRS Handle!\n");
+ return RRS_ERROR_INVALID_PARAMETER;
+ }
+
+ return 0;
+}