/* * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "smartthings.h" #include "smartthings_resource.h" #include "smartthings_payload.h" #include "sensor-data.h" #include "log.h" // URI and key information #define SENSOR_LIDAR_URI "/capability/illuminanceMeasurement/main/0" #define SENSOR_LIDAR_KEY "illuminance" static smartthings_resource_h st_res_h; static smartthings_resource_connection_status_e st_res_status; static int st_cloud_reg_status; static sensor_data *resource_sd; static const char * _resource_error_to_str(smartthings_resource_error_e err) { const char *err_str = NULL; switch (err) { case SMARTTHINGS_RESOURCE_ERROR_NONE: err_str = "SMARTTHINGS_RESOURCE_ERROR_NONE"; break; case SMARTTHINGS_RESOURCE_ERROR_INVALID_PARAMETER: err_str = "SMARTTHINGS_RESOURCE_ERROR_INVALID_PARAMETER"; break; case SMARTTHINGS_RESOURCE_ERROR_OUT_OF_MEMORY: err_str = "SMARTTHINGS_RESOURCE_ERROR_OUT_OF_MEMORY"; break; case SMARTTHINGS_RESOURCE_ERROR_PERMISSION_DENIED: err_str = "SMARTTHINGS_RESOURCE_ERROR_PERMISSION_DENIED"; break; case SMARTTHINGS_RESOURCE_ERROR_NO_DATA: err_str = "SMARTTHINGS_RESOURCE_ERROR_NO_DATA"; break; case SMARTTHINGS_RESOURCE_ERROR_NOT_SUPPORTED: err_str = "SMARTTHINGS_RESOURCE_ERROR_NOT_SUPPORTED"; break; case SMARTTHINGS_RESOURCE_ERROR_OPERATION_FAILED: err_str = "SMARTTHINGS_RESOURCE_ERROR_NOT_SUPPORTED"; break; case SMARTTHINGS_RESOURCE_ERROR_SERVICE_UNAVAILABLE: err_str = "SMARTTHINGS_RESOURCE_ERROR_SERVICE_UNAVAILABLE"; break; default: err_str = "Unknown error"; break; } return err_str; } static bool _handle_get_lidar(smartthings_payload_h resp_payload, void *user_data) { int err = SMARTTHINGS_RESOURCE_ERROR_NONE; unsigned int value = 0; _D("Received a GET request for LIDAR"); if (sensor_data_get_uint(resource_sd, &value)) return false; err = smartthings_payload_set_double(resp_payload, SENSOR_LIDAR_KEY, value); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) _E("smartthings_payload_set_double() failed, [%s]", _resource_error_to_str(err)); return true; } static void __request_cb(smartthings_resource_h handle, int id, const char *uri, smartthings_resource_req_type_e req_type, smartthings_payload_h payload, void *user_data) { smartthings_payload_h resp_payload = NULL; bool result = false; int err = SMARTTHINGS_RESOURCE_ERROR_NONE; _D("request on %s, type[%d], id[%d]", uri, req_type, id); err = smartthings_payload_create(&resp_payload); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE || ! resp_payload) _E("smartthings_payload_create() failed, [%s]", _resource_error_to_str(err)); if (req_type == SMARTTHINGS_RESOURCE_REQUEST_GET) { if (!strncmp(uri, SENSOR_LIDAR_URI, strlen(SENSOR_LIDAR_URI))) result = _handle_get_lidar(resp_payload, user_data); else _E("No matching Resource uri to get"); } else if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) { _E("No matching Resource uri to set"); } else { _E("Invalid request type - %d", req_type); smartthings_payload_destroy(resp_payload); return; } err = smartthings_resource_send_response(handle, id, uri, resp_payload, result); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) { _E("smartthings_resource_send_response() failed, [%s]", _resource_error_to_str(err)); smartthings_payload_destroy(resp_payload); return; } if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) { err = smartthings_resource_notify(handle, uri, resp_payload); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) _E("smartthings_resource_notify() failed, [%s]", _resource_error_to_str(err)); } if (smartthings_payload_destroy(resp_payload)) _E("smartthings_payload_destroy() failed"); } void _cloud_reg_status_cb(smartthings_resource_h handle, bool is_registered, void *user_data) { _D("registered [%d]", is_registered); st_cloud_reg_status = is_registered; } static void _resource_connection_status_cb( smartthings_resource_h handle, smartthings_resource_connection_status_e status, void *user_data) { int err = SMARTTHINGS_RESOURCE_ERROR_NONE; st_res_status = status; _D("status=[%d]", status); if (status != SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED) { _E("connection failed"); return; } err = smartthings_resource_set_request_cb(handle, __request_cb, NULL); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) { _E("smartthings_resource_set_request_cb() is failed, [%s]", _resource_error_to_str(err)); return; } err = smartthings_resource_set_cloud_registration_status_cb(handle, _cloud_reg_status_cb, NULL); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) { _E("smartthings_resource_set_cloud_registration_status_cb() is failed, [%s]", _resource_error_to_str(err)); return; } } static void __data_changed_cb(sensor_data *sd, sensor_data_type_e type, void *user_data) { unsigned int value = 0; int err = SMARTTHINGS_RESOURCE_ERROR_NONE; smartthings_payload_h resp_payload = NULL; if (st_res_status != SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED || !st_cloud_reg_status) { _D("resource not connected yet"); return; } sensor_data_get_uint(sd, &value); err = smartthings_payload_create(&resp_payload); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE || !resp_payload) { _E("smartthings_payload_create() failed, [%s]", _resource_error_to_str(err)); return; } err = smartthings_payload_set_double(resp_payload, SENSOR_LIDAR_KEY, value); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) { _E("smartthings_payload_set_bool() failed, [%s]", _resource_error_to_str(err)); smartthings_payload_destroy(resp_payload); return; } err = smartthings_resource_notify(st_res_h, SENSOR_LIDAR_URI, resp_payload); if (err != SMARTTHINGS_RESOURCE_ERROR_NONE) _E("smartthings_resource_notify() failed, [%s]", _resource_error_to_str(err)); smartthings_payload_destroy(resp_payload); } int st_resource_destroy(void) { if (!st_res_h) return 0; smartthings_resource_unset_request_cb(st_res_h); smartthings_resource_unset_cloud_registration_status_cb(st_res_h); smartthings_resource_deinitialize(st_res_h); sensor_data_changed_cb_set(resource_sd, NULL, NULL); st_res_h = NULL; st_res_status = SMARTTHINGS_RESOURCE_CONNECTION_STATUS_DISCONNECTED; st_cloud_reg_status = 0; return 0; } int st_resource_create(sensor_data *sd) { smartthings_resource_h res_h = NULL; int err = 0; retv_if(!sd, -1); if (st_res_h) { _I("Already initialized!"); return 0; } err = smartthings_resource_initialize(&res_h, _resource_connection_status_cb, NULL); if (err) { _E("smartthings_resource_initialize() is failed, [%s]", _resource_error_to_str(err)); return -1; } st_res_h = res_h; st_res_status = SMARTTHINGS_RESOURCE_CONNECTION_STATUS_DISCONNECTED; st_cloud_reg_status = 0; resource_sd = sd; sensor_data_changed_cb_set(sd, __data_changed_cb, st_res_h); return 0; }