tizen 5.0 migration
[apps/native/co2-meter.git] / src / co2sensor.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 <service_app.h>
18 #include <stdio.h>
19 #include "smartthings.h"
20 #include "smartthings_resource.h"
21 #include "smartthings_payload.h"
22 #include "resource/resource_co2_sensor.h"
23 #include "log.h"
24 #include <signal.h>
25
26 static const char *RES_CAPABILITY_SWITCH = "/capability/switch/main/0";
27 static const char *RES_CAPABILITY_THERMOSTATCOOLINGSETPOINT = "/capability/thermostatCoolingSetpoint/main/0";
28 static const char *RES_CAPABILITY_AIRQUALITYSENSOR = "/capability/airQualitySensor/main/0";
29
30 smartthings_resource_h st_handle = NULL;
31 static bool is_init = false;
32 static bool is_resource_init = false;
33 static smartthings_h st_h;
34
35 smartthings_status_e st_things_status = -1;
36
37 pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
38 extern int thread_done; /* resource_co2_sensor.c */
39
40 /* get and set request handlers */
41 extern bool handle_get_request_on_resource_capability_switch_main_0(smartthings_payload_h resp_payload, void *user_data);
42 extern bool handle_set_request_on_resource_capability_switch_main_0(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data);
43 extern bool handle_get_request_on_resource_capability_airqualitysensor_main_0(smartthings_payload_h resp_payload, void *user_data);
44 extern bool handle_get_request_on_resource_capability_thermostatcoolingsetpoint_main_0(smartthings_payload_h resp_payload, void *user_data);
45 extern bool handle_set_request_on_resource_capability_thermostatcoolingsetpoint_main_0(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data);
46
47 extern void *thread_sensor_main(void *arg);
48 extern void *thread_sensor_notify(void *arg);
49
50 void sig_handler(int sig)
51 {
52         switch (sig) {
53         case SIGINT:
54                 _I("SIGINT received");
55                 thread_done = 1;
56                 break;
57         case SIGSEGV:
58                 _I("SIGSEGV received");
59                 thread_done = 1;
60                 break;
61         case SIGTERM:
62                 _I("SIGTERM received");
63                 thread_done = 1;
64                 break;
65         default:
66                 _E("wasn't expecting that sig [%d]", sig);
67                 abort();
68         }
69 }
70
71 /* main loop */
72 void handle_main_loop(void)
73 {
74         pthread_t p_thread[2];
75         int ret = 0;
76
77         signal(SIGSEGV, sig_handler);
78         signal(SIGINT, sig_handler);
79         signal(SIGTERM, sig_handler);
80
81         pthread_mutex_init(&mutex, NULL);
82
83         ret = pthread_create(&p_thread[0], NULL, &thread_sensor_main, NULL);
84         if (ret != 0) {
85                 _E("[ERROR] thread_sensor_main create failed, ret=%d", ret);
86                 return;
87         }
88         ret = pthread_create(&p_thread[1], NULL, &thread_sensor_notify, NULL);
89         if (ret != 0) {
90                 _E("[ERROR] thread_sensor_notify create failed, ret=%d", ret);
91                 return;
92         }
93 }
94
95 void _send_response_result_cb(smartthings_resource_error_e result, void *user_data)
96 {
97         _D("app_control reply callback for send_response : result=[%d]", result);
98 }
99
100 void _notify_result_cb(smartthings_resource_error_e result, void *user_data)
101 {
102         _D("app_control reply callback for notify : result=[%d]", result);
103 }
104
105 void _request_cb(smartthings_resource_h st_h, int req_id, const char *uri, smartthings_resource_req_type_e req_type,
106                                 smartthings_payload_h payload, void *user_data)
107 {
108         START;
109
110         smartthings_payload_h resp_payload = NULL;
111
112         smartthings_payload_create(&resp_payload);
113         if (!resp_payload) {
114                 _E("Response payload is NULL");
115                 return;
116         }
117
118         bool result = false;
119
120         if (req_type == SMARTTHINGS_RESOURCE_REQUEST_GET) {
121                 if (0 == strncmp(uri, RES_CAPABILITY_SWITCH, strlen(RES_CAPABILITY_SWITCH))) {
122                         result = handle_get_request_on_resource_capability_switch_main_0(resp_payload, user_data);
123                 }
124                 if (0 == strncmp(uri, RES_CAPABILITY_AIRQUALITYSENSOR, strlen(RES_CAPABILITY_AIRQUALITYSENSOR))) {
125                         result = handle_get_request_on_resource_capability_airqualitysensor_main_0(resp_payload, user_data);
126                 }
127                 if (0 == strncmp(uri, RES_CAPABILITY_THERMOSTATCOOLINGSETPOINT, strlen(RES_CAPABILITY_THERMOSTATCOOLINGSETPOINT))) {
128                         result = handle_get_request_on_resource_capability_thermostatcoolingsetpoint_main_0(resp_payload, user_data);
129                 }
130         } else if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) {
131                 if (0 == strncmp(uri, RES_CAPABILITY_SWITCH, strlen(RES_CAPABILITY_SWITCH))) {
132                         result = handle_set_request_on_resource_capability_switch_main_0(payload, resp_payload, user_data);
133                 }
134                 if (0 == strncmp(uri, RES_CAPABILITY_THERMOSTATCOOLINGSETPOINT, strlen(RES_CAPABILITY_THERMOSTATCOOLINGSETPOINT))) {
135                         result = handle_set_request_on_resource_capability_thermostatcoolingsetpoint_main_0(payload, resp_payload, user_data);
136                 }
137         } else {
138                 _E("Invalid request type");
139                 smartthings_payload_destroy(resp_payload);
140                 END;
141                 return;
142         }
143
144         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
145
146         error = smartthings_resource_send_response(st_h, req_id, uri, resp_payload, result);
147         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
148                         smartthings_payload_destroy(resp_payload);
149                         _E("smartthings_resource_send_response() failed, err=[%d]", error);
150                         END;
151                         return;
152         }
153
154         if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) {
155                         error = smartthings_resource_notify(st_h, uri, resp_payload);
156                         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
157                                 _E("smartthings_resource_notify() failed, err=[%d]", error);
158                         }
159         }
160
161         if (smartthings_payload_destroy(resp_payload) != 0) {
162                 _E("smartthings_payload_destroy failed");
163         }
164
165         END;
166         return;
167 }
168
169 static void _resource_connection_status_cb(smartthings_resource_h handle, smartthings_resource_connection_status_e status, void *user_data)
170 {
171         START;
172
173         if (status == SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED) {
174                 if (smartthings_resource_set_request_cb(st_handle, _request_cb, NULL) != 0) {
175                         _E("smartthings_resource_set_request_cb() is failed");
176                         return;
177                 }
178         } else {
179                 _I("connection failed, status=[%d]", status);
180         }
181
182         END;
183         return;
184 }
185
186 int init_resource_app()
187 {
188         START;
189
190         if (is_resource_init) {
191                 _I("Already initialized!");
192                 return 0;
193         }
194
195         if (smartthings_resource_initialize(&st_handle, _resource_connection_status_cb, NULL) != 0) {
196                 _E("smartthings_resource_initialize() is failed");
197                 goto _out;
198         }
199
200         is_resource_init = true;
201
202         END;
203         return 0;
204
205 _out :
206         END;
207         return -1;
208 }
209
210 int deinit_resource_app()
211 {
212         START;
213
214         if (!st_handle)
215                 return 0;
216
217         smartthings_resource_unset_request_cb(st_handle);
218
219         if (smartthings_resource_deinitialize(st_handle) != 0)
220                 return -1;
221
222         is_init = false;
223
224         END;
225         return 0;
226 }
227
228 void _user_confirm_cb(smartthings_h handle, void *user_data)
229 {
230         START;
231
232         if (smartthings_send_user_confirm(handle, true) != 0)
233                 _E("smartthings_send_user_confirm() is failed");
234
235         END;
236         return;
237 }
238
239 void _reset_confirm_cb(smartthings_h handle, void *user_data)
240 {
241         START;
242
243         if (smartthings_send_reset_confirm(handle, true) != 0)
244                 _E("smartthings_send_reset_confirm() is failed");
245
246         END;
247         return;
248 }
249
250 static void _reset_result_cb(smartthings_h handle, bool result, void *user_data)
251 {
252         START;
253
254         _I("reset result = [%d]", result);
255
256         END;
257         return;
258 }
259
260 static void _thing_status_cb(smartthings_h handle, smartthings_status_e status, void *user_data)
261 {
262         START;
263
264         _D("Received status changed cb : status = [%d]", 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         handle_main_loop();
435
436         return true;
437 }
438
439 static void service_app_terminate(void *user_data)
440 {
441         MUTEX_LOCK;
442         thread_done = 1;
443         MUTEX_UNLOCK;
444
445         int status = pthread_mutex_destroy(&mutex);
446     _I("mutex destroy status = %d", status);
447 }
448
449 static void service_app_control(app_control_h app_control, void *user_data)
450 {
451         if (app_control == NULL) {
452                 _E("app_control is NULL");
453                 return;
454         }
455
456         init_master_app();
457         init_resource_app();
458 }
459
460 int main(int argc, char *argv[])
461 {
462         service_app_lifecycle_callback_s event_callback;
463
464         event_callback.create = service_app_create;
465         event_callback.terminate = service_app_terminate;
466         event_callback.app_control = service_app_control;
467
468         return service_app_main(argc, argv, &event_callback, NULL);
469 }