tizen 5.0 update
[apps/native/illuminance-sensor.git] / src / illuminance_sensor.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <Ecore.h>
23
24 #include "log.h"
25
26 #include "smartthings.h"
27 #include "smartthings_resource.h"
28 #include "smartthings_payload.h"
29
30 // Duration for a timer
31 #define TIMER_SENSOR_INTERVAL (.250f)
32 Ecore_Timer *sensor_event_timer = NULL;
33
34 #define THING_RESOURCE_FILE_NAME        "resource.json"
35
36 static smartthings_resource_h st_handle = NULL;
37 static bool is_init = false;
38 static bool is_resource_init = false;
39 static smartthings_h st_h;
40
41 smartthings_status_e st_things_status = -1;
42
43 static const char *RES_CAPABILITY_SWITCH_MAIN_0 = "/capability/switch/main/0";
44 static const char *RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0 = "/capability/illuminanceMeasurement/main/0";
45 static const char *PROP_ILLUMINANCE = "illuminance";
46
47 /* get and set request handlers */
48 extern bool handle_get_request_on_resource_capability_switch_main_0(smartthings_payload_h resp_payload, void *user_data);
49 extern bool handle_set_request_on_resource_capability_switch_main_0(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data);
50 extern bool handle_get_request_on_resource_capability_illuminancemeasurement_main_0(smartthings_payload_h resp_payload, void *user_data);
51
52 extern int resource_read_illuminance_sensor(uint16_t *out_value);
53 extern int resource_close_illuminance_sensor(void);
54
55 static Eina_Bool _get_sensor_data(void *user_data)
56 {
57         int ret = 0;
58         uint16_t value = 0;
59
60         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
61         smartthings_payload_h resp_payload = NULL;
62
63         if (st_things_status != SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD)
64                 return ECORE_CALLBACK_RENEW;
65
66         if (!st_handle) {
67                 _E("st_handle is NULL");
68                 return ECORE_CALLBACK_RENEW;
69         }
70
71         ret = resource_read_illuminance_sensor(&value);
72         if (ret != 0) {
73                 _E("cannot read data from the sensor");
74                 return ECORE_CALLBACK_CANCEL;
75         }
76
77         _D("Detected sensor value is: %u", value);
78
79         error = smartthings_payload_create(&resp_payload);
80         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE || !resp_payload) {
81                 _E("smartthings_payload_create() failed, [%d]", error);
82                 return ECORE_CALLBACK_CANCEL;
83         }
84
85         error = smartthings_payload_set_int(resp_payload, PROP_ILLUMINANCE, (int)value);
86         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE)
87                 _E("smartthings_payload_set_int() failed, [%d]", error);
88
89         error = smartthings_resource_notify(st_handle, RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0, resp_payload);
90         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE)
91                 _E("smartthings_resource_notify() failed, [%d]", error);
92
93         if (smartthings_payload_destroy(resp_payload))
94                 _E("smartthings_payload_destroy() failed");
95
96         return ECORE_CALLBACK_RENEW;
97 }
98
99 void _send_response_result_cb(smartthings_resource_error_e result, void *user_data)
100 {
101         _D("app_control reply callback for send_response : result=[%d]", result);
102 }
103
104 void _notify_result_cb(smartthings_resource_error_e result, void *user_data)
105 {
106         _D("app_control reply callback for notify : result=[%d]", result);
107 }
108
109 void _request_cb(smartthings_resource_h st_h, int req_id, const char *uri, smartthings_resource_req_type_e req_type,
110                                 smartthings_payload_h payload, void *user_data)
111 {
112         START;
113
114         smartthings_payload_h resp_payload = NULL;
115
116         smartthings_payload_create(&resp_payload);
117         if (!resp_payload) {
118                 _E("Response payload is NULL");
119                 return;
120         }
121
122         bool result = false;
123
124         if (req_type == SMARTTHINGS_RESOURCE_REQUEST_GET) {
125                 if (0 == strncmp(uri, RES_CAPABILITY_SWITCH_MAIN_0, strlen(RES_CAPABILITY_SWITCH_MAIN_0))) {
126                         result = handle_get_request_on_resource_capability_switch_main_0(resp_payload, user_data);
127                 }
128                 if (0 == strncmp(uri, RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0, strlen(RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0))) {
129                         result = handle_get_request_on_resource_capability_illuminancemeasurement_main_0(resp_payload, user_data);
130                 }
131         } else if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) {
132                 if (0 == strncmp(uri, RES_CAPABILITY_SWITCH_MAIN_0, strlen(RES_CAPABILITY_SWITCH_MAIN_0))) {
133                         result = handle_set_request_on_resource_capability_switch_main_0(payload, resp_payload, user_data);
134                 }
135         } else {
136                 _E("Invalid request type");
137                 smartthings_payload_destroy(resp_payload);
138                 END;
139                 return;
140         }
141
142         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
143
144         error = smartthings_resource_send_response(st_h, req_id, uri, resp_payload, result);
145         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
146                         smartthings_payload_destroy(resp_payload);
147                         _E("smartthings_resource_send_response() failed, err=[%d]", error);
148                         END;
149                         return;
150         }
151
152         if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) {
153                         error = smartthings_resource_notify(st_h, uri, resp_payload);
154                         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
155                                 _E("smartthings_resource_notify() failed, err=[%d]", error);
156                         }
157         }
158
159         if (smartthings_payload_destroy(resp_payload) != 0) {
160                 _E("smartthings_payload_destroy failed");
161         }
162
163         END;
164         return;
165 }
166
167 static void _resource_connection_status_cb(smartthings_resource_h handle, smartthings_resource_connection_status_e status, void *user_data)
168 {
169         START;
170
171         if (status == SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED) {
172                 if (smartthings_resource_set_request_cb(st_handle, _request_cb, NULL) != 0) {
173                         _E("smartthings_resource_set_request_cb() is failed");
174                         return;
175                 }
176         } else {
177                 _I("connection failed, status=[%d]", status);
178         }
179
180         END;
181         return;
182 }
183
184 int init_resource_app()
185 {
186         START;
187
188         if (is_resource_init) {
189                 _I("Already initialized!");
190                 return 0;
191         }
192
193         if (smartthings_resource_initialize(&st_handle, _resource_connection_status_cb, NULL) != 0) {
194                 _E("smartthings_resource_initialize() is failed");
195                 goto _out;
196         }
197
198         is_resource_init = true;
199
200         END;
201         return 0;
202
203 _out :
204         END;
205         return -1;
206 }
207
208 int deinit_resource_app()
209 {
210         START;
211
212         if (!st_handle)
213                 return 0;
214
215         smartthings_resource_unset_request_cb(st_handle);
216
217         if (smartthings_resource_deinitialize(st_handle) != 0)
218                 return -1;
219
220         is_resource_init = false;
221
222         END;
223         return 0;
224 }
225
226
227 void _user_confirm_cb(smartthings_h handle, void *user_data)
228 {
229         START;
230
231         if (smartthings_send_user_confirm(handle, true) != 0)
232                 _E("smartthings_send_user_confirm() is failed");
233
234         END;
235         return;
236 }
237
238 void _reset_confirm_cb(smartthings_h handle, void *user_data)
239 {
240         START;
241
242         if (smartthings_send_reset_confirm(handle, true) != 0)
243                 _E("smartthings_send_reset_confirm() is failed");
244
245         END;
246         return;
247 }
248
249 static void _reset_result_cb(smartthings_h handle, bool result, void *user_data)
250 {
251         START;
252
253         _I("reset result = [%d]", result);
254
255         END;
256         return;
257 }
258
259 static void _thing_status_cb(smartthings_h handle, smartthings_status_e status, void *user_data)
260 {
261         START;
262
263         _D("Received status changed cb : status = [%d]", status);
264         st_things_status = status;
265
266         switch (status) {
267         case SMARTTHINGS_STATUS_NOT_READY:
268                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_NOT_READY");
269                         break;
270         case SMARTTHINGS_STATUS_INIT:
271                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_INIT");
272                         break;
273         case SMARTTHINGS_STATUS_ES_STARTED:
274                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_STARTED");
275                         break;
276         case SMARTTHINGS_STATUS_ES_DONE:
277                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_DONE");
278                         break;
279         case SMARTTHINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER:
280                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER");
281                         break;
282         case SMARTTHINGS_STATUS_CONNECTING_TO_AP:
283                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTING_TO_AP");
284                         break;
285         case SMARTTHINGS_STATUS_CONNECTED_TO_AP:
286                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTED_TO_AP");
287                         break;
288         case SMARTTHINGS_STATUS_CONNECTING_TO_AP_FAILED:
289                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTING_TO_AP_FAILED");
290                         break;
291         case SMARTTHINGS_STATUS_REGISTERING_TO_CLOUD:
292                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_TO_CLOUD");
293                         break;
294         case SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD:
295                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD");
296                         break;
297         case SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN:
298                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN");
299                         break;
300         case SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES:
301                         _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES");
302                         break;
303         default:
304                         _E("status: [%d][%s]", status, "Unknown Status");
305                         break;
306         }
307         END;
308         return;
309 }
310
311 static void _things_connection_status_cb(smartthings_h handle, smartthings_connection_status_e status, void *user_data)
312 {
313         START;
314
315         _D("Received connection status changed cb : status = [%d]", status);
316
317         if (status == SMARTTHINGS_CONNECTION_STATUS_CONNECTED) {
318                 const char* dev_name = "IoT Test Device";
319                 int wifi_mode = SMARTTHINGS_WIFI_MODE_11B | SMARTTHINGS_WIFI_MODE_11G | SMARTTHINGS_WIFI_MODE_11N;
320                 int wifi_freq = SMARTTHINGS_WIFI_FREQ_24G | SMARTTHINGS_WIFI_FREQ_5G;
321
322                 if (smartthings_set_device_property(handle, dev_name, wifi_mode, wifi_freq) != 0) {
323                         _E("smartthings_initialize() is failed");
324                         return;
325                 }
326
327                 if (smartthings_set_certificate_file(handle, "certificate.pem", "privatekey.der") != 0) {
328                         _E("smartthings_set_certificate_file() is failed");
329                         return;
330                 }
331
332                 if (smartthings_set_user_confirm_cb(st_h, _user_confirm_cb, NULL) != 0) {
333                         _E("smartthings_set_user_confirm_cb() is failed");
334                         return;
335                 }
336
337                 if (smartthings_set_reset_confirm_cb(handle, _reset_confirm_cb, NULL) != 0) {
338                         _E("smartthings_set_reset_confirm_cb() is failed");
339                         return;
340                 }
341
342                 if (smartthings_set_reset_result_cb(handle, _reset_result_cb, NULL) != 0) {
343                         _E("smartthings_set_reset_confirm_cb() is failed");
344                         return;
345                 }
346
347                 if (smartthings_set_status_changed_cb(handle, _thing_status_cb, NULL) != 0) {
348                         _E("smartthings_set_status_changed_callback() is failed");
349                         return;
350                 }
351
352                 if (smartthings_start(handle) != 0) {
353                         _E("smartthings_start() is failed");
354                         return;
355                 }
356
357                 bool is_es_completed = false;
358                 if (smartthings_get_easysetup_status(handle, &is_es_completed) != 0) {
359                         _E("smartthings_get_easysetup_status() is failed");
360                         return;
361                 }
362
363                 if (is_es_completed == true) {
364                         _I("Easysetup is already done");
365                         return;
366                 }
367
368                 if (smartthings_start_easysetup(handle) != 0) {
369                         _E("smartthings_start_easysetup() is failed");
370                         return;
371                 }
372         } else {
373                         _E("connection failed, status=[%d]", status);
374         }
375
376         END;
377         return;
378 }
379
380 int init_master_app()
381 {
382         START;
383
384         if (is_init) {
385                 _I("Already initialized!");
386                 END;
387                 return 0;
388         }
389
390         if (smartthings_initialize(&st_h, _things_connection_status_cb, NULL) != 0) {
391                 _E("smartthings_initialize() is failed");
392                 goto _out;
393         }
394
395         is_init = true;
396
397         END;
398         return 0;
399
400 _out :
401         END;
402         return -1;
403 }
404
405 int deinit_master_app()
406 {
407         START;
408
409         is_init = false;
410
411         if (!st_h) {
412                 _I("handle is already NULL");
413                 END;
414                 return 0;
415         }
416
417         smartthings_unset_user_confirm_cb(st_h);
418         smartthings_unset_reset_confirm_cb(st_h);
419         smartthings_unset_reset_result_cb(st_h);
420         smartthings_unset_status_changed_cb(st_h);
421
422         if (smartthings_deinitialize(st_h) != 0)  {
423                 _E("smartthings_deinitialize() is failed");
424                 END;
425                 return -1;
426         }
427
428         END;
429         return 0;
430 }
431
432 static bool service_app_create(void *user_data)
433 {
434         if (sensor_event_timer)
435                 ecore_timer_del(sensor_event_timer);
436
437         sensor_event_timer = ecore_timer_add(TIMER_SENSOR_INTERVAL, _get_sensor_data, NULL);
438         if (!sensor_event_timer)
439                 _E("Failed to add a timer");
440
441         return true;
442 }
443
444 static void service_app_terminate(void *user_data)
445 {
446         // clear timer resource
447         if (sensor_event_timer) {
448                 ecore_timer_del(sensor_event_timer);
449                 sensor_event_timer = NULL;
450         }
451
452         // close sensor resource
453         resource_close_illuminance_sensor();
454
455         /*terminate resource*/
456         if (deinit_resource_app() != 0) {
457                 _E("deinit_resource_app failed");
458         }
459
460         /*terminate master*/
461         if (deinit_master_app() != 0) {
462                 _E("deinit_master_app failed");
463         }
464
465         return;
466 }
467
468 static void service_app_control(app_control_h app_control, void *user_data)
469 {
470         if (app_control == NULL) {
471                 _E("app_control is NULL");
472                 return;
473         }
474
475         init_master_app();
476         init_resource_app();
477
478         return;
479 }
480
481 int main(int argc, char *argv[])
482 {
483         service_app_lifecycle_callback_s event_callback;
484
485         event_callback.create = service_app_create;
486         event_callback.terminate = service_app_terminate;
487         event_callback.app_control = service_app_control;
488
489         return service_app_main(argc, argv, &event_callback, NULL);
490 }