3b1404e69ab7c153552d8e8fdbcc9fab1d66e6fa
[apps/native/rcc.git] / smartthings-final / src / controller.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <tizen.h>
18 #include <service_app.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <Ecore.h>
22
23 #include "st_things.h"
24 #include "log.h"
25 #include "resource/resource_infrared_motion_sensor.h"
26 #include "resource/resource_led.h"
27 #include "sensor-data.h"
28
29 #define JSON_NAME "device_def.json"
30 #define SENSOR_MOTION_URI "/capability/motionSensor/main/0"
31 #define SENSOR_MOTION_KEY "value"
32 #define SENSOR_LED_URI "/capability/switch/main/0"
33 #define SENSOR_LED_KEY "power"
34 #define SENSOR_LED_INIT "off"
35
36 #define SENSORING_TIME_INTERVAL (1.0f)
37 #define SENSOR_MOTION_PIN_NUM (46)
38 #define SENSOR_LED_PIN_NUM (130)
39
40 #define LED_ON "on"
41 #define LED_OFF "off"
42
43 #define USE_ST_SDK
44
45 typedef struct app_data_s {
46         Ecore_Timer *getter_motion;
47         sensor_data *motion_data;
48         sensor_data *led_data;
49 } app_data;
50
51 static app_data *g_ad = NULL;
52
53 static Eina_Bool control_sensors_cb(void *data)
54 {
55         uint32_t value = 0;
56
57         /* Gets value from motion sensor */
58         int ret = resource_read_infrared_motion_sensor(SENSOR_MOTION_PIN_NUM, &value);
59         if (ret != 0) _E("Cannot read sensor value");
60
61         sensor_data_set_bool(g_ad->motion_data, value);
62         _D("Detected motion value is: %d", value);
63
64         #ifdef USE_ST_SDK
65                 st_things_notify_observers(SENSOR_MOTION_URI);
66         #endif
67
68         return ECORE_CALLBACK_RENEW;
69 }
70
71 static int __set_led_light(void *data, char *state) {
72         int ret = 0;
73         app_data *ad = data;
74
75         retv_if(!ad, -1);
76         retv_if(!ad->led_data, -1);
77
78         if (0 == strcmp(state, LED_ON)) {
79                 ret = resource_write_led(SENSOR_LED_PIN_NUM, 1);
80         } else {
81                 ret = resource_write_led(SENSOR_LED_PIN_NUM, 0);
82         }
83
84         retv_if(ret != 0, -1);
85
86         sensor_data_set_string(ad->led_data, state, strlen(state));
87         _D("Set LED to %s", state);
88
89 #ifdef USE_ST_SDK
90         st_things_notify_observers(SENSOR_LED_URI);
91 #endif
92
93         return 0;
94 }
95
96 void gathering_start(void *data)
97 {
98         app_data *ad = data;
99         ret_if(!ad);
100
101         if (ad->getter_motion)
102                 ecore_timer_del(ad->getter_motion);
103
104         ad->getter_motion = ecore_timer_add(SENSORING_TIME_INTERVAL, control_sensors_cb, ad);
105
106         if (!ad->getter_motion) {
107                 _E("Failed to add infrared motion getter timer");
108         }
109
110         return;
111 }
112
113 #ifdef USE_ST_SDK
114 static bool handle_reset_request(void)
115 {
116         _D("Received a request for RESET.");
117         return false;
118 }
119
120 static void handle_reset_result(bool result)
121 {
122         _D("Reset %s.\n", result ? "succeeded" : "failed");
123 }
124
125 static bool handle_ownership_transfer_request(void)
126 {
127         _D("Received a request for Ownership-transfer.");
128         return true;
129 }
130
131 static void handle_things_status_change(st_things_status_e things_status)
132 {
133         _D("Things status is changed: %d\n", things_status);
134
135         if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD)
136                 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
137 }
138
139 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
140 {
141         _D("resource_uri [%s]", req_msg->resource_uri);
142         retv_if(!g_ad, false);
143
144         if (0 == strcmp(req_msg->resource_uri, SENSOR_MOTION_URI)) {
145                 _D("query : %s, property: %s", req_msg->query, req_msg->property_key);
146
147                 if (req_msg->has_property_key(req_msg, SENSOR_MOTION_KEY)) {
148                         bool value = false;
149                         sensor_data_get_bool(g_ad->motion_data, &value);
150                         _D("Value : %d", value);
151                         resp_rep->set_bool_value(resp_rep, SENSOR_MOTION_KEY, value);
152                 }
153
154                 return true;
155         } else if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) {
156                 _D("query : %s, property: %s", req_msg->query, req_msg->property_key);
157
158                 if (req_msg->has_property_key(req_msg, SENSOR_LED_KEY)) {
159                         const char *str = NULL;
160                         sensor_data_get_string(g_ad->led_data, &str);
161                         if (!str) {
162                                 str = SENSOR_LED_INIT;
163                         }
164                         resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str);
165                         _D("Power : %s", str);
166                 }
167                 return true;
168         }
169
170         _E("not supported uri");
171         return false;
172 }
173
174 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
175 {
176         _D("resource_uri [%s]", req_msg->resource_uri);
177         retv_if(!g_ad, false);
178
179                 if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) {
180                         int ret = 0;
181                         char *str = NULL;
182
183                         if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_LED_KEY, &str)) {
184                                 retv_if(!str, false);
185                                 _D("set [%s:%s] == %s", SENSOR_LED_URI, SENSOR_LED_KEY, str);
186
187                                 sensor_data_set_string(g_ad->led_data, str, strlen(str));
188                                 resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str);
189                                 ret = __set_led_light(g_ad, strdup(str));
190
191                                 retv_if(ret != 0, false);
192                         } else {
193                                 _E("cannot get a string value");
194                         }
195
196                         free(str);
197
198                         return true;
199                 }
200
201         return false;
202 }
203
204 static int __things_init(void)
205 {
206         bool easysetup_complete = false;
207         char app_json_path[128] = {'\0', };
208         char *app_res_path = NULL;
209         char *app_data_path = NULL;
210
211         app_res_path = app_get_resource_path();
212         if (!app_res_path) {
213                 _E("app_res_path is NULL!!");
214                 return -1;
215         }
216
217         app_data_path = app_get_data_path();
218         if (!app_data_path) {
219                 _E("app_data_path is NULL!!");
220                 free(app_res_path);
221                 return -1;
222         }
223
224         if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
225                 _E("st_things_set_configuration_prefix_path() failed!!");
226                 free(app_res_path);
227                 free(app_data_path);
228                 return -1;
229         }
230         free(app_data_path);
231
232         snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_NAME);
233         free(app_res_path);
234
235         if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
236                 _E("st_things_initialize() failed!!");
237                 return -1;
238         }
239
240         _D("easysetup_complete:[%d] ", easysetup_complete);
241
242         st_things_register_request_cb(handle_get_request, handle_set_request);
243         st_things_register_reset_cb(handle_reset_request, handle_reset_result);
244         st_things_register_user_confirm_cb(handle_ownership_transfer_request);
245         st_things_register_things_status_change_cb(handle_things_status_change);
246
247         return 0;
248 }
249
250 static int __things_deinit(void)
251 {
252         st_things_deinitialize();
253         return 0;
254 }
255
256 static int __things_start(void)
257 {
258         st_things_start();
259         return 0;
260 }
261
262 static int __things_stop(void)
263 {
264         st_things_stop();
265         return 0;
266 }
267 #endif /* USE_ST_SDK */
268
269 static bool service_app_create(void *user_data)
270 {
271         app_data *ad = user_data;
272
273         ad->motion_data = sensor_data_new(SENSOR_DATA_TYPE_BOOL);
274         if (!ad->motion_data)
275                 return false;
276
277         ad->led_data = sensor_data_new(SENSOR_DATA_TYPE_STR);
278         if (!ad->led_data)
279                 return false;
280
281         sensor_data_set_string(g_ad->led_data, SENSOR_LED_INIT, strlen(SENSOR_LED_INIT));
282
283         #ifdef USE_ST_SDK
284                 if (__things_init())
285                         return false;
286         #endif
287
288         return true;
289 }
290
291 static void service_app_control(app_control_h app_control, void *user_data)
292 {
293 #ifdef USE_ST_SDK
294         __things_start();
295 #else
296         gathering_start(user_data);
297 #endif
298 }
299
300 static void service_app_terminate(void *user_data)
301 {
302         app_data *ad = (app_data *)user_data;
303
304         if (ad->getter_motion)
305                 ecore_timer_del(ad->getter_motion);
306
307 #ifdef USE_ST_SDK
308         __things_stop();
309         __things_deinit();
310 #endif
311
312         __set_led_light(ad, LED_OFF);
313
314         sensor_data_free(ad->motion_data);
315         sensor_data_free(ad->led_data);
316
317         resource_close_infrared_motion_sensor(SENSOR_MOTION_PIN_NUM);
318         resource_close_led(SENSOR_LED_PIN_NUM);
319
320         free(ad);
321
322         FN_END;
323 }
324
325 int main(int argc, char *argv[])
326 {
327         app_data *ad = NULL;
328         service_app_lifecycle_callback_s event_callback;
329
330         ad = calloc(1, sizeof(app_data));
331         retv_if(!ad, -1);
332
333         g_ad = ad;
334
335         event_callback.create = service_app_create;
336         event_callback.terminate = service_app_terminate;
337         event_callback.app_control = service_app_control;
338
339         return service_app_main(argc, argv, &event_callback, ad);
340 }
341