From: Jin Yoon Date: Thu, 9 Aug 2018 00:04:49 +0000 (+0900) Subject: Smart blind : initial version X-Git-Url: http://review.tizen.org/git/?p=apps%2Fnative%2Fst-things-blind.git;a=commitdiff_plain;h=b12040d13b411ddddbd8f755b9d9629c3e8bdb6f Smart blind : initial version Change-Id: Ib6e890da758f3896b5ea9406f2d2d55a4f360038 --- diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..f557db1 --- /dev/null +++ b/.cproject @@ -0,0 +1,734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.exportMap b/.exportMap new file mode 100644 index 0000000..de30516 --- /dev/null +++ b/.exportMap @@ -0,0 +1,5 @@ +{ + global: main; + _IO_*; + local: *; +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b0adc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/Debug/ +/SA_Report/ diff --git a/.project b/.project new file mode 100644 index 0000000..580a699 --- /dev/null +++ b/.project @@ -0,0 +1,46 @@ + + + smart-blind + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + 1532670384450 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + 1532670384528 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-project_def.prop + + + + diff --git a/.smartthingsapp b/.smartthingsapp new file mode 100644 index 0000000..e69de29 diff --git a/.tproject b/.tproject new file mode 100644 index 0000000..f857534 --- /dev/null +++ b/.tproject @@ -0,0 +1,12 @@ + + + + + iot-headless-4.0 + + + + + + + diff --git a/inc/log.h b/inc/log.h new file mode 100644 index 0000000..d958e2e --- /dev/null +++ b/inc/log.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __POSITION_FINDER_SERVER_H__ +#define __POSITION_FINDER_SERVER_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "TT" + +#if !defined(_D) +#define _D(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(DBG) +#define DBG(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_I) +#define _I(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_W) +#define _W(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_E) +#define _E(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + _E(fmt, ##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return val; \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + _E(fmt, ##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ +} while (0) + +#define ret_if(expr) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ +} while (0) + +#define goto_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> goto", #expr); \ + goto val; \ + } \ +} while (0) + +#define break_if(expr) { \ + if (expr) { \ + _E("(%s) -> break", #expr); \ + break; \ + } \ +} + +#define continue_if(expr) { \ + if (expr) { \ + _E("(%s) -> continue", #expr); \ + continue; \ + } \ +} + + + +#endif /* __POSITION_FINDER_SERVER_H__ */ diff --git a/inc/resource.h b/inc/resource.h new file mode 100755 index 0000000..cf59cb9 --- /dev/null +++ b/inc/resource.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __POSITION_FINDER_RESOURCE_H__ +#define __POSITION_FINDER_RESOURCE_H__ + +#include + +#include "resource_internal.h" +#include "resource/resource_illuminance_sensor.h" +#include "resource/resource_servo_motor.h" + +#endif /* __POSITION_FINDER_RESOURCE_H__ */ diff --git a/inc/resource/resource_illuminance_sensor.h b/inc/resource/resource_illuminance_sensor.h new file mode 100644 index 0000000..05523ca --- /dev/null +++ b/inc/resource/resource_illuminance_sensor.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_H__ +#define __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_H__ + +/** + * @brief Reads the value of i2c bus connected illuminance sensor. + * @param[in] i2c_bus The i2c bus number that the slave device is connected + * @param[out] out_value The value read by the illuminance sensor + * @return 0 on success, otherwise a negative error value + * @see If the i2c bus is not open, creates i2c handle before reading data from the i2c slave device. + */ +extern int resource_read_illuminance_sensor(int i2c_bus, uint32_t *out_value); + +#endif /* __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_H__ */ + diff --git a/inc/resource/resource_illuminance_sensor_internal.h b/inc/resource/resource_illuminance_sensor_internal.h new file mode 100644 index 0000000..0bfec0a --- /dev/null +++ b/inc/resource/resource_illuminance_sensor_internal.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_INTERNAL_H__ +#define __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_INTERNAL_H__ + +/** + * @brief Destory the i2c handle and changes the gpio pin state to the close(0). + */ +extern void resource_close_illuminance_sensor(void); + +#endif /* __POSITION_FINDER_RESOURCE_ILLUMINANCE_SENSOR_INTERNAL_H__ */ + diff --git a/inc/resource/resource_servo_motor.h b/inc/resource/resource_servo_motor.h new file mode 100644 index 0000000..43a0916 --- /dev/null +++ b/inc/resource/resource_servo_motor.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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_SERVO_MOTOR_H__ +#define __RESOURCE_SERVO_MOTOR_H__ + +void resource_close_servo_motor(void); + +/** + * This module is sample codes to handling Servo motors in Tizen platform. + * Hardware is configured with HS-53, + * Bus : 0 + * Pin : 2 + * @param[in] duty_cycle_ms + * @return 0 on success, otherwise a negative error value + */ +int resource_set_servo_motor_value(double duty_cycle_ms); + +#endif /* __RESOURCE_SERVO_MOTOR_H__ */ diff --git a/inc/resource_internal.h b/inc/resource_internal.h new file mode 100755 index 0000000..acea1e1 --- /dev/null +++ b/inc/resource_internal.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __POSITION_FINDER_RESOURCE_INTERNAL_H__ +#define __POSITION_FINDER_RESOURCE_INTERNAL_H__ + +#include + +#include "resource/resource_illuminance_sensor_internal.h" + +#define PIN_MAX 40 + +struct _resource_s { + int opened; + peripheral_gpio_h sensor_h; + void (*close) (int); +}; +typedef struct _resource_s resource_s; + +typedef void (*resource_read_cb)(double value, void *data); + +struct _resource_read_cb_s { + resource_read_cb cb; + void *data; + int pin_num; +}; +typedef struct _resource_read_cb_s resource_read_s; + +extern resource_s *resource_get_info(int pin_num); +extern void resource_close_all(void); + +#endif /* __POSITION_FINDER_RESOURCE_INTERNAL_H__ */ diff --git a/inc/sensor-data.h b/inc/sensor-data.h new file mode 100644 index 0000000..d6b3001 --- /dev/null +++ b/inc/sensor-data.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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_DATA_H__ +#define __SENSOR_DATA_H__ + +#include + +typedef enum { + SENSOR_DATA_TYPE_NONE = 0, + SENSOR_DATA_TYPE_INT, + SENSOR_DATA_TYPE_UINT, + SENSOR_DATA_TYPE_BOOL, + SENSOR_DATA_TYPE_DOUBLE, + SENSOR_DATA_TYPE_STR, +} sensor_data_type_e; + +typedef struct __sensor_data_s sensor_data; + +sensor_data *sensor_data_new(sensor_data_type_e type); +void sensor_data_free(sensor_data *data); + +int sensor_data_set_int(sensor_data *data, int value); +int sensor_data_set_uint(sensor_data *data, unsigned int value); +int sensor_data_set_bool(sensor_data *data, bool value); +int sensor_data_set_double(sensor_data *data, double value); +int sensor_data_set_string(sensor_data *data, const char *value, unsigned int size); + +int sensor_data_get_int(sensor_data *data, int *value); +int sensor_data_get_uint(sensor_data *data, unsigned int *value); +int sensor_data_get_bool(sensor_data *data, bool *value); +int sensor_data_get_double(sensor_data *data, double *value); +int sensor_data_get_string(sensor_data *data, const char **value); + +#endif /* __SENSOR_DATA_H__ */ diff --git a/inc/st_things.h b/inc/st_things.h new file mode 100644 index 0000000..31340a5 --- /dev/null +++ b/inc/st_things.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __ST_THINGS_H__ +#define __ST_THINGS_H__ + +#include +#include + +#ifdef __ST_THINGS_RTOS__ +#include +#else +#include "st_things_types.h" +#endif // __ST_THINGS_RTOS__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Set prefix paths (ReadOnly and ReadWrite) for configuration files for the device. + * This is Optional API, and should be used if relative location is used in + * filePath variable in JSON Configuration file. + * @param[in] ro_path Prefix Path for Read Only directory location. + * @param[in] rw_path Prefix Path for Read Write directory location. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter(both ro_path and rw_path are NULL). + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED Stack already initialized. + * To set Prefix Paths, stack should be deinitilized first by calling st_things_deinitialize(). + * @retval #ST_THINGS_ERROR_STACK_RUNNING Stack is currently running. + * To set Prefix Paths, stack should be stopped first by calling st_things_stop() + * and then deinitialized by calling st_things_deinitialize(). + */ +int st_things_set_configuration_prefix_path(const char* ro_path, const char* rw_path); + +/** + * @brief Initializes things stack and returns whether easy-setup is completed or not. + * Easy-setup enable users to acquire the ownership of things and to connect the things with the cloud. + * After performing easy-setup, users can access things from anywhere through the cloud. + * In things stack, easy-setup is a primary and the first operation to be performed on the thing. + * Application running on the thing can know whether easy-setup is done already or not. + * If easy-setup is done, app can start the things stack by calling st_things_start(). + * If easy-setup is not done, app can either wait for the user interaction before starting the things stack or + * start the things stack directly without waiting for any events(This case is for those things which doesn't + * support input capability and for all other unknown cases). + * To use a new json file after initialization, stack should be deinitialized + * and stopped(if its started already). + * @param[in] json_path Path to Json file which defines a thing. Definition includes the device information, + * resources and their properties, configuration info for connectivity and easy-setup, etc. + * @param[out] easysetup_complete Indicates whether easysetup is completed already or not. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED Stack already initialized. + * To initialize again, stack should be deinitilized first by calling st_things_deinitialize(). + * @retval #ST_THINGS_ERROR_STACK_RUNNING Stack is currently running. + * To initialize again, stack should be stopped first by calling st_things_stop() + * and then deinitialized by calling st_things_deinitialize(). + */ +int st_things_initialize(const char *json_path, bool *easysetup_complete); + +/** + * @brief Deinitializes things stack. + * Stack should have been initialized before calling this API. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized. + * Initialize the stack by calling st_things_initialize(). + * @retval #ST_THINGS_ERROR_STACK_RUNNING Stack is currently running. + * Before deinitialize, stack needs to be stopped by calling st_things_stop(). + */ +int st_things_deinitialize(void); + +/** + * @brief Callback for handling GET request. + * @param[in] req_msg GET request message. + * @param[out] resp_rep Representation that will be set to payload of response. + * @return @c true in case of success, otherwise @c false + */ +typedef bool (*st_things_get_request_cb)(st_things_get_request_message_s *req_msg, st_things_representation_s *resp_rep); + +/** + * @brief Callback for handling SET(POST) request. + * @param[in] req_msg SET request message. + * @param[out] resp_rep Representation that will be set to payload of response. + * @return @c true in case of success, otherwise @c false + */ +typedef bool (*st_things_set_request_cb)(st_things_set_request_message_s *req_msg, st_things_representation_s *resp_rep); + +/** + * @brief Callback registration function for handling request messages. + * @details The callbacks ensure that a request message will be carried with one of the resource uris from json file of st_things_start(). + * @remarks Only one callback function can be set with this API.\n + * If multiple callbacks are set, the last one is registered only.\n + * And the callbacks are called in the internal thread, which is not detached,\n + * so application should return it to get the next callbacks. + * @param[in] get_cb Reference of the callback function to handle GET request. + * @param[in] set_cb Reference of the callback function to handle SET(POST) request. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + */ +int st_things_register_request_cb(st_things_get_request_cb get_cb, st_things_set_request_cb set_cb); + +/** + * @brief Starts things stack. + * Parses the thing definition(whose path is passed to st_things_initialize(), configures the thing, + * creates the resources and prepares it for easy-setup. + * If easy-setup is not done yet, onboarding will be started using either SoftAP or BLE connection. + * Onboarding creates an ad-hoc network between the thing and the client for performing easy-setup. + * If easy-setup is already done, thing will be connected with the cloud. + * Application can know whether easy-setup is done or not through st_things_initialize API. + * Stack should have been initialized before calling this API. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful. + * It is also used for the case that the stack is started already. + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized. + * Initialize the stack by calling st_things_initialize(). + */ +int st_things_start(void); + +/** + * @brief Stops things stack. + * Removes all the data being used internally and releases all the memory allocated for the stack. + * Stack should have been initialized and started before calling this API. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not initialized. + * Initialize the stack by calling st_things_initialize(). + * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started. + * Start the stack by calling st_things_start(). + */ +int st_things_stop(void); + +/** + * @brief Callback for getting user's opinion regarding device reset. + * @return @c true to confirm, otherwise @c to deny + */ +typedef bool (*st_things_reset_confirm_cb)(void); + +/** + * @brief Callback for carrying the result of reset. + * @param[in] is_success Result of Stack-reset. (true : success, false : failure) + */ +typedef void (*st_things_reset_result_cb)(bool is_success); + +/** + * @brief Callback registration function for Reset-Confirmation and Reset-Result functions. + * @remarks Only one callback function can be set with this API.\n + * If multiple callbacks are set, the last one is registered only.\n + And the callbacks are called in the internal thread, which is not detached,\n + * so application should return it to get the next callbacks. + * @param[in] confirm_cb Callback function that will be called to get the user's input when reset is triggered. + * @param[in] result_cb Callback function that will be called after the reset process is done. + * This parameter can be NULL if notification for result of reset is not needed. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + */ +int st_things_register_reset_cb(st_things_reset_confirm_cb confirm_cb, st_things_reset_result_cb result_cb); + +/** + * @brief Reset all the data related to security and cloud being used in the stack. + * Stack should have been initialized and started before calling this API. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not intialized. + * Initialize the stack by calling st_things_initialize(). + * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started. + * Start the stack by calling st_things_start(). + */ +int st_things_reset(void); + +/** + * @brief Callback for carrying the randomly generated PIN info. + * @details Device should show the PIN on display. + * @param[in] pin_data PIN data in string format. + * @param[in] pin_size Length of the PIN String. + */ +typedef void (*st_things_pin_generated_cb)(const char *pin_data, const size_t pin_size); + +/** + * @brief Callback for informing the application to close the PIN display. + */ +typedef void (*st_things_pin_display_close_cb)(void); + +/** + * @brief Callback registration function for getting randomly generated PIN for the PIN-Based Ownership Transfer Request. + * @remarks Only one callback function can be set with this API.\n + * If multiple callbacks are set, the last one is registered only.\n + * And the callbacks are called in the internal thread, which is not detached,\n + * so application should return it to get the next callbacks. + * @param[in] generated_cb Callback function that will be called when device receives a Ownership Transfer request from client. + * @param[in] close_cb Callback function that will be called when Ownership Transfer is done so device can stop showing PIN on display. + * This parameter can be NULL if stop triggering is not needed. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + */ +int st_things_register_pin_handling_cb(st_things_pin_generated_cb generated_cb, st_things_pin_display_close_cb close_cb); + +/** + * @brief Callback for getting user's input regarding mutual verification. + * @return @c true true in cse of confirmed, otherwise @c false + */ +typedef bool (*st_things_user_confirm_cb)(void); + +/** + * @brief Callback registration function for getting user confirmation for MUTUAL VERIFICATION BASED JUST WORK Ownership transfer. + * @remarks Only one callback function can be set with this API.\n + * If multiple callbacks are set, the last one is registered only.\n + * And the callbacks are called in the internal thread, which is not detached,\n + * so application should return it to get the next callbacks. + * @param[in] confirm_cb Callback function that will be called when device receives a confirm request from client. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + */ +int st_things_register_user_confirm_cb(st_things_user_confirm_cb confirm_cb); + +/** + * @brief Callback for getting the current state of ST Things. + * @param[in] things_status ST Things State + */ +typedef void (*st_things_status_change_cb)(st_things_status_e things_status); + +/** + * @brief Callback registration function for getting notified when ST Things state changes. + * @remarks Only one callback function can be set with this API.\n + * If multiple callbacks are set, the last one is registered only.\n + * And the callbacks are called in the internal thread, which is not detached,\n + * so application should return it to get the next callbacks. + * @param[in] status_cb Refernce of the callback function to get ST Things status + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + */ +int st_things_register_things_status_change_cb(st_things_status_change_cb status_cb); + +/** + * @brief Notify the observers of a specific resource. + * Stack should have been initialized and started before calling this API. + * @param[in] resource_uri Resource URI of the resource which will be notified to observers. + * @return @c 0 on success, otherwise a negative error value + * @retval #ST_THINGS_ERROR_NONE Successful + * @retval #ST_THINGS_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #ST_THINGS_ERROR_OPERATION_FAILED Operation failed + * @retval #ST_THINGS_ERROR_STACK_NOT_INITIALIZED Stack is not intialized. + * Initialize the stack by calling st_things_initialize(). + * @retval #ST_THINGS_ERROR_STACK_NOT_STARTED Stack is not started. + * Start the stack by calling st_things_start(). + */ +int st_things_notify_observers(const char *resource_uri); + +/** + * @brief Create an instance of representation. + * @remarks To destroy an instance, st_things_destroy_representation_inst() should be used. + * @return a pointer of the created representation, otherwise a null pointer if the memory is insufficient. + */ +st_things_representation_s *st_things_create_representation_inst(void); + +/** + * @brief Destroy an instance of representation. + * @param[in] rep Representation that will be destroyed. + */ +void st_things_destroy_representation_inst(st_things_representation_s *rep); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __ST_THINGS_H__ */ diff --git a/inc/st_things_types.h b/inc/st_things_types.h new file mode 100644 index 0000000..867f0ac --- /dev/null +++ b/inc/st_things_types.h @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * 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 __ST_THINGS_TYPES_H__ +#define __ST_THINGS_TYPES_H__ + +#include +#include +#include + +/** + * @brief Enumeration for ST Things error code. + */ +typedef enum { + ST_THINGS_ERROR_NONE = 0, /**< Successful */ + ST_THINGS_ERROR_INVALID_PARAMETER = -1, /**< Invalid parameter (If parameter is null or empty)*/ + ST_THINGS_ERROR_OPERATION_FAILED = -2, /**< Operation Failed */ + ST_THINGS_ERROR_STACK_NOT_INITIALIZED = -3, /**< Stack is not yet initialized*/ + ST_THINGS_ERROR_STACK_ALREADY_INITIALIZED = -4, /**< Stack is already initialized*/ + ST_THINGS_ERROR_STACK_NOT_STARTED = -5, /**< Stack is not yet started*/ + ST_THINGS_ERROR_STACK_RUNNING = -6, /**< Stack is currently running*/ +} st_things_error_e; + +/** + * @brief Enumeration for ST Things status. + */ +typedef enum { + ST_THINGS_STATUS_INIT = 0, /**< Initial state of ST Things */ + ST_THINGS_STATUS_ES_STARTED, /**< Easy-setup is started */ + ST_THINGS_STATUS_ES_DONE, /**< Easy-setup is done */ + ST_THINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER, /**< Easy-setup failed due to Ownership-Transfer failure */ + ST_THINGS_STATUS_CONNECTING_TO_AP, /**< Connecting to target Wi-Fi access point */ + ST_THINGS_STATUS_CONNECTED_TO_AP, /**< Connected to target Wi-Fi access point */ + ST_THINGS_STATUS_CONNECTING_TO_AP_FAILED, /**< Failed to connect to target Wi-Fi access point */ + ST_THINGS_STATUS_REGISTERING_TO_CLOUD, /**< Trying to Sign-up/Sign-in/Publish-Resource(s) to Cloud */ + ST_THINGS_STATUS_REGISTERED_TO_CLOUD, /**< Publish resource(s) to cloud is complete. Now the Thing is ready to be controlled via Cloud */ + ST_THINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN, /**< Failed to sign-in to Cloud */ + ST_THINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES /**< Failed to publish resources to Cloud */ +} st_things_status_e; + +/** + * @brief Structure for Representation. + */ +typedef struct _st_things_representation +{ + void* payload; /**< Payload of representation */ + + /** + * @brief API for getting the value of string type property with a key. + * @remarks This API will return deep-copied string value as out parameter, so application must free it after use. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value String value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_str_value) (struct _st_things_representation* rep, const char* key, char** value); + + /** + * @brief API for getting the value of boolean type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value Bool value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_bool_value) (struct _st_things_representation* rep, const char* key, bool* value); + + /** + * @brief API for getting the value of integer type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value Integer value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_int_value) (struct _st_things_representation* rep, const char* key, int64_t* value); + + /** + * @brief API for getting the value of double type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value Double value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_double_value) (struct _st_things_representation* rep, const char* key, double* value); + + /** + * @brief API for getting the value of byte array type property with a key. + * @remarks This API will return deep-copied byte value as out parameter, so application must free it after use. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value Byte value + * @param[out] size Size of Byte value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_byte_value) (struct _st_things_representation* rep, const char* key, uint8_t** value, size_t* size); + + /** + * @brief API for getting the value of object type property with a key. + * @remarks This API will return deep-copied object value as out parameter, so application must free it after use.\n + * To free an object, st_things_destroy_representation_inst() in st_things.h should be used. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[out] value Object value + * @return @c true if value exist, otherwise @c false + */ + bool (*get_object_value) (struct _st_things_representation* rep, const char* key, struct _st_things_representation** value); + + /** + * @brief API for setting the value of string type property with a key. + * @remarks This API will deep-copy the string value inside, so application still has an ownership of memory for the string value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value String value. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_str_value) (struct _st_things_representation* rep, const char* key, const char* value); + + /** + * @brief API for setting the value of boolean type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value Bool value. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_bool_value) (struct _st_things_representation* rep, const char* key, bool value); + + /** + * @brief API for setting the value of integer type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value Integer value. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_int_value) (struct _st_things_representation* rep, const char* key, int64_t value); + + /** + * @brief API for setting the value of double type property with a key. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value Double value. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_double_value) (struct _st_things_representation* rep, const char* key, double value); + + /** + * @brief API for setting the value of byte array type property with a key. + * @remarks This API will deep-copy the byte value inside, so application still has an ownership of memory for the byte value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value Byte value. + * @param[in] size Size of Byte value. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_byte_value) (struct _st_things_representation* rep, const char* key, const uint8_t* value, size_t size); + + /** + * @brief API for setting the value of object type property with a key. + * @remarks This API will deep-copy the object value inside, so application still has an ownership of memory for the object value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the value. + * @param[in] value Object value. + * @return @c true if value exist, otherwise @c false + */ + bool (*set_object_value) (struct _st_things_representation* rep, const char* key, const struct _st_things_representation* value); + + /** + * @brief API for getting the value of string array type property with a key. + * @remarks This API will return deep-copied array value as out parameter, so application must free it after use. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the array type of value. + * @param[out] array Reference of the string array to where the value will be copied. + * @param[out] length Total number of elements in the array. + * @return @c true if value exist, otherwise @c false + */ + bool (*get_str_array_value) (struct _st_things_representation* rep, const char* key, char*** array, size_t* length); + + /** + * @brief API for getting the value of integer array type property with a key. + * @remarks This API will return deep-copied array value as out parameter, so application must free it after use. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the array type of value. + * @param[out] array Reference of the integer array where the value will be copied. + * @param[out] length Total number of elements in the array. + * @return @c true if value exist, otherwise @c false + */ + bool (*get_int_array_value) (struct _st_things_representation* rep, const char* key, int64_t** array, size_t* length); + + /** + * @brief API for getting the value of double array type property with a key. + * @remarks This API will return deep-copied array value as out parameter, so application must free it after use. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which will represent the array type of value. + * @param[out] array Reference of the double array where the value will be copied. + * @param[out] length Total number of elements in the array. + * @return @c true if value exist, otherwise @c false + */ + bool (*get_double_array_value) (struct _st_things_representation* rep, const char* key, double** array, size_t* length); + + /** + * @brief API for getting the value of object array type property with a key. + * @remarks This API will return deep-copied array value as out parameter, so application must free it after use.\n + * To free each object in array, st_things_destroy_representation_inst() in st_things.h should be used. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the array type of value. + * @param[out] array Reference of the object array where the value will be copied. + * @param[out] length Total number of elements in the array. + * @return @c true if value exist, otherwise @c false + */ + bool (*get_object_array_value) (struct _st_things_representation* rep, const char* key, struct _st_things_representation*** array, size_t* length); + + /** + * @brief API for setting the value of string array type property with a key. + * @remarks This API will deep-copy the array value inside, so application still has an ownership of memory for the array value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[in] array String array type value. + * @param[in] length Total number of elements in the array. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_str_array_value) (struct _st_things_representation* rep, const char* key, const char** array, size_t length); + + /** + * @brief API for setting the value of integer array type property with a key. + * @remarks This API will deep-copy the array value inside, so application still has an ownership of memory for the array value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[in] array Integer array type value. + * @param[in] length Total number of elements in the array. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_int_array_value) (struct _st_things_representation* rep, const char* key, const int64_t* array, size_t length); + + /** + * @brief API for setting the value of double array type property with a key. + * @remarks This API will deep-copy the array value inside, so application still has an ownership of memory for the array value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[in] array Double array type value. + * @param[in] length Total number of elements in the array. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_double_array_value) (struct _st_things_representation* rep, const char* key, const double* array, size_t length); + + /** + * @brief API for setting the value of object array type property with a key. + * @remarks This API will deep-copy the array value inside, so application still has an ownership of memory for the array value. + * @param[in] rep Instance of Representation. + * @param[in] key Property Name which represents the value. + * @param[in] array Object array type value. + * @param[in] length Total number of elements in the array. + * @return @c true if setting value is successful, otherwise @c false + */ + bool (*set_object_array_value) (struct _st_things_representation* rep, const char* key, const struct _st_things_representation** array, size_t length); + +} st_things_representation_s; + +/** + * @brief Structure for representing the Get Request Message. + */ +typedef struct _st_things_get_request_message +{ + char* resource_uri; /**< Resource URI */ + char* query; /**< One or more query parameters of the request message. Ex: key1=value1;key2=value2;... */ + char* property_key; /**< One or more property key that application needs to set a value for response. Ex: key1;key2;... */ + + /** + * @brief API for getting the value of a specific query from the query parameters of the request. + * @param[in] req_msg Instance of get request message. + * @param[in] key Name of the query.(ex: key1, key2, etc) + * @param[out] value Value of the query.(value1, value2, etc) + * @return @c true if query exist, otherwise @c false + */ + bool (*get_query_value) (struct _st_things_get_request_message* req_msg, const char* key, char** value); + + /** + * @brief API for checking whether the request has a specific property key or not. + * @param[in] req_msg Instance of get request message. + * @param[in] key Name of the property. + * @return @c true if the property key exists, otherwise @c false + */ + bool (*has_property_key) (struct _st_things_get_request_message* req_msg, const char* key); + +} st_things_get_request_message_s; + +/** + * @brief Structure for representing the Set Request Message. + */ +typedef struct _st_things_set_request_message +{ + char* resource_uri; /**< Resource URI */ + char* query; /**< One or more query parameters of the request message. Ex: key1=value1?key2=value2?... */ + struct _st_things_representation* rep; /**< Representation of the set request message */ + + /** + * @brief API for getting the value of a specific query from the query parameters of the request. + * @param[in] req_msg Instance of request message. + * @param[in] key Name of the query.(ex: key1, key2, etc) + * @param[out] value Value of the query.(value1, value2, etc) + * @return @c true if query exist, otherwise @c false + */ + bool (*get_query_value) (struct _st_things_set_request_message* req_msg, const char* key, char** value); + +} st_things_set_request_message_s; + +#endif /* __ST_THINGS_TYPES_H__ */ diff --git a/lib/liboicdastack.so b/lib/liboicdastack.so new file mode 100644 index 0000000..4a5cc91 Binary files /dev/null and b/lib/liboicdastack.so differ diff --git a/lib/libsdkapi.so b/lib/libsdkapi.so new file mode 100644 index 0000000..47ca354 Binary files /dev/null and b/lib/libsdkapi.so differ diff --git a/project_def.prop b/project_def.prop new file mode 100644 index 0000000..4f221b5 --- /dev/null +++ b/project_def.prop @@ -0,0 +1,11 @@ +APPNAME = smart-blind + +type = app +profile = iot-headless-4.0 + +USER_SRCS = src/smart-blind.c +USER_DEFS = +USER_INC_DIRS = inc, inc/sdk +USER_OBJS = +USER_LIBS = lib/liboicdastack.so, lib/libsdkapi.so +USER_EDCS = diff --git a/res/certificate.pem b/res/certificate.pem new file mode 100644 index 0000000..d3470a3 --- /dev/null +++ b/res/certificate.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAnCgAwIBAgIUREVWM1AwMTE1MzM2ODUwODUwNzkwCgYIKoZIzj0EAwIw +fTE4MDYGA1UEAwwvU2Ftc3VuZyBFbGVjdHJvbmljcyBPQ0YgRGV2ZWxvcGVyIFN1 +YkNBIHYzIFRFU1QxFjAUBgNVBAsMDU9DRiBEZXYgU3ViQ0ExHDAaBgNVBAoME1Nh +bXN1bmcgRWxlY3Ryb25pY3MxCzAJBgNVBAYTAktSMB4XDTE4MDgwNzIzMzgwNVoX +DTE4MTAwNjIzMzgwNVowgbMxZzBlBgNVBAMMXkRldmVsb3BlciBEZXZpY2UgVEVT +VDogU21hcnRCbGluZCAoYjg4MzdhNWYtMjNiNS00Y2RhLWE0ZmEtNGE5NDU5YzRl +MTBhKS9qYXkudHQudGVzdEBnbWFpbC5jb20xHTAbBgNVBAsMFE9DRiBEZXYgRGV2 +aWNlKGZBYnIpMRwwGgYDVQQKDBNTYW1zdW5nIEVsZWN0cm9uaWNzMQswCQYDVQQG +EwJLUjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJMDmIztgUXrbfrPaBibwShB +oFnYd4vhWLA9II3SkaPzET23uGemCH7jtEd8YmCPezz7yGJTXxg3s4PYJs91GXOj +gZYwgZMwCwYDVR0PBAQDAgPIMDwGCCsGAQUFBwEBBDAwLjAsBggrBgEFBQcwAYYg +aHR0cDovL29jc3AtdGVzdC5zYW1zdW5naW90cy5jb20wOwYDVR0fBDQwMjAwoC6g +LIYqaHR0cDovL2NybC10ZXN0LnNhbXN1bmdpb3RzLmNvbS9kZXYzY2EuY3JsMAkG +A1UdEwQCMAAwCgYIKoZIzj0EAwIDSAAwRQIgJ4Vak8GiWRmMq6pgNwddzBmCRz/b +Px6CO+svAUIgmS8CIQD8f7L6pB+dT8xRa6tC7xcFXccIDnS7z2ST3B1PUIvjLw== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIClDCCAjmgAwIBAgITCBdmNie8mlu4WgGqOB3KClKsjzAMBggqhkjOPQQDAgUA +MHAxLTArBgNVBAMTJFNhbXN1bmcgRWxlY3Ryb25pY3MgT0NGIFJvb3QgQ0EgVEVT +VDEUMBIGA1UECxMLT0NGIFJvb3QgQ0ExHDAaBgNVBAoTE1NhbXN1bmcgRWxlY3Ry +b25pY3MxCzAJBgNVBAYTAktSMCAXDTE3MTAxMDEwMjY0NloYDzIwNjkxMjMxMTQ1 +OTU5WjB9MTgwNgYDVQQDEy9TYW1zdW5nIEVsZWN0cm9uaWNzIE9DRiBEZXZlbG9w +ZXIgU3ViQ0EgdjMgVEVTVDEWMBQGA1UECxMNT0NGIERldiBTdWJDQTEcMBoGA1UE +ChMTU2Ftc3VuZyBFbGVjdHJvbmljczELMAkGA1UEBhMCS1IwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAASaLdjStXbZ6UcF7TFXDqratJxficMlBt8ec46MYQEocqZw +cIAh6UP8mpDMlOs1cUxatCoEDrGUNOZyFuNpztqfo4GgMIGdMA4GA1UdDwEB/wQE +AwIBBjA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLXRlc3Quc2Ftc3VuZ2lv +dHMuY29tL3Jvb3QuY3JsMBIGA1UdEwEB/wQIMAYBAf8CAQAwPAYIKwYBBQUHAQEE +MDAuMCwGCCsGAQUFBzABhiBodHRwOi8vb2NzcC10ZXN0LnNhbXN1bmdpb3RzLmNv +bTAMBggqhkjOPQQDAgUAA0cAMEQCIDAcuxI2o3RATk1JOGCmNmAqwPNLJxXzq1LA +GPqAP+fnAiBbrlkNBbmWk3q3nLO+0yJP1jd+uh5a7gd8/WF6t5osGA== +-----END CERTIFICATE----- diff --git a/res/device_def.json b/res/device_def.json new file mode 100644 index 0000000..e9ac95e --- /dev/null +++ b/res/device_def.json @@ -0,0 +1,97 @@ +{ + "device": [ + { + "specification": { + "device": { + "deviceType": "oic.d.light", + "deviceName": "Smart Blind", + "specVersion": "core.1.1.0", + "dataModelVersion": "res.1.1.0" + }, + "platform": { + "manufacturerName": "fAbr", + "manufacturerUrl": "http://www.samsung.com/sec/", + "manufacturingDate": "2017-08-31", + "modelNumber": "NWSP-01", + "platformVersion": "1.0", + "osVersion": "1.0", + "hardwareVersion": "1.0", + "firmwareVersion": "1.0", + "vendorId": "TizenVendor" + } + }, + "resources": { + "single": [ + { + "uri": "/capability/switch/main/0", + "types": [ + "x.com.st.powerswitch" + ], + "interfaces": [ + "oic.if.a", + "oic.if.baseline" + ], + "policy": 3 + }, + { + "uri": "/capability/illuminanceMeasurement/main/0", + "types": [ + "oic.r.sensor.illuminance" + ], + "interfaces": [ + "oic.if.s", + "oic.if.baseline" + ], + "policy": 3 + } + ] + } + } + ], + "resourceTypes": [ + { + "type": "x.com.st.powerswitch", + "properties": [ + { + "key": "power", + "type": 3, + "mandatory": true, + "rw": 3 + } + ] + }, + { + "type": "oic.r.sensor.illuminance", + "properties": [ + { + "key": "illuminance", + "type": 2, + "mandatory": true, + "rw": 1 + } + ] + } + ], + "configuration": { + "easySetup": { + "connectivity": { + "type": 1, + "softAP": { + "setupId": "007", + "artik": false + } + }, + "ownershipTransferMethod": 2 + }, + "wifi": { + "interfaces": 15, + "frequency": 1 + }, + "filePath": { + "svrdb": "artikserversecured.dat", + "provisioning": "provisioning.dat", + "certificate": "certificate.pem", + "privateKey": "privatekey.der" + } + } +} \ No newline at end of file diff --git a/res/privatekey.der b/res/privatekey.der new file mode 100644 index 0000000..1847512 Binary files /dev/null and b/res/privatekey.der differ diff --git a/shared/res/smart-blind.png b/shared/res/smart-blind.png new file mode 100644 index 0000000..9765b1b Binary files /dev/null and b/shared/res/smart-blind.png differ diff --git a/src/resource.c b/src/resource.c new file mode 100644 index 0000000..ad85e27 --- /dev/null +++ b/src/resource.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "log.h" +#include "resource.h" + +static resource_s resource_info[PIN_MAX] = { {0, NULL, NULL}, }; + +resource_s *resource_get_info(int pin_num) +{ + return &resource_info[pin_num]; +} + +void resource_close_all(void) +{ + int i = 0; + for (i = 0; i < PIN_MAX; i++) { + if (!resource_info[i].opened) continue; + _I("GPIO[%d] is closing...", i); + + if (resource_info[i].close) + resource_info[i].close(i); + } + resource_close_illuminance_sensor(); +} diff --git a/src/resource/resource_illuminance_sensor.c b/src/resource/resource_illuminance_sensor.c new file mode 100644 index 0000000..787e992 --- /dev/null +++ b/src/resource/resource_illuminance_sensor.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "log.h" +#include "resource_internal.h" + +#define I2C_PIN_MAX 28 +/* I2C */ +#define GY30_ADDR 0x23 /* Address of GY30 light sensor */ +#define GY30_CONT_HIGH_RES_MODE 0x10 /* Start measurement at 11x resolution. Measurement time is approx 120mx */ +#define GY30_CONSTANT_NUM (1.2) + +static struct { + int opened; + peripheral_i2c_h sensor_h; +} resource_sensor_s; + +void resource_close_illuminance_sensor(void) +{ + if (!resource_sensor_s.opened) + return; + + _I("Illuminance Sensor is finishing..."); + peripheral_i2c_close(resource_sensor_s.sensor_h); + resource_sensor_s.opened = 0; +} + +int resource_read_illuminance_sensor(int i2c_bus, uint32_t *out_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + static int write = 0; + unsigned char buf[10] = { 0, }; + + if (!resource_sensor_s.opened) { + ret = peripheral_i2c_open(i2c_bus, GY30_ADDR, &resource_sensor_s.sensor_h); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("i2c open error : %s", get_error_message(ret)); + return -1; + } + resource_sensor_s.opened = 1; + } + + buf[0] = 0x10; + + if (!write) { + ret = peripheral_i2c_write(resource_sensor_s.sensor_h, buf, 1); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("i2c write error : %s", get_error_message(ret)); + return -1; + } + write = 1; + } + + ret = peripheral_i2c_read(resource_sensor_s.sensor_h, buf, 2); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("i2c read error : %s", get_error_message(ret)); + return -1; + } + + *out_value = (buf[0] << 8 | buf[1]) / GY30_CONSTANT_NUM; // Just Sum High 8bit and Low 8bit + + return 0; +} diff --git a/src/resource/resource_servo_motor.c b/src/resource/resource_servo_motor.c new file mode 100644 index 0000000..c6895ea --- /dev/null +++ b/src/resource/resource_servo_motor.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "log.h" + +#define SERVO_MOTOR_CHANNER (0) + +static peripheral_pwm_h g_pwm_h; + +void resource_close_servo_motor(void) +{ + if (g_pwm_h) { + peripheral_pwm_close(g_pwm_h); + g_pwm_h = NULL; + } +} + +int resource_set_servo_motor_value(double duty_cycle_ms) +{ + int ret = 0; + + if (!g_pwm_h) { + ret = peripheral_pwm_open(0, SERVO_MOTOR_CHANNER, &g_pwm_h); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("failed to open servo motor with ch : %s", get_error_message(ret)); + return -1; + } + } + + ret = peripheral_pwm_set_period(g_pwm_h, 20 * 1000 * 1000); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("failed to set period : %s", get_error_message(ret)); + return -1; + } + + ret = peripheral_pwm_set_duty_cycle(g_pwm_h, duty_cycle_ms * 1000 * 1000); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("failed to set duty cycle : %s", get_error_message(ret)); + return -1; + } + + ret = peripheral_pwm_set_enabled(g_pwm_h, true); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("failed to enable : %s", get_error_message(ret)); + return -1; + } + + return 0; +} diff --git a/src/sensor-data.c b/src/sensor-data.c new file mode 100644 index 0000000..d135979 --- /dev/null +++ b/src/sensor-data.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "log.h" +#include "sensor-data.h" + +struct __sensor_data_s { + sensor_data_type_e type; + union { + int int_val; + unsigned int uint_val; + bool b_val; + double d_val; + char *str_val; + } value; + pthread_mutex_t mutex; +}; + +sensor_data *sensor_data_new(sensor_data_type_e type) +{ + sensor_data *data = NULL; + retv_if(type == SENSOR_DATA_TYPE_NONE, NULL); + + data = calloc(1, sizeof(sensor_data)); + retv_if(!data, NULL); + + data->type = type; + pthread_mutex_init(&data->mutex, NULL); + + return data; +} + +void sensor_data_free(sensor_data *data) +{ + ret_if(!data); + + if (data->type == SENSOR_DATA_TYPE_STR) { + pthread_mutex_lock(&data->mutex); + free(data->value.str_val); + data->value.str_val = NULL; + pthread_mutex_unlock(&data->mutex); + } + pthread_mutex_destroy(&data->mutex); + + free(data); +} + +int sensor_data_set_int(sensor_data *data, int value) +{ + retv_if(!data, -1); + retv_if(data->type != SENSOR_DATA_TYPE_INT, -1); + + pthread_mutex_lock(&data->mutex); + data->value.int_val = value; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_set_uint(sensor_data *data, unsigned int value) +{ + retv_if(!data, -1); + retv_if(data->type != SENSOR_DATA_TYPE_UINT, -1); + + pthread_mutex_lock(&data->mutex); + data->value.uint_val = value; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_set_bool(sensor_data *data, bool value) +{ + retv_if(!data, -1); + retv_if(data->type != SENSOR_DATA_TYPE_BOOL, -1); + + pthread_mutex_lock(&data->mutex); + data->value.b_val = value; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_set_double(sensor_data *data, double value) +{ + retv_if(!data, -1); + retv_if(data->type != SENSOR_DATA_TYPE_DOUBLE, -1); + + pthread_mutex_lock(&data->mutex); + data->value.d_val = value; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_set_string(sensor_data *data, const char *value, unsigned int size) +{ + char *temp = NULL; + retv_if(!data, -1); + retv_if(data->type != SENSOR_DATA_TYPE_STR, -1); + retv_if(!value, -1); + retv_if(size == 0, -1); + + temp = strndup(value, size); + retv_if(!temp, -1); + + pthread_mutex_lock(&data->mutex); + free(data->value.str_val); + data->value.str_val = temp; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_get_int(sensor_data *data, int *value) +{ + retv_if(!data, -1); + retv_if(!value, -1); + retv_if(data->type != SENSOR_DATA_TYPE_INT, -1); + + pthread_mutex_lock(&data->mutex); + *value = data->value.int_val; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_get_uint(sensor_data *data, unsigned int *value) +{ + retv_if(!data, -1); + retv_if(!value, -1); + retv_if(data->type != SENSOR_DATA_TYPE_UINT, -1); + + pthread_mutex_lock(&data->mutex); + *value = data->value.uint_val; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_get_bool(sensor_data *data, bool *value) +{ + retv_if(!data, -1); + retv_if(!value, -1); + retv_if(data->type != SENSOR_DATA_TYPE_BOOL, -1); + + pthread_mutex_lock(&data->mutex); + *value = data->value.b_val; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_get_double(sensor_data *data, double *value) +{ + retv_if(!data, -1); + retv_if(!value, -1); + retv_if(data->type != SENSOR_DATA_TYPE_DOUBLE, -1); + + pthread_mutex_lock(&data->mutex); + *value = data->value.d_val; + pthread_mutex_unlock(&data->mutex); + + return 0; +} + +int sensor_data_get_string(sensor_data *data, const char **value) +{ + retv_if(!data, -1); + retv_if(!value, -1); + retv_if(data->type != SENSOR_DATA_TYPE_STR, -1); + + pthread_mutex_lock(&data->mutex); + *value = data->value.str_val; + pthread_mutex_unlock(&data->mutex); + + return 0; +} diff --git a/src/smart-blind.c b/src/smart-blind.c new file mode 100644 index 0000000..961e58e --- /dev/null +++ b/src/smart-blind.c @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Contact: Jin Yoon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "st_things.h" +#include "log.h" +#include "sensor-data.h" +#include "resource.h" + +#define JSON_PATH "device_def.json" + +#define SENSOR_URI_ILLUMINANCE "/capability/illuminanceMeasurement/main/0" +#define SENSOR_KEY_ILLUMINANCE "illuminance" +#define SENSOR_KEY_RANGE "range" + +#define SENSOR_URI_POWER "/capability/switch/main/0" +#define SENSOR_KEY_POWER "power" +#define SENSOR_POWER_INITIALIZING "off" + +#define I2C_BUS_NUMBER (1) + +// QUIZ +#define SENSOR_GATHER_INTERVAL (100.0f) + +// QUIZ +//#define USE_ST_SDK + +typedef struct app_data_s { + Ecore_Timer *getter_illuminance; + sensor_data *illuminance_data; + sensor_data *power_data; +} app_data; + +static app_data *g_ad = NULL; + +#define ILLUMINATION_CRITERIA 1000 + +// HS-53 Servo Motor Duty Cycle : 0.54ms ~ 2.1ms +// Spec Duty Cycle : 0.553ms ~ 2.227ms(https://www.servocity.com/hitec-hs-53-servo) +#define SERVO_MOTOR_DUTY_CYCLE_COUNTER_CLOCKWISE 1.0 +#define SERVO_MOTOR_DUTY_CYCLE_CLOCKWISE 2.0 + +#define BLIND_UP "on" +#define BLIND_DOWN "off" + +static inline int __get_illuminance(void *data, unsigned int *illuminance_value) +{ + int ret = 0; + app_data *ad = data; + + retv_if(!ad, -1); + retv_if(!ad->illuminance_data, -1); + + // QUIZ + //ret = resource_read_illuminance_sensor(/* ? */, illuminance_value); + retv_if(ret != 0, -1); + + sensor_data_set_uint(ad->illuminance_data, *illuminance_value); + _D("Illuminance value : %u", *illuminance_value); + +#ifdef USE_ST_SDK + st_things_notify_observers(SENSOR_URI_ILLUMINANCE); +#endif + + return 0; +} + +static int __set_servo_motor(void *data, int on) +{ + double duty_cycle = 0; + int ret = 0; + const char *power_value = NULL; + app_data *ad = data; + + retv_if(!ad, -1); + retv_if(!ad->illuminance_data, -1); + + if (on) { + duty_cycle = SERVO_MOTOR_DUTY_CYCLE_CLOCKWISE; + power_value = BLIND_UP; + } else { + duty_cycle = SERVO_MOTOR_DUTY_CYCLE_COUNTER_CLOCKWISE; + power_value = BLIND_DOWN; + } + + ret = resource_set_servo_motor_value(duty_cycle); + retv_if(ret != 0, -1); + + sensor_data_set_string(ad->power_data, power_value, strlen(power_value)); + +#ifdef USE_ST_SDK + st_things_notify_observers(SENSOR_URI_POWER); +#endif + + return 0; +} + +static Eina_Bool __illuminance_to_servo_motor(void *data) +{ + int ret = 0; + unsigned int illuminance_value = 0; + + app_data *ad = data; + + if (!ad) { + _E("failed to get app_data"); + service_app_exit(); + } + + if (!ad->illuminance_data) { + _E("failed to get illuminance_data"); + service_app_exit(); + } + + ret = __get_illuminance(ad, &illuminance_value); + retv_if(ret != 0, ECORE_CALLBACK_RENEW); + +#if 0 // # Senario : Illuminance sensor + if (illuminance_value < ILLUMINATION_CRITERIA) { + on = 0; + } else { + on = 1; + } + + ret = __set_servo_motor(ad, on); + retv_if(ret != 0, ECORE_CALLBACK_RENEW); +#endif + + return ECORE_CALLBACK_RENEW; +} + +void gathering_stop(void *data) +{ + app_data *ad = data; + + ret_if(!ad); + + if (ad->getter_illuminance) + ecore_timer_del(ad->getter_illuminance); +} + +void gathering_start(void *data) +{ + app_data *ad = data; + + ret_if(!ad); + + gathering_stop(ad); + + ad->getter_illuminance = ecore_timer_add(SENSOR_GATHER_INTERVAL, __illuminance_to_servo_motor, ad); + if (!ad->getter_illuminance) + _E("Failed to add getter_illuminance"); +} + +#ifdef USE_ST_SDK +static bool handle_reset_request(void) +{ + _D("Received a request for RESET."); + return false; +} + +static void handle_reset_result(bool result) +{ + _D("Reset %s.\n", result ? "succeeded" : "failed"); +} + +static bool handle_ownership_transfer_request(void) +{ + _D("Received a request for Ownership-transfer."); + return true; +} + +static void handle_things_status_change(st_things_status_e things_status) +{ + _D("Things status is changed: %d", things_status); + + if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD) { + ecore_main_loop_thread_safe_call_async(gathering_start, g_ad); + } +} + +static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + _D("resource_uri [%s]", req_msg->resource_uri); + retv_if(!g_ad, false); + + if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_ILLUMINANCE)) { + if (req_msg->has_property_key(req_msg, SENSOR_KEY_ILLUMINANCE)) { + unsigned int value = 0; + sensor_data_get_uint(g_ad->illuminance_data, &value); + resp_rep->set_int_value(resp_rep, SENSOR_KEY_ILLUMINANCE, value); + } + return true; + } else if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_POWER)) { + if (req_msg->has_property_key(req_msg, SENSOR_KEY_POWER)) { + const char *str = NULL; + sensor_data_get_string(g_ad->power_data, &str); + if (!str) { + str = SENSOR_POWER_INITIALIZING; + } + resp_rep->set_str_value(resp_rep, SENSOR_KEY_POWER, str); + _D("Power : %s", str); + } + return true; + } + _E("not supported uri"); + return false; +} + +static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + _D("resource_uri [%s]", req_msg->resource_uri); + retv_if(!g_ad, false); + + if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_POWER)) { + int ret = 0; + char *str = NULL; + + if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_KEY_POWER, &str)) { + retv_if(!str, false); + _D("set [%s:%s] == %s", SENSOR_URI_POWER, SENSOR_KEY_POWER, str); + + sensor_data_set_string(g_ad->power_data, str, strlen(str)); + resp_rep->set_str_value(resp_rep, SENSOR_KEY_POWER, str); + + if (0 == strcmp(str, "on")) { + ret = __set_servo_motor(g_ad, 1); + } else { + ret = __set_servo_motor(g_ad, 0); + } + + retv_if(ret != 0, false); + } else { + _E("cannot get a string value"); + } + + return true; + } + return false; +} + +static int __st_things_init(void) +{ + bool easysetup_complete = false; + char app_json_path[128] = {'\0', }; + char *app_res_path = NULL; + char *app_data_path = NULL; + + app_res_path = app_get_resource_path(); + if (!app_res_path) { + _E("app_res_path is NULL!!"); + return -1; + } + + app_data_path = app_get_data_path(); + if (!app_data_path) { + _E("app_data_path is NULL!!"); + free(app_res_path); + return -1; + } + + snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_PATH); + + if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) { + _E("st_things_set_configuration_prefix_path() failed!!"); + free(app_res_path); + free(app_data_path); + return -1; + } + + free(app_res_path); + free(app_data_path); + + if (0 != st_things_initialize(app_json_path, &easysetup_complete)) { + _E("st_things_initialize() failed!!"); + return -1; + } + + _D("easysetup_complete:[%d] ", easysetup_complete); + + st_things_register_request_cb(handle_get_request, handle_set_request); + st_things_register_reset_cb(handle_reset_request, handle_reset_result); + st_things_register_user_confirm_cb(handle_ownership_transfer_request); + st_things_register_things_status_change_cb(handle_things_status_change); + + return 0; +} + +static int __st_things_deinit(void) +{ + st_things_deinitialize(); + return 0; +} + +static int __st_things_start(void) +{ + st_things_start(); + return 0; +} + +static int __st_things_stop(void) +{ + st_things_stop(); + return 0; +} +#endif /* USE_ST_SDK */ + +static bool service_app_create(void *user_data) +{ + app_data *ad = (app_data *)user_data; + + ad->illuminance_data = sensor_data_new(SENSOR_DATA_TYPE_UINT); + if (!ad->illuminance_data) + return false; + + ad->power_data = sensor_data_new(SENSOR_DATA_TYPE_STR); + if (!ad->power_data) + return false; + sensor_data_set_string(g_ad->power_data, SENSOR_POWER_INITIALIZING, strlen(SENSOR_POWER_INITIALIZING)); + +#ifdef USE_ST_SDK + if (__st_things_init()) + return false; +#endif + + return true; +} + +static void service_app_control(app_control_h app_control, void *user_data) +{ +#ifdef USE_ST_SDK + __st_things_start(); +#else + gathering_start(user_data); +#endif +} + +static void service_app_terminate(void *user_data) +{ + app_data *ad = (app_data *)user_data; + + if (ad->getter_illuminance) + ecore_timer_del(ad->getter_illuminance); + + resource_close_illuminance_sensor(); + resource_close_servo_motor(); + +#ifdef USE_ST_SDK + __st_things_stop(); + __st_things_deinit(); +#else + gathering_stop(ad); +#endif + + sensor_data_free(ad->illuminance_data); + free(ad); +} + +int main(int argc, char *argv[]) +{ + app_data *ad = NULL; + service_app_lifecycle_callback_s event_callback; + + ad = calloc(1, sizeof(app_data)); + retv_if(!ad, -1); + + g_ad = ad; + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + + return service_app_main(argc, argv, &event_callback, ad); +} + diff --git a/tizen-manifest.xml b/tizen-manifest.xml new file mode 100644 index 0000000..b8c9cb7 --- /dev/null +++ b/tizen-manifest.xml @@ -0,0 +1,17 @@ + + + + + + smart-blind.png + + + + http://tizen.org/privilege/network.get + http://tizen.org/privilege/network.set + http://tizen.org/privilege/internet + http://tizen.org/privilege/alarm.set + http://tizen.org/privilege/network.profile + http://tizen.org/privilege/peripheralio + +