2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <service_app.h>
26 #include "smartthings.h"
27 #include "smartthings_resource.h"
28 #include "smartthings_payload.h"
30 // Duration for a timer
31 #define TIMER_SENSOR_INTERVAL (.250f)
32 Ecore_Timer *sensor_event_timer = NULL;
34 #define THING_RESOURCE_FILE_NAME "resource.json"
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;
41 smartthings_status_e st_things_status = -1;
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";
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);
52 extern int resource_read_illuminance_sensor(uint16_t *out_value);
53 extern int resource_close_illuminance_sensor(void);
55 static Eina_Bool _get_sensor_data(void *user_data)
60 int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
61 smartthings_payload_h resp_payload = NULL;
63 if (st_things_status != SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD)
64 return ECORE_CALLBACK_RENEW;
67 _E("st_handle is NULL");
68 return ECORE_CALLBACK_RENEW;
71 ret = resource_read_illuminance_sensor(&value);
73 _E("cannot read data from the sensor");
74 return ECORE_CALLBACK_CANCEL;
77 _D("Detected sensor value is: %u", value);
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;
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);
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);
93 if (smartthings_payload_destroy(resp_payload))
94 _E("smartthings_payload_destroy() failed");
96 return ECORE_CALLBACK_RENEW;
99 void _send_response_result_cb(smartthings_resource_error_e result, void *user_data)
101 _D("app_control reply callback for send_response : result=[%d]", result);
104 void _notify_result_cb(smartthings_resource_error_e result, void *user_data)
106 _D("app_control reply callback for notify : result=[%d]", result);
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)
114 smartthings_payload_h resp_payload = NULL;
116 smartthings_payload_create(&resp_payload);
118 _E("Response payload is NULL");
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);
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);
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);
136 _E("Invalid request type");
137 smartthings_payload_destroy(resp_payload);
142 int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
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);
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);
159 if (smartthings_payload_destroy(resp_payload) != 0) {
160 _E("smartthings_payload_destroy failed");
167 static void _resource_connection_status_cb(smartthings_resource_h handle, smartthings_resource_connection_status_e status, void *user_data)
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");
177 _I("connection failed, status=[%d]", status);
184 int init_resource_app()
188 if (is_resource_init) {
189 _I("Already initialized!");
193 if (smartthings_resource_initialize(&st_handle, _resource_connection_status_cb, NULL) != 0) {
194 _E("smartthings_resource_initialize() is failed");
198 is_resource_init = true;
208 int deinit_resource_app()
215 smartthings_resource_unset_request_cb(st_handle);
217 if (smartthings_resource_deinitialize(st_handle) != 0)
220 is_resource_init = false;
227 void _user_confirm_cb(smartthings_h handle, void *user_data)
231 if (smartthings_send_user_confirm(handle, true) != 0)
232 _E("smartthings_send_user_confirm() is failed");
238 void _reset_confirm_cb(smartthings_h handle, void *user_data)
242 if (smartthings_send_reset_confirm(handle, true) != 0)
243 _E("smartthings_send_reset_confirm() is failed");
249 static void _reset_result_cb(smartthings_h handle, bool result, void *user_data)
253 _I("reset result = [%d]", result);
259 static void _thing_status_cb(smartthings_h handle, smartthings_status_e status, void *user_data)
263 _D("Received status changed cb : status = [%d]", status);
264 st_things_status = status;
267 case SMARTTHINGS_STATUS_NOT_READY:
268 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_NOT_READY");
270 case SMARTTHINGS_STATUS_INIT:
271 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_INIT");
273 case SMARTTHINGS_STATUS_ES_STARTED:
274 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_STARTED");
276 case SMARTTHINGS_STATUS_ES_DONE:
277 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_DONE");
279 case SMARTTHINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER:
280 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_ES_FAILED_ON_OWNERSHIP_TRANSFER");
282 case SMARTTHINGS_STATUS_CONNECTING_TO_AP:
283 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTING_TO_AP");
285 case SMARTTHINGS_STATUS_CONNECTED_TO_AP:
286 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTED_TO_AP");
288 case SMARTTHINGS_STATUS_CONNECTING_TO_AP_FAILED:
289 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_CONNECTING_TO_AP_FAILED");
291 case SMARTTHINGS_STATUS_REGISTERING_TO_CLOUD:
292 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_TO_CLOUD");
294 case SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD:
295 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD");
297 case SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN:
298 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_SIGN_IN");
300 case SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES:
301 _I("status: [%d] [%s]", status, "SMARTTHINGS_STATUS_REGISTERING_FAILED_ON_PUB_RES");
304 _E("status: [%d][%s]", status, "Unknown Status");
311 static void _things_connection_status_cb(smartthings_h handle, smartthings_connection_status_e status, void *user_data)
315 _D("Received connection status changed cb : status = [%d]", status);
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;
322 if (smartthings_set_device_property(handle, dev_name, wifi_mode, wifi_freq) != 0) {
323 _E("smartthings_initialize() is failed");
327 if (smartthings_set_certificate_file(handle, "certificate.pem", "privatekey.der") != 0) {
328 _E("smartthings_set_certificate_file() is failed");
332 if (smartthings_set_user_confirm_cb(st_h, _user_confirm_cb, NULL) != 0) {
333 _E("smartthings_set_user_confirm_cb() is failed");
337 if (smartthings_set_reset_confirm_cb(handle, _reset_confirm_cb, NULL) != 0) {
338 _E("smartthings_set_reset_confirm_cb() is failed");
342 if (smartthings_set_reset_result_cb(handle, _reset_result_cb, NULL) != 0) {
343 _E("smartthings_set_reset_confirm_cb() is failed");
347 if (smartthings_set_status_changed_cb(handle, _thing_status_cb, NULL) != 0) {
348 _E("smartthings_set_status_changed_callback() is failed");
352 if (smartthings_start(handle) != 0) {
353 _E("smartthings_start() is failed");
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");
363 if (is_es_completed == true) {
364 _I("Easysetup is already done");
368 if (smartthings_start_easysetup(handle) != 0) {
369 _E("smartthings_start_easysetup() is failed");
373 _E("connection failed, status=[%d]", status);
380 int init_master_app()
385 _I("Already initialized!");
390 if (smartthings_initialize(&st_h, _things_connection_status_cb, NULL) != 0) {
391 _E("smartthings_initialize() is failed");
405 int deinit_master_app()
412 _I("handle is already NULL");
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);
422 if (smartthings_deinitialize(st_h) != 0) {
423 _E("smartthings_deinitialize() is failed");
432 static bool service_app_create(void *user_data)
434 if (sensor_event_timer)
435 ecore_timer_del(sensor_event_timer);
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");
444 static void service_app_terminate(void *user_data)
446 // clear timer resource
447 if (sensor_event_timer) {
448 ecore_timer_del(sensor_event_timer);
449 sensor_event_timer = NULL;
452 // close sensor resource
453 resource_close_illuminance_sensor();
455 /*terminate resource*/
456 if (deinit_resource_app() != 0) {
457 _E("deinit_resource_app failed");
461 if (deinit_master_app() != 0) {
462 _E("deinit_master_app failed");
468 static void service_app_control(app_control_h app_control, void *user_data)
470 if (app_control == NULL) {
471 _E("app_control is NULL");
481 int main(int argc, char *argv[])
483 service_app_lifecycle_callback_s event_callback;
485 event_callback.create = service_app_create;
486 event_callback.terminate = service_app_terminate;
487 event_callback.app_control = service_app_control;
489 return service_app_main(argc, argv, &event_callback, NULL);