Update comments in controller.c
[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 LED_ON "on"
37 #define LED_OFF "off"
38
39 #define USE_ST_SDK
40
41 typedef struct app_data_s {
42         Ecore_Timer *getter_motion;
43         sensor_data *motion_data;
44         sensor_data *led_data;
45 } app_data;
46
47 static app_data *g_ad = NULL;
48
49 static Eina_Bool control_sensors_cb(void *data)
50 {
51         uint32_t value = 0;
52
53         /* Gets value from motion sensor */
54         int ret = resource_read_infrared_motion_sensor(46, &value);
55         if (ret != 0) _E("Cannot read sensor value");
56
57         sensor_data_set_bool(g_ad->motion_data, value);
58         _D("Detected motion value is: %d", value);
59
60         // Notify motion sensor change
61         st_things_notify_observers(SENSOR_MOTION_URI);
62
63         return ECORE_CALLBACK_RENEW;
64 }
65
66 static int __set_led_light(void *data, char *state) {
67         int ret = 0;
68         app_data *ad = data;
69
70         retv_if(!ad, -1);
71         retv_if(!ad->led_data, -1);
72
73         if (0 == strcmp(state, LED_ON)) {
74                 ret = resource_write_led(130, 1);
75         } else {
76                 ret = resource_write_led(130, 0);
77         }
78
79         retv_if(ret != 0, -1);
80
81         // Set LED sensor data
82         sensor_data_set_string(ad->led_data, state, strlen(state));
83
84         // Log LED sensor value
85         _D("Set LED to %s", state);
86
87         // Notify LED sensor change
88         st_things_notify_observers(SENSOR_LED_URI);
89
90         return 0;
91 }
92
93 void gathering_start(void *data)
94 {
95         app_data *ad = data;
96         ret_if(!ad);
97
98         if (ad->getter_motion)
99                 ecore_timer_del(ad->getter_motion);
100
101         ad->getter_motion = ecore_timer_add(1.0f, control_sensors_cb, ad);
102
103         if (!ad->getter_motion) {
104                 _E("Failed to add infrared motion getter timer");
105         }
106
107         return;
108 }
109
110 static bool handle_reset_request(void)
111 {
112         _D("Received a request for RESET.");
113         return false;
114 }
115
116 static void handle_reset_result(bool result)
117 {
118         _D("Reset %s.\n", result ? "succeeded" : "failed");
119 }
120
121 static bool handle_ownership_transfer_request(void)
122 {
123         _D("Received a request for Ownership-transfer.");
124         return true;
125 }
126
127 static void handle_things_status_change(st_things_status_e things_status)
128 {
129         _D("Things status is changed: %d\n", things_status);
130
131         if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD)
132                 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
133 }
134
135 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
136 {
137         _D("resource_uri [%s]", req_msg->resource_uri);
138         retv_if(!g_ad, false);
139
140         if (0 == strcmp(req_msg->resource_uri, SENSOR_MOTION_URI)) {
141                 _D("query : %s, property: %s", req_msg->query, req_msg->property_key);
142
143                 if (req_msg->has_property_key(req_msg, SENSOR_MOTION_KEY)) {
144                         bool value = false;
145
146                         // Get Motion sensor data
147                         sensor_data_get_bool(g_ad->motion_data, &value);
148
149                         // Set Motion sensor value value for smart things representation
150                         resp_rep->set_bool_value(resp_rep, SENSOR_MOTION_KEY, value);
151
152                         _D("Value : %d", value);
153                 }
154
155                 return true;
156         } else if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) {
157                 _D("query : %s, property: %s", req_msg->query, req_msg->property_key);
158
159                 if (req_msg->has_property_key(req_msg, SENSOR_LED_KEY)) {
160                         // Set LED sensor data
161                         const char *str = NULL;
162
163                         // Get LED sensor data
164                         sensor_data_get_string(g_ad->led_data, &str);
165
166                         // Set initial value for LED data if data does not exist
167                         if (!str) {
168                                 str = SENSOR_LED_INIT;
169                         }
170
171                         // Set Motion sensor value value for smart things representation
172                         resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str);
173
174                         _D("Power : %s", str);
175                 }
176                 return true;
177         }
178
179         _E("not supported uri");
180         return false;
181 }
182
183 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
184 {
185         _D("resource_uri [%s]", req_msg->resource_uri);
186         retv_if(!g_ad, false);
187
188                 if (0 == strcmp(req_msg->resource_uri, SENSOR_LED_URI)) {
189                         int ret = 0;
190                         char *str = NULL;
191
192                         if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_LED_KEY, &str)) {
193                                 retv_if(!str, false);
194                                 _D("set [%s:%s] == %s", SENSOR_LED_URI, SENSOR_LED_KEY, str);
195
196                                 // Set LED sensor data
197                                 sensor_data_set_string(g_ad->led_data, str, strlen(str));
198
199                                 // Set Motion sensor value value for smart things representation
200                                 resp_rep->set_str_value(resp_rep, SENSOR_LED_KEY, str);
201
202                                 // Turn on LED light with __set_led_light()
203                                 ret = __set_led_light(g_ad, strdup(str));
204
205                                 retv_if(ret != 0, false);
206                         } else {
207                                 _E("cannot get a string value");
208                         }
209
210                         free(str);
211
212                         return true;
213                 }
214
215         return false;
216 }
217
218 static int __things_init(void)
219 {
220         bool easysetup_complete = false;
221         char app_json_path[128] = {'\0', };
222         char *app_res_path = NULL;
223         char *app_data_path = NULL;
224
225         app_res_path = app_get_resource_path();
226         if (!app_res_path) {
227                 _E("app_res_path is NULL!!");
228                 return -1;
229         }
230
231         app_data_path = app_get_data_path();
232         if (!app_data_path) {
233                 _E("app_data_path is NULL!!");
234                 free(app_res_path);
235                 return -1;
236         }
237
238         if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
239                 _E("st_things_set_configuration_prefix_path() failed!!");
240                 free(app_res_path);
241                 free(app_data_path);
242                 return -1;
243         }
244         free(app_data_path);
245
246         snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_NAME);
247         free(app_res_path);
248
249         if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
250                 _E("st_things_initialize() failed!!");
251                 return -1;
252         }
253
254         _D("easysetup_complete:[%d] ", easysetup_complete);
255
256         st_things_register_request_cb(handle_get_request, handle_set_request);
257         st_things_register_reset_cb(handle_reset_request, handle_reset_result);
258         st_things_register_user_confirm_cb(handle_ownership_transfer_request);
259         st_things_register_things_status_change_cb(handle_things_status_change);
260
261         return 0;
262 }
263
264 static int __things_deinit(void)
265 {
266         st_things_deinitialize();
267         return 0;
268 }
269
270 static int __things_start(void)
271 {
272         st_things_start();
273         return 0;
274 }
275
276 static int __things_stop(void)
277 {
278         st_things_stop();
279         return 0;
280 }
281
282 static bool service_app_create(void *user_data)
283 {
284         app_data *ad = user_data;
285
286         // Declare new sensor data for Motion data
287         ad->motion_data = sensor_data_new(SENSOR_DATA_TYPE_BOOL);
288         if (!ad->motion_data)
289                 return false;
290
291         // Declare new sensor data for LED data
292         ad->led_data = sensor_data_new(SENSOR_DATA_TYPE_STR);
293         if (!ad->led_data)
294                 return false;
295
296         // Initialize LED sensor data
297         sensor_data_set_string(g_ad->led_data, SENSOR_LED_INIT, strlen(SENSOR_LED_INIT));
298
299         if (__things_init())
300                 return false;
301
302         return true;
303 }
304
305 static void service_app_control(app_control_h app_control, void *user_data)
306 {
307         __things_start();
308 }
309
310 static void service_app_terminate(void *user_data)
311 {
312         app_data *ad = (app_data *)user_data;
313
314         // Delete ecore timer
315         if (ad->getter_motion)
316                 ecore_timer_del(ad->getter_motion);
317
318         // Stop and deinitialize things
319         __things_stop();
320         __things_deinit();
321
322         // Turn off LED light with __set_led_light()
323         __set_led_light(ad, LED_OFF);
324
325         // Free sensor Motion & LED data
326         sensor_data_free(ad->motion_data);
327         sensor_data_free(ad->led_data);
328
329         // Close Motion and LED resources
330         resource_close_infrared_motion_sensor(46);
331         resource_close_led(130);
332
333         // Free app data
334         free(ad);
335
336         FN_END;
337 }
338
339 int main(int argc, char *argv[])
340 {
341         app_data *ad = NULL;
342         service_app_lifecycle_callback_s event_callback;
343
344         ad = calloc(1, sizeof(app_data));
345         retv_if(!ad, -1);
346
347         g_ad = ad;
348
349         event_callback.create = service_app_create;
350         event_callback.terminate = service_app_terminate;
351         event_callback.app_control = service_app_control;
352
353         return service_app_main(argc, argv, &event_callback, ad);
354 }
355