diff options
Diffstat (limited to 'src/controller.c')
-rw-r--r-- | src/controller.c | 424 |
1 files changed, 172 insertions, 252 deletions
diff --git a/src/controller.c b/src/controller.c index 90a54d0..8c3e48d 100644 --- a/src/controller.c +++ b/src/controller.c @@ -19,57 +19,54 @@ #include <string.h> #include <stdlib.h> #include <stdint.h> -#include <glib.h> +#include <Ecore.h> #include "log.h" #include "resource/resource_infrared_motion_sensor.h" #include "resource/resource_led.h" -#include "sensor-data.h" -#define LED_ON "on" -#define LED_OFF "off" -#define SENSOR_LED_INIT "off" -#define SENSOR_MOTION_CH (46) -#define SENSOR_LED_CH (130) -#define SENSOR_GATHER_INTERVAL (50) //50ms +// Duration for a timer +#define TIMER_GATHER_INTERVAL (5.0f) -#define USE_ST_SDK +// Motion sensor info +#define SENSOR_MOTION_GPIO_NUMBER (46) -#ifdef USE_ST_SDK +// LED info +#define SENSOR_LED_GPIO_NUMBER (130) +#define SENSOR_LED_ON "on" +#define SENSOR_LED_OFF "off" +#define USE_ST_SDK +#ifdef USE_ST_SDK #include "smartthings.h" #include "smartthings_resource.h" #include "smartthings_payload.h" -/* You have to FIX IT !!! */ -#define CERT_FILE "certificate.pem" // cert file name in 'res' directory -#define PRIV_FILE "privatekey.der" // private key file name in 'res' directory +// Cert file name in 'res' directory +#define CERT_FILE "certificate.pem" +// Private key file name in 'res' directory +#define PRIV_FILE "privatekey.der" #define SENSOR_MOTION_URI "/capability/motionSensor/main/0" #define SENSOR_MOTION_KEY "value" #define SENSOR_LED_URI "/capability/switch/main/0" #define SENSOR_LED_KEY "power" - #endif /* USE_ST_SDK */ typedef struct app_data_s { - guint getter_motion; - sensor_data *motion_data; - sensor_data *led_data; + Ecore_Timer *getter_timer; + uint32_t motion_data; + int led_data; #ifdef USE_ST_SDK smartthings_h st_master_h; smartthings_resource_h st_res_h; - smartthings_resource_connection_status_e st_res_conn_status; + smartthings_status_e status; #endif /* USE_ST_SDK */ } app_data; - static app_data *g_ad = NULL; #ifdef USE_ST_SDK - -/* smartthings resource functions */ -static const char * -__resource_error_to_str(smartthings_resource_error_e error) +static const char * _resource_error_to_str(smartthings_resource_error_e error) { const char *err_str = NULL; @@ -105,72 +102,122 @@ __resource_error_to_str(smartthings_resource_error_e error) return err_str; } +#endif -static int __change_led_data(void *data, char *state) { +static Eina_Bool _get_motion_sensor_data(void *user_data) +{ int ret = 0; - app_data *ad = data; + uint32_t value = 0; + app_data *ad = user_data; - retv_if(!ad, -1); - retv_if(!ad->led_data, -1); + if (!ad) { + _E("failed to get app_data"); + return ECORE_CALLBACK_CANCEL; + } - sensor_data_set_string(ad->led_data, state, strlen(state)); + ret = resource_read_infrared_motion_sensor(SENSOR_MOTION_GPIO_NUMBER, &value); + if (ret != 0) { + _E("cannot read data from the infrared motion sensor"); + return ECORE_CALLBACK_CANCEL; + } + ad->motion_data = value; - if (0 == strcmp(state, LED_ON)) { - ret = resource_write_led(SENSOR_LED_CH, 1); - } else { - ret = resource_write_led(SENSOR_LED_CH, 0); + _D("Detected motion value is: %u", value); + +#ifdef USE_ST_SDK + int error = SMARTTHINGS_RESOURCE_ERROR_NONE; + smartthings_payload_h resp_payload = NULL; + + if (ad->status != SMARTTHINGS_STATUS_REGISTERED_TO_CLOUD) + return ECORE_CALLBACK_RENEW; + + error = smartthings_payload_create(&resp_payload); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE || !resp_payload) { + _E("smartthings_payload_create() failed, [%s]", + _resource_error_to_str(error)); + return ECORE_CALLBACK_CANCEL; } - retv_if(ret != 0, -1); + error = smartthings_payload_set_bool(resp_payload, SENSOR_MOTION_KEY, (bool)ad->motion_data); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) + _E("smartthings_payload_set_bool() failed, [%s]", + _resource_error_to_str(error)); + + error = smartthings_resource_notify(ad->st_res_h, SENSOR_MOTION_URI, resp_payload); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) + _E("smartthings_resource_notify() failed, [%s]", + _resource_error_to_str(error)); + + if (smartthings_payload_destroy(resp_payload)) + _E("smartthings_payload_destroy() failed"); +#endif + + return ECORE_CALLBACK_RENEW; +} + +static int _set_led_data(app_data *ad, int state) { + int ret = 0; + + ad->led_data = state; + ret = resource_write_led(SENSOR_LED_GPIO_NUMBER, state); + if (ret != 0) { + _E("cannot write led data"); + return -1; + } + _I("LED : %d",state); return 0; } -static bool -handle_get_motion(smartthings_payload_h resp_payload, void *user_data) +#ifdef USE_ST_SDK +/* SmartThings resource functions */ +static bool _handle_get_motion(smartthings_payload_h resp_payload, void *user_data) { + int error = SMARTTHINGS_RESOURCE_ERROR_NONE; app_data *ad = user_data; - bool value = false; retv_if(!ad, false); _D("Received a GET request for MOTION"); - sensor_data_get_bool(ad->motion_data, &value); - smartthings_payload_set_bool(resp_payload, SENSOR_MOTION_KEY, ad->motion_data); - - _D("Value : %d", value); + error = smartthings_payload_set_bool(resp_payload, SENSOR_MOTION_KEY, (bool)ad->motion_data); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) + _E("smartthings_payload_set_bool() failed, [%s]", + _resource_error_to_str(error)); return true; } -static bool -handle_get_led(smartthings_payload_h resp_payload, void *user_data) +static bool _handle_get_led(smartthings_payload_h resp_payload, void *user_data) { app_data *ad = user_data; - const char *str = NULL; int error = SMARTTHINGS_RESOURCE_ERROR_NONE; + char *str = NULL; retv_if(!ad, false); _D("Received a GET request for LED"); - error = smartthings_payload_set_string(resp_payload, SENSOR_LED_KEY, ad->led_data); - if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) - _E("smartthings_resource_notify() failed, [%s]", - __resource_error_to_str(error)); + if (ad->led_data) + str = SENSOR_LED_ON; + else + str = SENSOR_LED_OFF; + error = smartthings_payload_set_string(resp_payload, SENSOR_LED_KEY, str); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) + _E("smartthings_payload_set_string() failed, [%s]", + _resource_error_to_str(error)); _D("Power : %s", str); return true; } -static bool -handle_set_led(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data) +static bool _handle_set_led(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data) { app_data *ad = user_data; char *str = NULL; + char *res_str = NULL; int ret = 0; int error = SMARTTHINGS_RESOURCE_ERROR_NONE; @@ -178,27 +225,34 @@ handle_set_led(smartthings_payload_h payload, smartthings_payload_h resp_payload _D("Received a SET request"); - smartthings_payload_get_string(payload, SENSOR_LED_KEY, &str); + error = smartthings_payload_get_string(payload, SENSOR_LED_KEY, &str); if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) - _E("smartthings_resource_notify() failed, [%s]", - __resource_error_to_str(error)); + _E("smartthings_payload_get_string() failed, [%s]", + _resource_error_to_str(error)); - ret = __change_led_data(ad, strdup(str)); - - retv_if(ret != 0, false); + if (strncmp(str, SENSOR_LED_ON, strlen(SENSOR_LED_ON))) { + ret = _set_led_data(ad, 0); + res_str = SENSOR_LED_OFF; + } else { + ret = _set_led_data(ad, 1); + res_str = SENSOR_LED_ON; + } free(str); + if (ret != 0) { + _E("cannot set LED"); + return false; + } - error = smartthings_payload_set_string(resp_payload, SENSOR_LED_KEY, ad->led_data); + error = smartthings_payload_set_string(resp_payload, SENSOR_LED_KEY, res_str); if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) - _E("smartthings_resource_notify() failed, [%s]", - __resource_error_to_str(error)); + _E("smartthings_payload_set_string() failed, [%s]", + _resource_error_to_str(error)); return true; } -static void -_request_cb(smartthings_resource_h handle, int req_id, +static void _request_cb(smartthings_resource_h handle, int req_id, const char *uri, smartthings_resource_req_type_e req_type, smartthings_payload_h payload, void *user_data) { @@ -208,22 +262,21 @@ _request_cb(smartthings_resource_h handle, int req_id, _D("request on %s, type[%d], id[%d]", uri, req_type, req_id); - smartthings_payload_create(&resp_payload); - if (!resp_payload) { - _E("Response payload is NULL"); - return; - } + error = smartthings_payload_create(&resp_payload); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE || ! resp_payload) + _E("smartthings_payload_create() failed, [%s]", + _resource_error_to_str(error)); if (req_type == SMARTTHINGS_RESOURCE_REQUEST_GET) { - if (0 == g_strcmp0(uri, SENSOR_MOTION_URI)) - result = handle_get_motion(resp_payload, user_data); - else if (0 == g_strcmp0(uri, SENSOR_LED_URI)) - result = handle_get_led(resp_payload, user_data); + if (!strncmp(uri, SENSOR_MOTION_URI, strlen(SENSOR_MOTION_URI))) + result = _handle_get_motion(resp_payload, user_data); + else if (!strncmp(uri, SENSOR_LED_URI, strlen(SENSOR_LED_URI))) + result = _handle_get_led(resp_payload, user_data); else _E("No matching Resource uri to get"); } else if (req_type == SMARTTHINGS_RESOURCE_REQUEST_SET) { - if (0 == g_strcmp0(uri, SENSOR_LED_URI)) - result = handle_set_led(payload, resp_payload, user_data); + if (!strncmp(uri, SENSOR_LED_URI, strlen(SENSOR_LED_URI))) + result = _handle_set_led(payload, resp_payload, user_data); else _E("No matching Resource uri to get"); } else { @@ -234,9 +287,9 @@ _request_cb(smartthings_resource_h handle, int req_id, error = smartthings_resource_send_response(handle, req_id, uri, resp_payload, result); if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) { - smartthings_payload_destroy(resp_payload); _E("smartthings_resource_send_response() failed, [%s]", - __resource_error_to_str(error)); + _resource_error_to_str(error)); + smartthings_payload_destroy(resp_payload); return; } @@ -244,118 +297,38 @@ _request_cb(smartthings_resource_h handle, int req_id, error = smartthings_resource_notify(handle, uri, resp_payload); if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) _E("smartthings_resource_notify() failed, [%s]", - __resource_error_to_str(error)); + _resource_error_to_str(error)); } if (smartthings_payload_destroy(resp_payload)) - _E("smartthings_payload_destroy failed"); + _E("smartthings_payload_destroy() failed"); return; } -static void -_resource_connection_status_cb(smartthings_resource_error_e error, +static void _resource_connection_status_cb( smartthings_resource_h handle, smartthings_resource_connection_status_e status, void *user_data) { app_data *ad = user_data; - _D("result [%s], status=[%d]", __resource_error_to_str(error), status); + _D("status=[%d]", status); ret_if(!ad); - ad->st_res_conn_status = status; - if (status == SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED) { - if (smartthings_resource_set_request_cb(handle, _request_cb, ad)) { + int error = SMARTTHINGS_RESOURCE_ERROR_NONE; + error = smartthings_resource_set_request_cb(handle, _request_cb, ad); + if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) { _E("smartthings_resource_set_request_cb() is failed"); return; } } else { _E("connection failed"); } - return; -} - -static int -st_thing_notify_resource(app_data *ad, const char *uri, const char *key, sensor_data *data) -{ - smartthings_resource_h handle = NULL; - smartthings_payload_h payload = NULL; - int error = SMARTTHINGS_RESOURCE_ERROR_NONE; - sensor_data_type_e data_type = SENSOR_DATA_TYPE_NONE; - - retv_if(!ad, -1); - retv_if(!ad->st_res_h, -1); - retv_if(ad->st_res_conn_status != SMARTTHINGS_RESOURCE_CONNECTION_STATUS_CONNECTED, -1); - retv_if(!uri, -1); - retv_if(!key, -1); - retv_if(!data, -1); - - handle = ad->st_res_h; - - data_type = sensor_data_get_type(data); - retv_if(data_type == SENSOR_DATA_TYPE_NONE, -1); - - smartthings_payload_create(&payload); - if (!payload) { - _E("failed to create payload is NULL"); - return -1; - } - - switch (data_type) { - case SENSOR_DATA_TYPE_INT: - { - int value = 0; - sensor_data_get_int(data, &value); - smartthings_payload_set_int(payload, key, value); - } - break; - case SENSOR_DATA_TYPE_UINT: - { - unsigned int value = 0; - sensor_data_get_uint(data, &value); - smartthings_payload_set_int(payload, key, (int)value); - } - break; - case SENSOR_DATA_TYPE_BOOL: - { - bool value = 0; - sensor_data_get_bool(data, &value); - smartthings_payload_set_bool(payload, key, value); - } - break; - case SENSOR_DATA_TYPE_DOUBLE: - { - double value = 0; - sensor_data_get_double(data, &value); - smartthings_payload_set_double(payload, key, value); - } - break; - case SENSOR_DATA_TYPE_STR: - { - const char *value = NULL; - sensor_data_get_string(data, &value); - smartthings_payload_set_string(payload, key, value); - } - break; - case SENSOR_DATA_TYPE_NONE: - default: - _E("unsupport data type"); - break; - } - - error = smartthings_resource_notify(handle, uri, payload); - if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) - _E("smartthings_resource_notify() failed, [%s]", - __resource_error_to_str(error)); - - smartthings_payload_destroy(payload); - - return 0; } -static int st_thing_resource_init(app_data *ad) +static int _init_resource(app_data *ad) { smartthings_resource_h st_res_h = NULL; int error = 0; @@ -370,17 +343,16 @@ static int st_thing_resource_init(app_data *ad) _resource_connection_status_cb, ad); if (error) { _E("smartthings_resource_initialize() is failed, [%s]", - __resource_error_to_str(error)); + _resource_error_to_str(error)); return -1; } ad->st_res_h = st_res_h; - ad->st_res_conn_status = SMARTTHINGS_RESOURCE_CONNECTION_STATUS_DISCONNECTED; return 0; } -static int st_thing_resource_fini(app_data *ad) +static int _fini_resource(app_data *ad) { retv_if(!ad, -1); @@ -391,12 +363,11 @@ static int st_thing_resource_fini(app_data *ad) smartthings_resource_deinitialize(ad->st_res_h); ad->st_res_h = NULL; - ad->st_res_conn_status = SMARTTHINGS_RESOURCE_CONNECTION_STATUS_DISCONNECTED; return 0; } -/* smartthings master functions */ +/* SmartThings master functions */ static const char *__master_error_to_str(smartthings_error_e error) { const char *err_str = NULL; @@ -451,19 +422,20 @@ static void _reset_result_cb(smartthings_h handle, bool result, void *user_data) _I("reset result = [%d]", result); } -static void -_thing_status_cb( +static void _thing_status_cb( smartthings_h handle, smartthings_status_e status, void *user_data) { + app_data *ad = user_data; _D("status: [%d]", status); + ad->status = status; } -static void -_things_connection_status_cb(smartthings_error_e error, - smartthings_h handle, smartthings_connection_status_e status, - void *user_data) +//static void _things_connection_status_cb(smartthings_error_e error, +static void _things_connection_status_cb( + smartthings_h handle, smartthings_connection_status_e status, + void *user_data) { - _D("result [%s], status = [%d]", __master_error_to_str(error), status); + _D("status = [%d]", status); if (status == SMARTTHINGS_CONNECTION_STATUS_CONNECTED) { int err = 0; @@ -478,7 +450,7 @@ _things_connection_status_cb(smartthings_error_e error, err = smartthings_set_device_property( handle, dev_name, wifi_mode, wifi_freq); if (err) { - _E("smartthings_initialize() is failed, [%s]", + _E("smartthings_set_device_property() is failed, [%s]", __master_error_to_str(err)); return; } @@ -506,12 +478,12 @@ _things_connection_status_cb(smartthings_error_e error, err = smartthings_set_reset_result_cb(handle, _reset_result_cb, NULL); if (err) { - _E("smartthings_set_reset_confirm_cb() is failed, [%s]", + _E("smartthings_set_reset_result_cb() is failed, [%s]", __master_error_to_str(err)); return; } - err = smartthings_set_status_changed_cb(handle, _thing_status_cb, NULL); + err = smartthings_set_status_changed_cb(handle, _thing_status_cb, user_data); if (err) { _E("smartthings_set_status_changed_callback() is failed, [%s]", __master_error_to_str(err)); @@ -537,6 +509,7 @@ _things_connection_status_cb(smartthings_error_e error, return; } + _I("Easysetup is starting now"); err = smartthings_start_easysetup(handle); if (err) { _E("smartthings_start_easysetup() is failed, [%s]", @@ -547,10 +520,9 @@ _things_connection_status_cb(smartthings_error_e error, } else { _E("connection failed"); } - return; } -static int st_thing_master_init(app_data *ad) +static int _init_master(app_data *ad) { int err = 0; smartthings_h st_handle = NULL; @@ -562,7 +534,7 @@ static int st_thing_master_init(app_data *ad) return 0; } - err = smartthings_initialize(&st_handle, _things_connection_status_cb, NULL); + err = smartthings_initialize(&st_handle, _things_connection_status_cb, ad); if (err) { _E("smartthings_initialize() is failed, [%s]", __master_error_to_str(err)); @@ -574,7 +546,7 @@ static int st_thing_master_init(app_data *ad) return 0; } -int st_thing_master_fini(app_data *ad) +int _fini_master(app_data *ad) { retv_if(!ad, -1); @@ -599,90 +571,42 @@ int st_thing_master_fini(app_data *ad) return 0; } - #endif /* USE_ST_SDK */ -static gboolean __change_motion_sensor_data(gpointer user_data) -{ - int ret = 0; - uint32_t value = 0; - - app_data *ad = user_data; - - if (!ad) { - _E("failed to get app_data"); - service_app_exit(); - return FALSE; - } - - if (!ad->motion_data) { - _E("failed to get motion_data"); - service_app_exit(); - ad->getter_motion = 0; - return FALSE; - } - - ret = resource_read_infrared_motion_sensor(SENSOR_MOTION_CH, &value); - retv_if(ret != 0, TRUE); - - sensor_data_set_bool(ad->motion_data, value); - - _D("Detected motion value is: %d", value); - -#ifdef USE_ST_SDK - // Notify observers of the Motion sensor resource - st_thing_notify_resource(ad, SENSOR_MOTION_URI, SENSOR_MOTION_KEY, ad->motion_data); -#endif - return FALSE; -// return TRUE; -} - -static void gathering_stop(void *data) +static void _stop_gathering(void *data) { app_data *ad = data; ret_if(!ad); - if (ad->getter_motion) { - g_source_remove(ad->getter_motion); - ad->getter_motion = 0; + if (ad->getter_timer) { + ecore_timer_del(ad->getter_timer); + ad->getter_timer = NULL; } } -static void gathering_start(void *data) +static void _start_gathering(void *data) { app_data *ad = data; ret_if(!ad); - ad->getter_motion = g_timeout_add(SENSOR_GATHER_INTERVAL, __change_motion_sensor_data, ad); + if (ad->getter_timer) + ecore_timer_del(ad->getter_timer); - if (!ad->getter_motion) - _E("Failed to add getter_motion"); + ad->getter_timer = ecore_timer_add(TIMER_GATHER_INTERVAL, _get_motion_sensor_data, ad); + if (!ad->getter_timer) + _E("Failed to add a timer"); } static bool service_app_create(void *user_data) { +#ifdef USE_ST_SDK app_data *ad = user_data; - // Declare new sensor data for Motion data - ad->motion_data = sensor_data_new(SENSOR_DATA_TYPE_BOOL); - - if (!ad->motion_data) + if (_init_master(ad)) return false; - // Declare new sensor data for LED data - ad->led_data = sensor_data_new(SENSOR_DATA_TYPE_STR); - - if (!ad->led_data) - return false; - - sensor_data_set_string(ad->led_data, SENSOR_LED_INIT, strlen(SENSOR_LED_INIT)); - -#ifdef USE_ST_SDK - if (st_thing_master_init(ad)) - return false; - - if (st_thing_resource_init(ad)) { - st_thing_master_fini(ad); + if (_init_resource(ad)) { + _fini_master(ad); return false; } #endif @@ -692,25 +616,21 @@ static bool service_app_create(void *user_data) static void service_app_control(app_control_h app_control, void *user_data) { - gathering_stop(user_data); - gathering_start(user_data); + _stop_gathering(user_data); + _start_gathering(user_data); } static void service_app_terminate(void *user_data) { - app_data *ad = (app_data *)user_data; + app_data *ad = user_data; #ifdef USE_ST_SDK - st_thing_resource_fini(ad); - st_thing_master_fini(ad); + _fini_resource(ad); + _fini_master(ad); #endif // Turn off LED light with __set_led() - __change_led_data(ad, LED_OFF); - - // Free sensor Motion & LED data - sensor_data_free(ad->motion_data); - sensor_data_free(ad->led_data); + _set_led_data(ad, 0); // Close Motion and LED resources resource_close_infrared_motion_sensor(); |