From 1e88e5abf48bb32c6c7cd83be55e58e3f4477952 Mon Sep 17 00:00:00 2001 From: Jeonghoon Park Date: Fri, 3 Nov 2017 11:17:26 +0900 Subject: [PATCH] update connectivity module to support http type Change-Id: Ie2ee5e1a9413a5ba2ae951cc39db2342690698ca --- inc/connectivity.h | 23 +- inc/connectivity_internal.h | 2 - src/connectivity.c | 1059 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 857 insertions(+), 227 deletions(-) diff --git a/inc/connectivity.h b/inc/connectivity.h index 5165dda..ed4795a 100644 --- a/inc/connectivity.h +++ b/inc/connectivity.h @@ -24,13 +24,14 @@ #include "connectivity_internal.h" -struct connectivity_resource { - iotcon_resource_h res; - iotcon_observers_h observers; - char *path; -}; +typedef struct _connectivity_resource connectivity_resource_s; -typedef struct connectivity_resource connectivity_resource_s; +typedef enum { + CONNECTIVITY_TYPE_DEFAULT = 0, + CONNECTIVITY_TYPE_IOTIVITY, + CONNECTIVITY_TYPE_HTTP, + CONNECTIVITY_TYPE_MAX +} connectivity_type_e; /** * @brief Create connectivity resource and registers the resource in server. @@ -87,6 +88,14 @@ extern int connectivity_notify_double(connectivity_resource_s *resource_info, co * @return 0 on success, otherwise a negative error value * @see If key is already exists, current value will be replaced with new value. */ -extern int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, char *value); +extern int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, const char *value); + +/* Here is six new functions, I don't like a name of these functions, please recommand me a good name */ +extern int connectivity_set_connectivity_type(connectivity_type_e connectivity_type); +extern int connectivity_notify_multi_add_bool(connectivity_resource_s *resource_info, const char *key, bool value); +extern int connectivity_notify_multi_add_int(connectivity_resource_s *resource_info, const char *key, int value); +extern int connectivity_notify_multi_add_double(connectivity_resource_s *resource_info, const char *key, double value); +extern int connectivity_notify_multi_add_string(connectivity_resource_s *resource_info, const char *key, const char *value); +extern int connectivity_notify_multi_perform(connectivity_resource_s *resource_info); #endif /* __POSITION_FINDER_CONNECTIVITY_H__ */ diff --git a/inc/connectivity_internal.h b/inc/connectivity_internal.h index d3da902..33ea0e4 100644 --- a/inc/connectivity_internal.h +++ b/inc/connectivity_internal.h @@ -22,8 +22,6 @@ #ifndef __POSITION_FINDER_CONNECTIVITY_INTERNAL_H__ #define __POSITION_FINDER_CONNECTIVITY_INTERNAL_H__ -#include - extern int connectivity_init(void); extern int connectivity_fini(void); diff --git a/src/connectivity.c b/src/connectivity.c index cc2c547..6aa774d 100644 --- a/src/connectivity.c +++ b/src/connectivity.c @@ -23,19 +23,193 @@ #include #include #include -#include #include +#include #include "log.h" #include "connectivity.h" +#include "webutil.h" +#include "controller_util.h" -#define ULTRASONIC_RESOURCE_TYPE "org.tizen.door" +#define DEFAULT_RESOURCE_TYPE "org.tizen.door" #define BUFSIZE 1024 #define URI_PATH_LEN 64 #define URI_PATH "/door/1" #define PATH "path" +#define IOTCON_DB_FILENAME "iotcon-test-svr-db-server.dat" + +struct _connectivity_resource { + char *path; + char *type; + connectivity_type_e conn_type; + GHashTable *value_hash; + union { + struct { + iotcon_resource_h res; + iotcon_observers_h observers; + } iotcon_data; + struct { + /* Nothing */ + char *reserve; + } http_data; + } conn_data; +}; + +typedef enum { + DATA_VAL_TYPE_BOOL = 0, + DATA_VAL_TYPE_INT, + DATA_VAL_TYPE_DOUBLE, + DATA_VAL_TYPE_STRING +} conn_data_val_type_e; + +typedef struct _conn_data_value_s { + conn_data_val_type_e type; + union { + bool b_val; + int i_val; + double d_val; + char *s_val; + }; +} conn_data_value_s; + +static connectivity_type_e ConnectivityType = CONNECTIVITY_TYPE_DEFAULT; +static int connectivity_iotcon_intialized = 0; +static int connectivity_http_intialized = 0; -static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data); +static void _print_iotcon_error(int err_no) +{ + switch (err_no) { + case IOTCON_ERROR_NOT_SUPPORTED: + _E("IOTCON_ERROR_NOT_SUPPORTED"); + break; + case IOTCON_ERROR_PERMISSION_DENIED: + _E("IOTCON_ERROR_PERMISSION_DENIED"); + break; + case IOTCON_ERROR_INVALID_PARAMETER: + _E("IOTCON_ERROR_INVALID_PARAMETER"); + break; + default: + _E("Error : [%d]", err_no); + break; + } + + return; +} + +static void _copy_file(const char *in_filename, const char *out_filename) +{ + char buf[BUFSIZE] = { 0, }; + size_t nread = 0; + FILE *in = NULL; + FILE *out = NULL; + + ret_if(!in_filename); + ret_if(!out_filename); + + in = fopen(in_filename, "r"); + ret_if(!in); + + out = fopen(out_filename, "w"); + goto_if(!out, error); + + rewind(in); + while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) { + if (fwrite(buf, 1, nread, out) < nread) { + _E("critical error to copy a file"); + break; + } + } + + fclose(in); + fclose(out); + + return; + +error: + fclose(out); + return; +} + +static bool _query_cb(const char *key, const char *value, void *user_data) +{ + _D("Key : [%s], Value : [%s]", key, value); + + return IOTCON_FUNC_CONTINUE; +} + +static int _handle_query(iotcon_request_h request) +{ + iotcon_query_h query = NULL; + int ret = -1; + + ret = iotcon_request_get_query(request, &query); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + if (query) iotcon_query_foreach(query, _query_cb, NULL); + + return 0; +} + +static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info) +{ + iotcon_request_type_e type; + int ret = -1; + + ret = iotcon_request_get_request_type(request, &type); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + switch (type) { + case IOTCON_REQUEST_GET: + _I("Do not support 'get' query"); + break; + case IOTCON_REQUEST_PUT: + _I("Do not support 'put' query"); + break; + case IOTCON_REQUEST_POST: + _I("Do not support 'post' query"); + break; + case IOTCON_REQUEST_DELETE: + _I("Do not support 'delete' query"); + break; + default: + _E("Cannot reach here"); + ret = -1; + break; + } + retv_if(0 != ret, -1); + + return 0; +} + +static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers) +{ + iotcon_observe_type_e observe_type; + int ret = -1; + int observe_id = -1; + + ret = iotcon_request_get_observe_type(request, &observe_type); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + if (IOTCON_OBSERVE_REGISTER == observe_type) { + ret = iotcon_request_get_observe_id(request, &observe_id); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + _I("Add an observer : %d", observe_id); + + ret = iotcon_observers_add(observers, observe_id); + retv_if(IOTCON_ERROR_NONE != ret, -1); + } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) { + ret = iotcon_request_get_observe_id(request, &observe_id); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + _I("Remove an observer : %d", observe_id); + + ret = iotcon_observers_remove(observers, observe_id); + retv_if(IOTCON_ERROR_NONE != ret, -1); + } + + return 0; +} static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result) { @@ -63,10 +237,185 @@ error: return -1; } +static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data) +{ + connectivity_resource_s *resource_info = user_data; + int ret = -1; + char *host_address = NULL; + + ret_if(!request); + + ret = iotcon_request_get_host_address(request, &host_address); + goto_if(IOTCON_ERROR_NONE != ret, error); + + _D("Host address : %s", host_address); + + ret = _handle_query(request); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = _handle_request_by_crud_type(request, resource_info); + goto_if(0 != ret, error); + + ret = _handle_observer(request, resource_info->conn_data.iotcon_data.observers); + goto_if(0 != ret, error); + + return; + +error: + _send_response(request, NULL, IOTCON_RESPONSE_ERROR); + return; +} + +static int __init_iotcon(connectivity_resource_s *resource_info) +{ + int ret = -1; + iotcon_resource_types_h resource_types = NULL; + iotcon_resource_interfaces_h ifaces = NULL; + uint8_t policies = IOTCON_RESOURCE_NO_POLICY; + char res_path[PATH_MAX] = {0,}; + char data_path[PATH_MAX] = {0,}; + char *prefix = NULL; + + retv_if(!resource_info, -1); + retv_if(resource_info->conn_type != CONNECTIVITY_TYPE_IOTIVITY, -1); + + prefix = app_get_resource_path(); + retv_if(!prefix, -1); + snprintf(res_path, sizeof(res_path)-1, "%s%s", prefix, IOTCON_DB_FILENAME); + free(prefix); + prefix = NULL; + + prefix = app_get_data_path(); + retv_if(!prefix, -1); + snprintf(data_path, sizeof(data_path)-1, "%s%s", prefix, IOTCON_DB_FILENAME); + free(prefix); + + _copy_file(res_path, data_path); + + ret = iotcon_initialize(data_path); + retv_if(IOTCON_ERROR_NONE != ret, -1); + + /* TODO : If we have to set device name, naming it more gorgeous one */ + ret = iotcon_set_device_name(DEFAULT_RESOURCE_TYPE); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_resource_types_create(&resource_types); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_resource_types_add(resource_types, resource_info->type); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_resource_interfaces_create(&ifaces); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH); + goto_if(IOTCON_ERROR_NONE != ret, error); + + policies = + IOTCON_RESOURCE_DISCOVERABLE | + IOTCON_RESOURCE_OBSERVABLE | + IOTCON_RESOURCE_SECURE; + + ret = iotcon_resource_create(URI_PATH, + resource_types, + ifaces, + policies, + _request_resource_handler, + resource_info, + &resource_info->conn_data.iotcon_data.res); + goto_if(IOTCON_ERROR_NONE != ret, error); + + ret = iotcon_observers_create(&resource_info->conn_data.iotcon_data.observers); + goto_if(IOTCON_ERROR_NONE != ret, error); + + iotcon_resource_types_destroy(resource_types); + iotcon_resource_interfaces_destroy(ifaces); + connectivity_iotcon_intialized = 1; + + return 0; + +error: + if (resource_types) iotcon_resource_types_destroy(resource_types); + if (ifaces) iotcon_resource_interfaces_destroy(ifaces); + if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res); + iotcon_deinitialize(); + return -1; +} + +static int __init_http(connectivity_resource_s *resource_info) +{ + int ret = 0; + ret = web_util_noti_init(); + if (!ret) + connectivity_http_intialized = 1; + + return ret; +} + +#ifdef PRINT_DEBUG_DETAIL +static bool __print_attributes_cb(iotcon_attributes_h attributes, const char *key, void *user_data) +{ + iotcon_type_e type = IOTCON_TYPE_NONE; + + iotcon_attributes_get_type(attributes, key, &type); + + switch (type) { + case IOTCON_TYPE_INT: { + int value = 0; + iotcon_attributes_get_int(attributes, key, &value); + _D("key[%s] - int value [%d]", key, value); + } + break; + case IOTCON_TYPE_BOOL: { + bool value = 0; + iotcon_attributes_get_bool(attributes, key, &value); + _D("key[%s] - bool value [%d]", key, value); + } + break; + case IOTCON_TYPE_DOUBLE: { + double value = 0; + iotcon_attributes_get_double(attributes, key, &value); + _D("key[%s] - double value [%lf]", key, value); + } + break; + case IOTCON_TYPE_STR: { + char *value = 0; + iotcon_attributes_get_str(attributes, key, &value); + _D("key[%s] - string value [%s]", key, value); + } + break; + case IOTCON_TYPE_NONE: + case IOTCON_TYPE_BYTE_STR: + case IOTCON_TYPE_NULL: + case IOTCON_TYPE_LIST: + case IOTCON_TYPE_ATTRIBUTES: + default: + _W("unhandled key[%s] type[%d]", key, type); + break; + } + + return IOTCON_FUNC_CONTINUE; +} +#endif + +static void __print_attribute(iotcon_attributes_h attributes) +{ +#ifdef PRINT_DEBUG_DETAIL + ret_if(!attributes); + + iotcon_attributes_foreach(attributes, __print_attributes_cb, NULL); +#endif + return; +} + static void _destroy_representation(iotcon_representation_h representation) { ret_if(!representation); iotcon_representation_destroy(representation); + return; } static iotcon_representation_h _create_representation_with_bool(connectivity_resource_s *resource_info, const char *key, bool value) @@ -76,7 +425,7 @@ static iotcon_representation_h _create_representation_with_bool(connectivity_res char *uri_path = NULL; int ret = -1; - ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path); + ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path); retv_if(IOTCON_ERROR_NONE != ret, NULL); ret = iotcon_representation_create(&representation); @@ -115,7 +464,7 @@ static iotcon_representation_h _create_representation_with_int(connectivity_reso char *uri_path = NULL; int ret = -1; - ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path); + ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path); retv_if(IOTCON_ERROR_NONE != ret, NULL); ret = iotcon_representation_create(&representation); @@ -154,7 +503,7 @@ static iotcon_representation_h _create_representation_with_double(connectivity_r char *uri_path = NULL; int ret = -1; - ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path); + ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path); retv_if(IOTCON_ERROR_NONE != ret, NULL); ret = iotcon_representation_create(&representation); @@ -186,14 +535,14 @@ error: return NULL; } -static iotcon_representation_h _create_representation_with_string(connectivity_resource_s *resource_info, const char *key, char *value) +static iotcon_representation_h _create_representation_with_string(connectivity_resource_s *resource_info, const char *key, const char *value) { iotcon_attributes_h attributes = NULL; iotcon_representation_h representation = NULL; char *uri_path = NULL; int ret = -1; - ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path); + ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path); retv_if(IOTCON_ERROR_NONE != ret, NULL); ret = iotcon_representation_create(&representation); @@ -208,7 +557,8 @@ static iotcon_representation_h _create_representation_with_string(connectivity_r ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path); goto_if(IOTCON_ERROR_NONE != ret, error); - ret = iotcon_attributes_add_str(attributes, key, value); + /* WTF - type of 2nd argument of iotcon_attributes_add_str() should be "const char *" */ + ret = iotcon_attributes_add_str(attributes, key, (char *)value); goto_if(IOTCON_ERROR_NONE != ret, error); ret = iotcon_representation_set_attributes(representation, attributes); @@ -225,306 +575,562 @@ error: return NULL; } -static void _print_iotcon_error(int err_no) +static inline void __noti_by_http(void) { - switch (err_no) { - case IOTCON_ERROR_NOT_SUPPORTED: - _E("IOTCON_ERROR_NOT_SUPPORTED"); - break; - case IOTCON_ERROR_PERMISSION_DENIED: - _E("IOTCON_ERROR_PERMISSION_DENIED"); - break; - case IOTCON_ERROR_INVALID_PARAMETER: - _E("IOTCON_ERROR_INVALID_PARAMETER"); - break; - default: - _E("Error : [%d]", err_no); - break; - } + char *json_data = NULL; + + json_data = web_util_get_json_string(); + if (json_data) { + const char *url = NULL; + controller_util_get_address(&url); + if (url) + web_util_noti_post(url, json_data); + else + _E("fail to get url"); + free(json_data); + } else + _E("fail to get json_data"); + + return; } int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value) { - iotcon_representation_h representation; int ret = -1; retv_if(!resource_info, -1); - retv_if(!resource_info->observers, -1); + retv_if(!key, -1); + + _D("Notify key[%s], value[%d]", key, value); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + retv_if(!resource_info->conn_data.iotcon_data.res, -1); + retv_if(!resource_info->conn_data.iotcon_data.observers, -1); + { + iotcon_representation_h representation; + representation = _create_representation_with_bool(resource_info, key, value); + retv_if(!representation, -1); + ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, + representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW); + if (IOTCON_ERROR_NONE != ret) { + _W("There are some troubles for notifying value[%d]", ret); + _print_iotcon_error(ret); + return -1; + } + _destroy_representation(representation); + } + break; + case CONNECTIVITY_TYPE_HTTP: + ret = web_util_json_init(); + retv_if(ret, -1); - _D("Notify the value[%d]", value); + ret = web_util_json_begin(); + retv_if(ret, -1); - representation = _create_representation_with_bool(resource_info, key, value); - retv_if(!representation, -1); + web_util_json_add_string("SensorPiID", resource_info->path); + web_util_json_add_string("SensorPiType", resource_info->type); /* need it? */ + web_util_json_add_boolean(key, value); + web_util_json_end(); - ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW); - if (IOTCON_ERROR_NONE != ret) { - _I("There are some troubles for notifying value[%d]", ret); - _print_iotcon_error(ret); + __noti_by_http(); + + web_util_json_fini(); + break; + default: + _E("Unknown connectivity type[%d]", resource_info->conn_type); return -1; + break; } - _destroy_representation(representation); - return 0; } +/* WTF - I want to use 'long long int' type as a value, but iotcon api accept 'int' type */ int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value) { - iotcon_representation_h representation; int ret = -1; retv_if(!resource_info, -1); - retv_if(!resource_info->observers, -1); + retv_if(!key, -1); + + _D("Notify key[%s], value[%d]", key, value); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + retv_if(!resource_info->conn_data.iotcon_data.res, -1); + retv_if(!resource_info->conn_data.iotcon_data.observers, -1); + { + iotcon_representation_h representation; + representation = _create_representation_with_int(resource_info, key, value); + retv_if(!representation, -1); + ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, + representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW); + if (IOTCON_ERROR_NONE != ret) { + _W("There are some troubles for notifying value[%d]", ret); + _print_iotcon_error(ret); + return -1; + } + _destroy_representation(representation); + } + break; + case CONNECTIVITY_TYPE_HTTP: + ret = web_util_json_init(); + retv_if(ret, -1); - _D("Notify the value[%d]", value); + ret = web_util_json_begin(); + retv_if(ret, -1); - representation = _create_representation_with_int(resource_info, key, value); - retv_if(!representation, -1); + web_util_json_add_string("SensorPiID", resource_info->path); + web_util_json_add_string("SensorPiType", resource_info->type); /* need it? */ + web_util_json_add_int(key, value); + web_util_json_end(); - ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW); - if (IOTCON_ERROR_NONE != ret) { - _I("There are some troubles for notifying value[%d]", ret); - _print_iotcon_error(ret); + __noti_by_http(); + + web_util_json_fini(); + break; + default: + _E("Unknown connectivity type[%d]", resource_info->conn_type); return -1; + break; } - - _destroy_representation(representation); - return 0; } int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value) { - iotcon_representation_h representation; int ret = -1; retv_if(!resource_info, -1); - retv_if(!resource_info->observers, -1); + retv_if(!key, -1); + + _D("Notify key[%s], value[%lf]", key, value); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + retv_if(!resource_info->conn_data.iotcon_data.res, -1); + retv_if(!resource_info->conn_data.iotcon_data.observers, -1); + { + iotcon_representation_h representation; + representation = _create_representation_with_double(resource_info, key, value); + retv_if(!representation, -1); + ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, + representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW); + if (IOTCON_ERROR_NONE != ret) { + _W("There are some troubles for notifying value[%d]", ret); + _print_iotcon_error(ret); + return -1; + } + _destroy_representation(representation); + } + break; + case CONNECTIVITY_TYPE_HTTP: + ret = web_util_json_init(); + retv_if(ret, -1); - _D("Notify the value [%.2lf]", value); + ret = web_util_json_begin(); + retv_if(ret, -1); - representation = _create_representation_with_double(resource_info, key, value); - retv_if(!representation, -1); + web_util_json_add_string("SensorPiID", resource_info->path); + web_util_json_add_string("SensorPiType", resource_info->type); /* need it? */ + web_util_json_add_double(key, value); + web_util_json_end(); - ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW); - if (IOTCON_ERROR_NONE != ret) { - _I("There are some troubles for notifying value[%d]", ret); - _print_iotcon_error(ret); + __noti_by_http(); + + web_util_json_fini(); + break; + default: + _E("Unknown connectivity type[%d]", resource_info->conn_type); return -1; + break; } - - _destroy_representation(representation); - return 0; } -int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, char *value) +int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, const char *value) { - iotcon_representation_h representation; int ret = -1; retv_if(!resource_info, -1); - retv_if(!resource_info->observers, -1); + retv_if(!key, -1); + retv_if(!value, -1); + + _D("Notify key[%s], value[%s]", key, value); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + retv_if(!resource_info->conn_data.iotcon_data.res, -1); + retv_if(!resource_info->conn_data.iotcon_data.observers, -1); + { + iotcon_representation_h representation; + representation = _create_representation_with_string(resource_info, key, value); + retv_if(!representation, -1); + ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, + representation, resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW); + if (IOTCON_ERROR_NONE != ret) { + _W("There are some troubles for notifying value[%d]", ret); + _print_iotcon_error(ret); + return -1; + } + _destroy_representation(representation); + } + break; + case CONNECTIVITY_TYPE_HTTP: + ret = web_util_json_init(); + retv_if(ret, -1); - _D("Notify the value [%s]", value); + ret = web_util_json_begin(); + retv_if(ret, -1); - representation = _create_representation_with_string(resource_info, key, value); - retv_if(!representation, -1); + web_util_json_add_string("SensorPiID", resource_info->path); + web_util_json_add_string("SensorPiType", resource_info->type); /* need it? */ + web_util_json_add_string(key, value); + web_util_json_end(); - ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW); - if (IOTCON_ERROR_NONE != ret) { - _I("There are some troubles for notifying value[%d]", ret); - _print_iotcon_error(ret); + __noti_by_http(); + + web_util_json_fini(); + break; + default: + _E("Unknown connectivity type[%d]", resource_info->conn_type); return -1; + break; } - - _destroy_representation(representation); - return 0; } -static bool _query_cb(const char *key, const char *value, void *user_data) +static void __hash_key_free(gpointer data) { - _D("Key : [%s], Value : [%s]", key, value); + free(data); + return; +} - return IOTCON_FUNC_CONTINUE; +static void __hash_value_free(gpointer data) +{ + conn_data_value_s *value = data; + if (value && (value->type == DATA_VAL_TYPE_STRING)) + free(value->s_val); + free(value); + + return; } -static int _handle_query(iotcon_request_h request) +static int __add_value_to_hash(connectivity_resource_s *resource_info, const char *key, conn_data_value_s *value) { - iotcon_query_h query = NULL; - int ret = -1; + retv_if(!resource_info, -1); + retv_if(!key, -1); + retv_if(!value, -1); - ret = iotcon_request_get_query(request, &query); - retv_if(IOTCON_ERROR_NONE != ret, -1); + if (!resource_info->value_hash) { + resource_info->value_hash = g_hash_table_new_full(g_str_hash, g_str_equal, + __hash_key_free, __hash_value_free); + retv_if(!resource_info->value_hash, -1); + } - if (query) iotcon_query_foreach(query, _query_cb, NULL); + g_hash_table_insert(resource_info->value_hash, strdup(key), value); return 0; } -static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info) +int connectivity_notify_multi_add_bool(connectivity_resource_s *resource_info, const char *key, bool value) { - iotcon_request_type_e type; - int ret = -1; + conn_data_value_s *data_value = NULL; - ret = iotcon_request_get_request_type(request, &type); - retv_if(IOTCON_ERROR_NONE != ret, -1); + retv_if(!resource_info, -1); + retv_if(!key, -1); - switch (type) { - case IOTCON_REQUEST_GET: - _I("Do not support 'get' query"); - break; - case IOTCON_REQUEST_PUT: - _I("Do not support 'put' query"); - break; - case IOTCON_REQUEST_POST: - _I("Do not support 'post' query"); - break; - case IOTCON_REQUEST_DELETE: - _I("Do not support 'delete' query"); - break; - default: - _E("Cannot reach here"); - ret = -1; - break; - } - retv_if(0 != ret, -1); + _D("adding key[%s] - value[%d]", key, value); - return 0; + data_value = malloc(sizeof(conn_data_value_s)); + retv_if(!data_value, -1); + + data_value->type = DATA_VAL_TYPE_BOOL; + data_value->b_val = value; + + return __add_value_to_hash(resource_info, key, data_value); } -static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers) +/* WTF - I want to use 'long long int' type as a value, but iotcon api accept 'int' type */ +int connectivity_notify_multi_add_int(connectivity_resource_s *resource_info, const char *key, int value) { - iotcon_observe_type_e observe_type; - int ret = -1; - int observe_id = -1; + conn_data_value_s *data_value = NULL; - ret = iotcon_request_get_observe_type(request, &observe_type); - retv_if(IOTCON_ERROR_NONE != ret, -1); + retv_if(!resource_info, -1); + retv_if(!key, -1); - if (IOTCON_OBSERVE_REGISTER == observe_type) { - ret = iotcon_request_get_observe_id(request, &observe_id); - retv_if(IOTCON_ERROR_NONE != ret, -1); + _D("adding key[%s] - value[%d]", key, value); - _I("Add an observer : %d", observe_id); + data_value = malloc(sizeof(conn_data_value_s)); + retv_if(!data_value, -1); - ret = iotcon_observers_add(observers, observe_id); - retv_if(IOTCON_ERROR_NONE != ret, -1); - } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) { - ret = iotcon_request_get_observe_id(request, &observe_id); - retv_if(IOTCON_ERROR_NONE != ret, -1); + data_value->type = DATA_VAL_TYPE_INT; + data_value->i_val = value; - _I("Remove an observer : %d", observe_id); + return __add_value_to_hash(resource_info, key, data_value); +} - ret = iotcon_observers_remove(observers, observe_id); - retv_if(IOTCON_ERROR_NONE != ret, -1); - } +int connectivity_notify_multi_add_double(connectivity_resource_s *resource_info, const char *key, double value) +{ + conn_data_value_s *data_value = NULL; - return 0; + retv_if(!resource_info, -1); + retv_if(!key, -1); + + _D("adding key[%s] - value[%lf]", key, value); + + data_value = malloc(sizeof(conn_data_value_s)); + retv_if(!data_value, -1); + + data_value->type = DATA_VAL_TYPE_DOUBLE; + data_value->d_val = value; + + return __add_value_to_hash(resource_info, key, data_value); } -static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data) +int connectivity_notify_multi_add_string(connectivity_resource_s *resource_info, const char *key, const char *value) { - connectivity_resource_s *resource_info = user_data; - int ret = -1; - char *host_address = NULL; + conn_data_value_s *data_value = NULL; - ret_if(!request); + retv_if(!resource_info, -1); + retv_if(!key, -1); + retv_if(!value, -1); - ret = iotcon_request_get_host_address(request, &host_address); - goto_if(IOTCON_ERROR_NONE != ret, error); + _D("adding key[%s] - value[%s]", key, value); - _D("Host address : %s", host_address); + data_value = malloc(sizeof(conn_data_value_s)); + retv_if(!data_value, -1); - ret = _handle_query(request); - goto_if(IOTCON_ERROR_NONE != ret, error); + data_value->type = DATA_VAL_TYPE_STRING; + data_value->s_val = strdup(value); - ret = _handle_request_by_crud_type(request, resource_info); - goto_if(0 != ret, error); + return __add_value_to_hash(resource_info, key, data_value); +} - ret = _handle_observer(request, resource_info->observers); - goto_if(0 != ret, error); +static void __json_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data) +{ + char *name = key; + conn_data_value_s *data = value; + int ret = 0; + + ret_if(name); + ret_if(data); + + switch (data->type) { + case DATA_VAL_TYPE_BOOL: + ret = web_util_json_add_boolean(name, data->b_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%d]", name, data->b_val); + break; + case DATA_VAL_TYPE_INT: + ret = web_util_json_add_int(name, data->i_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%d]", name, data->i_val); + break; + case DATA_VAL_TYPE_DOUBLE: + ret = web_util_json_add_double(name, data->d_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%lf]", name, data->d_val); + break; + case DATA_VAL_TYPE_STRING: + ret = web_util_json_add_string(name, data->s_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%s]", name, data->s_val); + break; + default: + _E("Unknown data type [%d]", data->type); + break; + } return; - -error: - _send_response(request, NULL, IOTCON_RESPONSE_ERROR); } -static void _copy_file(const char *in_filename, const char *out_filename) +static void __attr_add_data_iter_cb(gpointer key, gpointer value, gpointer user_data) { - char buf[BUFSIZE] = { 0, }; - size_t nread = 0; - FILE *in = NULL; - FILE *out = NULL; - - ret_if(!in_filename); - ret_if(!out_filename); + char *name = key; + conn_data_value_s *data = value; + iotcon_attributes_h attr = user_data; + int ret = 0; + + ret_if(name); + ret_if(data); + ret_if(attr); + + switch (data->type) { + case DATA_VAL_TYPE_BOOL: + ret = iotcon_attributes_add_bool(attr, name, data->b_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%d]", name, data->b_val); + break; + case DATA_VAL_TYPE_INT: + ret = iotcon_attributes_add_int(attr, name, data->i_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%d]", name, data->i_val); + break; + case DATA_VAL_TYPE_DOUBLE: + ret = iotcon_attributes_add_double(attr, name, data->d_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%lf]", name, data->d_val); + break; + case DATA_VAL_TYPE_STRING: + ret = iotcon_attributes_add_str(attr, name, data->s_val); + if (IOTCON_ERROR_NONE != ret) + _E("failed to add key[%s], value[%s]", name, data->s_val); + break; + default: + _E("Unknown data type [%d]", data->type); + break; + } - in = fopen(in_filename, "r"); - ret_if(!in); + return; +} - out = fopen(out_filename, "w"); - goto_if(!out, error); +static int __create_attributes(connectivity_resource_s *resource_info, iotcon_attributes_h *attributes) +{ + int ret = 0; + iotcon_attributes_h attr = NULL; - rewind(in); - while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, nread, out) < nread) { - _E("critical error to copy a file"); - break; - } + ret = iotcon_attributes_create(&attr); + if (IOTCON_ERROR_NONE != ret) { + _print_iotcon_error(ret); + return -1; } - fclose(in); - fclose(out); + ret = iotcon_attributes_add_str(attr, PATH, resource_info->path); + if (IOTCON_ERROR_NONE != ret) { + _print_iotcon_error(ret); + iotcon_attributes_destroy(attr); + return -1; + } + if (resource_info->value_hash) + g_hash_table_foreach(resource_info->value_hash, __attr_add_data_iter_cb, attr); - return; + *attributes = attr; -error: - fclose(out); + return 0; } -int connectivity_init(void) +int connectivity_notify_multi_perform(connectivity_resource_s *resource_info) { - int ret = -1; + int ret = 0; - _copy_file(CBOR_FILE_IN_RES, CBOR_FILE_IN_DATA); + retv_if(!resource_info, -1); + retv_if(!resource_info->value_hash, -1); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + retv_if(!resource_info->conn_data.iotcon_data.res, -1); + retv_if(!resource_info->conn_data.iotcon_data.observers, -1); + { + char *uri_path = NULL; + iotcon_representation_h representation = NULL; + iotcon_attributes_h attributes = NULL; + int iotcon_ret = 0; + + iotcon_ret = iotcon_resource_get_uri_path(resource_info->conn_data.iotcon_data.res, &uri_path); + retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1); + + iotcon_ret = iotcon_representation_create(&representation); + retv_if(IOTCON_ERROR_NONE != iotcon_ret, -1); + + iotcon_ret = iotcon_representation_set_uri_path(representation, uri_path); + if (IOTCON_ERROR_NONE != iotcon_ret) { + _print_iotcon_error(iotcon_ret); + ret = -1; + } + + iotcon_ret = __create_attributes(resource_info, &attributes); + if (iotcon_ret) { + _E("failed to create attributes"); + ret = -1; + } + __print_attribute(attributes); + + iotcon_ret = iotcon_representation_set_attributes(representation, attributes); + if (IOTCON_ERROR_NONE != iotcon_ret) { + _print_iotcon_error(iotcon_ret); + ret = -1; + } + + iotcon_ret = iotcon_resource_notify(resource_info->conn_data.iotcon_data.res, representation, + resource_info->conn_data.iotcon_data.observers, IOTCON_QOS_LOW); + if (IOTCON_ERROR_NONE != iotcon_ret) { + _print_iotcon_error(iotcon_ret); + ret = -1; + } + + iotcon_representation_destroy(representation); + iotcon_attributes_destroy(attributes); + } + break; + case CONNECTIVITY_TYPE_HTTP: + /* TODO */ + ret = web_util_json_init(); + retv_if(ret, -1); - ret = iotcon_initialize(CBOR_FILE_IN_DATA); - retv_if(IOTCON_ERROR_NONE != ret, -1); + ret = web_util_json_begin(); + retv_if(ret, -1); - ret = iotcon_set_device_name(ULTRASONIC_RESOURCE_TYPE); - goto_if(IOTCON_ERROR_NONE != ret, error); + web_util_json_add_string("SensorPiID", resource_info->path); + web_util_json_add_string("SensorPiType", resource_info->type); /* need it? */ + g_hash_table_foreach(resource_info->value_hash, __json_add_data_iter_cb, NULL); + web_util_json_end(); - return 0; + __noti_by_http(); -error: - iotcon_deinitialize(); - return -1; + web_util_json_fini(); + break; + default: + break; + } + + g_hash_table_destroy(resource_info->value_hash); + resource_info->value_hash = NULL; + + return ret; +} + +/* Remove init and fini function or Not? */ +int connectivity_init(void) +{ + return 0; } int connectivity_fini(void) { - iotcon_deinitialize(); return 0; } void connectivity_unset_resource(connectivity_resource_s *resource_info) { ret_if(!resource_info); - if (resource_info->observers) iotcon_observers_destroy(resource_info->observers); - if (resource_info->res) iotcon_resource_destroy(resource_info->res); + + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_IOTIVITY: + if (resource_info->conn_data.iotcon_data.observers) iotcon_observers_destroy(resource_info->conn_data.iotcon_data.observers); + if (resource_info->conn_data.iotcon_data.res) iotcon_resource_destroy(resource_info->conn_data.iotcon_data.res); + iotcon_deinitialize(); + connectivity_iotcon_intialized = 0; + break; + case CONNECTIVITY_TYPE_HTTP: + web_util_noti_fini(); + connectivity_http_intialized = 0; + break; + default: + break; + } + if (resource_info->path) free(resource_info->path); + if (resource_info->type) free(resource_info->type); free(resource_info); + + return; } int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info) { - iotcon_resource_types_h resource_types = NULL; - iotcon_resource_interfaces_h ifaces = NULL; connectivity_resource_s *resource_info = NULL; - uint8_t policies; int ret = -1; retv_if(!path, -1); @@ -537,52 +1143,69 @@ int connectivity_set_resource(const char *path, const char *type, connectivity_r resource_info->path = strdup(path); goto_if(!resource_info->path, error); - _D("Path : [%s]", resource_info->path); - - ret = iotcon_resource_types_create(&resource_types); - goto_if(IOTCON_ERROR_NONE != ret, error); - - ret = iotcon_resource_types_add(resource_types, type); - goto_if(IOTCON_ERROR_NONE != ret, error); - - ret = iotcon_resource_interfaces_create(&ifaces); - goto_if(IOTCON_ERROR_NONE != ret, error); - - ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT); - goto_if(IOTCON_ERROR_NONE != ret, error); - - ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH); - goto_if(IOTCON_ERROR_NONE != ret, error); + resource_info->type = strdup(type); + goto_if(!resource_info->type, error); - policies = - IOTCON_RESOURCE_DISCOVERABLE | - IOTCON_RESOURCE_OBSERVABLE | - IOTCON_RESOURCE_SECURE; + resource_info->conn_type = ConnectivityType; - ret = iotcon_resource_create(URI_PATH, - resource_types, - ifaces, - policies, - _request_resource_handler, - resource_info, - &resource_info->res); - goto_if(IOTCON_ERROR_NONE != ret, error); + _D("Path[%s], Type[%s], conn_type[%d]" , resource_info->path, resource_info->type, resource_info->conn_type); - ret = iotcon_observers_create(&resource_info->observers); - goto_if(IOTCON_ERROR_NONE != ret, error); + switch (resource_info->conn_type) { + case CONNECTIVITY_TYPE_DEFAULT: + _D("default connectivity type is iotivity\n \ + To set connectivity use connectivity_set_connectivity_type() function"); + resource_info->conn_type = CONNECTIVITY_TYPE_IOTIVITY; + case CONNECTIVITY_TYPE_IOTIVITY: + ret = __init_iotcon(resource_info); + goto_if(ret, error); + break; + case CONNECTIVITY_TYPE_HTTP: + ret = __init_http(resource_info); + goto_if(ret, error); + break; + default: + goto error; + break; + } - iotcon_resource_types_destroy(resource_types); - iotcon_resource_interfaces_destroy(ifaces); *out_resource_info = resource_info; return 0; error: - if (ifaces) iotcon_resource_interfaces_destroy(ifaces); - if (resource_types) iotcon_resource_types_destroy(resource_types); - if (resource_info->res) iotcon_resource_destroy(resource_info->res); if (resource_info->path) free(resource_info->path); + if (resource_info->type) free(resource_info->type); if (resource_info) free(resource_info); return -1; } + +int connectivity_set_connectivity_type(connectivity_type_e connectivity_type) +{ + int ret = 0; + retv_if(connectivity_type >= CONNECTIVITY_TYPE_MAX, -1); + + switch (connectivity_type) { + case CONNECTIVITY_TYPE_DEFAULT: + case CONNECTIVITY_TYPE_IOTIVITY: + if (connectivity_iotcon_intialized) { + _E("connectivity type[%d] aleady initialized", connectivity_type); + return -1; + } + ConnectivityType = CONNECTIVITY_TYPE_IOTIVITY; + break; + case CONNECTIVITY_TYPE_HTTP: + if (connectivity_iotcon_intialized) { + _E("connectivity type[%d] aleady initialized", connectivity_type); + return -1; + } + ConnectivityType = CONNECTIVITY_TYPE_HTTP; + break; + default: + _E("unknown connectivity type[%d]", connectivity_type); + return -1; + break; + } + + return ret; +} -- 2.7.4