diff options
author | boyeon-son <bson1012@gmail.com> | 2018-09-10 12:15:48 +0900 |
---|---|---|
committer | boyeon-son <bson1012@gmail.com> | 2018-09-10 12:15:48 +0900 |
commit | 069c8fa8e1d9bb7af6ceeed1f2f1c667ace75b22 (patch) | |
tree | 096597fd9e579d116a7f20b2500c87968843be45 /src | |
parent | 6d3a92feab8113df67520283a45954e8eef3c17e (diff) | |
download | st-things-light-069c8fa8e1d9bb7af6ceeed1f2f1c667ace75b22.tar.gz st-things-light-069c8fa8e1d9bb7af6ceeed1f2f1c667ace75b22.tar.bz2 st-things-light-069c8fa8e1d9bb7af6ceeed1f2f1c667ace75b22.zip |
Initialize Smart Things Light project
Diffstat (limited to 'src')
-rwxr-xr-x | src/controller.c | 391 | ||||
-rwxr-xr-x | src/resource/resource_infrared_motion_sensor.c | 66 | ||||
-rwxr-xr-x | src/resource/resource_led.c | 68 | ||||
-rwxr-xr-x | src/sensor-data.c | 192 |
4 files changed, 717 insertions, 0 deletions
diff --git a/src/controller.c b/src/controller.c new file mode 100755 index 0000000..1c55e50 --- /dev/null +++ b/src/controller.c @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2018 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 <tizen.h> +#include <service_app.h> +#include <string.h> +#include <stdlib.h> +#include <Ecore.h> + +#include "st_things.h" +#include "log.h" +#include "resource/resource_infrared_motion_sensor.h" +#include "resource/resource_led.h" +#include "sensor-data.h" + +#define JSON_NAME "device_def.json" +#define SENSOR_MOTION_URI "/capability/motionSensor/main/0" +#define SENSOR_MOTION_KEY "value" +#define SENSOR_LED_URI "/capability/switch/main/0" +#define SENSOR_LED_KEY "power" +#define SENSOR_LED_INIT "off" + +#define LED_ON "on" +#define LED_OFF "off" + +#define USE_ST_SDK + +typedef struct app_data_s { + Ecore_Timer *getter_motion; + sensor_data *motion_data; + sensor_data *led_data; +} app_data; + +static app_data *g_ad = NULL; + +static Eina_Bool __change_motion_sensor_data(void *data) +{ + uint32_t value = 0; + + // Get value from motion sensor + int ret = resource_read_infrared_motion_sensor(46, &value); + + if (ret != 0) _E("Cannot read sensor value"); + + sensor_data_set_bool(g_ad->motion_data, value); + + _D("Detected motion value is: %d", value); + + // Notify observers of the Motion sensor resource + st_things_notify_observers(SENSOR_MOTION_URI); + + return ECORE_CALLBACK_RENEW; +} + +static int __change_led_data(void *data, char *state) { + int ret = 0; + app_data *ad = data; + + retv_if(!ad, -1); + retv_if(!ad->led_data, -1); + + sensor_data_set_string(g_ad->led_data, state, strlen(state)); + + if (0 == strcmp(state, LED_ON)) { + ret = resource_write_led(130, 1); + } else { + ret = resource_write_led(130, 0); + } + + retv_if(ret != 0, -1); + + // Notify observers of the LED resource + st_things_notify_observers(SENSOR_LED_URI); + + return 0; +} + +static bool __handle_get_request_on_motion (st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + if (req_msg->has_property_key(req_msg, SENSOR_MOTION_KEY)) { + bool value = false; + + sensor_data_get_bool(g_ad->motion_data, &value); + + // Update the response representation about the Motion sensor property which is sent to the client + resp_rep->set_bool_value(resp_rep, SENSOR_MOTION_KEY, value); + + _D("Value : %d", value); + + return true; + } else { + _E("not supported property"); + + return false; + } +} + +static bool __handle_get_request_on_led (st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + if (req_msg->has_property_key(req_msg, SENSOR_LED_KEY)) { + const char *str = NULL; + + sensor_data_get_string(g_ad->led_data, &str); + + if (!str) { + str = SENSOR_LED_INIT; + } + + // Update the response representation about the LED property which is sent to the client + resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str); + + _D("Power : %s", str); + + return true; + } else { + _E("not supported property"); + + return false; + } +} + +static bool __handle_set_request_on_led (st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + int ret = 0; + char *str = NULL; + + if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_LED_KEY, &str)) { + retv_if(!str, false); + + _D("set [%s:%s] == %s", SENSOR_LED_URI, SENSOR_LED_KEY, str); + + // Update the response representation about the LED property which is sent to the client + resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str); + + // Turn on LED light + ret = __change_led_data(g_ad, strdup(str)); + + retv_if(ret != 0, false); + } else { + _E("cannot get a string value"); + + return false; + + } + + free(str); + + return true; +} + +void gathering_start(void *data) +{ + app_data *ad = data; + ret_if(!ad); + + if (ad->getter_motion) + ecore_timer_del(ad->getter_motion); + + ad->getter_motion = ecore_timer_add(1.0f, __change_motion_sensor_data, ad); + + if (!ad->getter_motion) { + _E("Failed to add infrared motion getter timer"); + } + + return; +} + +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\n", 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) +{ + bool ret = false; + + _D("resource_uri [%s]", req_msg->resource_uri); + retv_if(!g_ad, false); + + if (0 == strcmp(req_msg->resource_uri, SENSOR_MOTION_URI)) { + _D("query : %s, property: %s", req_msg->query, req_msg->property_key); + + // Call get request function for motion sensor + ret = __handle_get_request_on_motion(req_msg, resp_rep); + } else if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) { + _D("query : %s, property: %s", req_msg->query, req_msg->property_key); + + // Call get request function for LED + ret = __handle_get_request_on_led(req_msg, resp_rep); + } else { + _E("not supported uri"); + } + + return ret; +} + +static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep) +{ + bool ret = false; + + _D("resource_uri [%s]", req_msg->resource_uri); + retv_if(!g_ad, false); + + if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) { + // Call set request function for LED + ret = __handle_set_request_on_led(req_msg, resp_rep); + } else { + _E("not supported uri"); + } + + return ret; +} + +static int __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; + } + + // Specify the read-only and read-write 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_data_path); + + snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_NAME); + free(app_res_path); + + // Specify the device configuration JSON file and change the status of easysetup_complete + if (0 != st_things_initialize(app_json_path, &easysetup_complete)) { + _E("st_things_initialize() failed!!"); + return -1; + } + + _D("easysetup_complete:[%d] ", easysetup_complete); + + // Register callback for handling request get (handle_get_request) and request set (handle_set_request) messages + st_things_register_request_cb(handle_get_request, handle_set_request); + // Register callback for reset confirmation (handle_reset_request) and reset result(handle_reset_result) functions + st_things_register_reset_cb(handle_reset_request, handle_reset_result); + // Register callback for getting user confirmation for ownership transfer (handle_ownership_transfer_request) + st_things_register_user_confirm_cb(handle_ownership_transfer_request); + // Register callback for getting notified when ST Things state changes (handle_things_status_change) + st_things_register_things_status_change_cb(handle_things_status_change); + + return 0; +} + +static int __things_deinit(void) +{ + st_things_deinitialize(); + return 0; +} + +static int __things_start(void) +{ + st_things_start(); + return 0; +} + +static int __things_stop(void) +{ + st_things_stop(); + return 0; +} + +static bool service_app_create(void *user_data) +{ + app_data *ad = user_data; + + // Declare new sensor data for Motion data + ad->motion_data = sensor_data_new(SENSOR_DATA_TYPE_BOOL); + + if (!ad->motion_data) + return false; + + // Declare new sensor data for LED data + ad->led_data = sensor_data_new(SENSOR_DATA_TYPE_STR); + + if (!ad->led_data) + return false; + + sensor_data_set_string(g_ad->led_data, SENSOR_LED_INIT, strlen(SENSOR_LED_INIT)); + + if (__things_init()) + return false; + + return true; +} + +static void service_app_control(app_control_h app_control, void *user_data) +{ + __things_start(); +} + +static void service_app_terminate(void *user_data) +{ + app_data *ad = (app_data *)user_data; + + // Delete ecore timer + if (ad->getter_motion) + ecore_timer_del(ad->getter_motion); + + // Stop and deinitialize things + __things_stop(); + __things_deinit(); + + // Turn off LED light with __set_led() + __change_led_data(ad, LED_OFF); + + // Free sensor Motion & LED data + sensor_data_free(ad->motion_data); + sensor_data_free(ad->led_data); + + // Close Motion and LED resources + resource_close_infrared_motion_sensor(); + resource_close_led(); + + // Free app data + free(ad); + + FN_END; +} + +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/src/resource/resource_infrared_motion_sensor.c b/src/resource/resource_infrared_motion_sensor.c new file mode 100755 index 0000000..d0605e6 --- /dev/null +++ b/src/resource/resource_infrared_motion_sensor.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2018 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 <peripheral_io.h> + +#include "log.h" + +static peripheral_gpio_h g_sensor_h = NULL; +static int g_pin_num = -1; + +void resource_close_infrared_motion_sensor(void) +{ + if (!g_sensor_h) return; + + _I("Infrared Motion Sensor is finishing..."); + + peripheral_gpio_close(g_sensor_h); + + g_sensor_h = NULL; + g_pin_num = -1; +} + +int resource_read_infrared_motion_sensor(int pin_num, uint32_t *out_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (!g_sensor_h) { + peripheral_gpio_h temp = NULL; + + ret = peripheral_gpio_open(pin_num, &temp); + retv_if(ret, -1); + + ret = peripheral_gpio_set_direction(temp, PERIPHERAL_GPIO_DIRECTION_IN); + if (ret) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_set_direction failed."); + return -1; + } + + g_sensor_h = temp; + g_pin_num = pin_num; + } + + if (g_pin_num != pin_num) { + _E("Invalid pin number."); + return -1; + } + + ret = peripheral_gpio_read(g_sensor_h, out_value); + retv_if(ret < 0, -1); + + return 0; +} diff --git a/src/resource/resource_led.c b/src/resource/resource_led.c new file mode 100755 index 0000000..242cf73 --- /dev/null +++ b/src/resource/resource_led.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 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 <peripheral_io.h> + +#include "log.h" + +static peripheral_gpio_h g_sensor_h = NULL; +static int g_pin_num = -1; + +void resource_close_led(void) +{ + if (!g_sensor_h) return; + + _I("LED is finishing..."); + + peripheral_gpio_close(g_sensor_h); + + g_sensor_h = NULL; + g_pin_num = -1; +} + +int resource_write_led(int pin_num, int write_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (!g_sensor_h) { + peripheral_gpio_h temp = NULL; + + ret = peripheral_gpio_open(pin_num, &temp); + retv_if(ret, -1); + + ret = peripheral_gpio_set_direction(temp, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW); + if (ret) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_set_direction failed."); + return -1; + } + + g_sensor_h = temp; + g_pin_num = pin_num; + } + + if (g_pin_num != pin_num) { + _E("Invalid pin number."); + return -1; + } + + ret = peripheral_gpio_write(g_sensor_h, write_value); + retv_if(ret < 0, -1); + + _I("LED Value : %s", write_value ? "ON":"OFF"); + + return 0; +} diff --git a/src/sensor-data.c b/src/sensor-data.c new file mode 100755 index 0000000..950aab0 --- /dev/null +++ b/src/sensor-data.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2018 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 <stdlib.h> +#include <pthread.h> +#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(type == SENSOR_DATA_TYPE_NONE, 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); + 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; +} + |