From 0a9564f207fee895fe894d2058382fc42741e561 Mon Sep 17 00:00:00 2001 From: hyunho kang Date: Thu, 22 Oct 2015 11:15:01 +0900 Subject: [PATCH] Improve data-control performance using socket fd passing. Change-Id: I46f560f5725baf74e35f7832ebf83022e5f3f036 Signed-off-by: hyunho kang Signed-off-by: jusung.son --- include/data-control-sql-cursor.h | 18 +- src/data-control-internal.c | 235 ++++++- src/data-control-internal.h | 50 +- src/data-control-map.c | 828 +++++++++++------------ src/data-control-provider.c | 1332 ++++++++++++++++++------------------- src/data-control-sql-cursor.c | 382 +++-------- src/data-control-sql.c | 1290 ++++++++++++++++++----------------- src/data_control_internal.c | 7 + src/data_control_provider.c | 20 +- 9 files changed, 2132 insertions(+), 2030 deletions(-) mode change 100644 => 100755 src/data-control-internal.c mode change 100644 => 100755 src/data-control-internal.h mode change 100644 => 100755 src/data-control-map.c mode change 100644 => 100755 src/data-control-provider.c mode change 100644 => 100755 src/data-control-sql-cursor.c mode change 100644 => 100755 src/data-control-sql.c mode change 100644 => 100755 src/data_control_internal.c mode change 100644 => 100755 src/data_control_provider.c diff --git a/include/data-control-sql-cursor.h b/include/data-control-sql-cursor.h index 5179efd..0c022dd 100644 --- a/include/data-control-sql-cursor.h +++ b/include/data-control-sql-cursor.h @@ -23,6 +23,7 @@ #define _APPFW_DATA_CONTROL_SQL_ENUMERATOR_H_ #include +#include #include "data-control-types.h" #ifdef __cplusplus @@ -35,14 +36,15 @@ extern "C" { typedef struct { int resultset_fd; - int resultset_row_count; + sqlite3_int64 resultset_row_count; int resultset_col_count; - int resultset_col_type_offset; - int resultset_col_name_offset; - int resultset_content_offset; - int resultset_current_offset; - int resultset_current_row_count; - char* resultset_path; + off_t resultset_col_type_offset; + off_t resultset_col_name_offset; + off_t resultset_content_offset; + off_t resultset_current_offset; + sqlite3_int64 resultset_current_row_count; + char *resultset_path; + off_t *row_offset_list; } resultset_cursor; /** @@ -51,7 +53,7 @@ typedef struct * @param [in] path The path of the file containing the SQL result set * @return A pointer to struct @c resultset_cursor */ -resultset_cursor* datacontrol_sql_get_cursor(const char *path); +resultset_cursor* datacontrol_sql_get_cursor(); /** * @brief Moves the cursor to the first position diff --git a/src/data-control-internal.c b/src/data-control-internal.c old mode 100644 new mode 100755 index aea4808..a7917be --- a/src/data-control-internal.c +++ b/src/data-control-internal.c @@ -5,32 +5,117 @@ #include #include #include +#include #include +#include +#include #include +#include #include +#include + +#include + #include "data-control-sql-cursor.h" #include "data-control-internal.h" #define MAX_COLUMN_SIZE 512 #define MAX_STATEMENT_SIZE 1024 +#define RESULT_VALUE_COUNT "RESULT_VALUE_COUNT" +#define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE" +#define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER" +#define MAX_RETRY 5 -int -_datacontrol_sql_get_cursor(const char *path) +#define BUFSIZE 512 + +int _consumer_request_compare_cb(gconstpointer a, gconstpointer b) { + datacontrol_consumer_request_info *key1 = (datacontrol_consumer_request_info *)a; + datacontrol_consumer_request_info *key2 = (datacontrol_consumer_request_info *)b; + if (key1->request_id == key2->request_id) + return 0; + + return 1; +} + +int _write_socket(int fd, + void *buffer, + unsigned int nbytes, + unsigned int *bytes_write) { + + unsigned int left = nbytes; + gsize nb; + + int retry_cnt = 0; + + *bytes_write = 0; + while (left && (retry_cnt < MAX_RETRY)) { + nb = write(fd, buffer, left); + LOGI("_write_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb); + + if (nb == -1) { + if (errno == EINTR) { + LOGE("_write_socket: EINTR error continue ..."); + retry_cnt++; + continue; + } + LOGE("_write_socket: ...error fd %d: errno %d\n", fd, errno); + return DATACONTROL_ERROR_IO_ERROR; + } + + left -= nb; + buffer += nb; + *bytes_write += nb; + retry_cnt = 0; + } + + return DATACONTROL_ERROR_NONE; +} - return 0; +int _read_socket(int fd, + char *buffer, + unsigned int nbytes, + unsigned int *bytes_read) { + + unsigned int left = nbytes; + gsize nb; + + int retry_cnt = 0; + + *bytes_read = 0; + while (left && (retry_cnt < MAX_RETRY)) { + nb = read(fd, buffer, left); + LOGI("_read_socket: ...from %d: nb %d left %d\n", fd, nb, left - nb); + if (nb == 0) { + LOGE("_read_socket: ...read EOF, socket closed %d: nb %d\n", fd, nb); + return DATACONTROL_ERROR_IO_ERROR; + } else if (nb == -1) { + if (errno == EINTR) { + LOGE("_read_socket: EINTR error continue ..."); + retry_cnt++; + continue; + } + LOGE("_read_socket: ...error fd %d: errno %d\n", fd, errno); + return DATACONTROL_ERROR_IO_ERROR; + } + + left -= nb; + buffer += nb; + *bytes_read += nb; + retry_cnt = 0; + } + return DATACONTROL_ERROR_NONE; } -char* -_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page) +char *_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, + const char *where, const char *order, int page_number, int count_per_page) { char *column = calloc(MAX_COLUMN_SIZE, sizeof(char)); int i = 0; - while (i < column_count - 1) - { + while (i < column_count - 1) { LOGI("column i = %d, %s", i, column_list[i]); strcat(column, column_list[i]); strcat(column, ", "); @@ -41,7 +126,8 @@ _datacontrol_create_select_statement(char *data_id, const char **column_list, in strcat(column, column_list[i]); char *statement = calloc(MAX_STATEMENT_SIZE, sizeof(char)); - snprintf(statement, MAX_STATEMENT_SIZE, "SELECT %s * FROM %s WHERE %s ORDER BY %s", column, data_id, where, order); + snprintf(statement, MAX_STATEMENT_SIZE, "SELECT %s * FROM %s WHERE %s ORDER BY %s", column, + data_id, where, order); LOGI("SQL statement: %s", statement); @@ -49,12 +135,139 @@ _datacontrol_create_select_statement(char *data_id, const char **column_list, in return statement; } -int -_datacontrol_create_request_id(void) +int _datacontrol_create_request_id(void) { static int id = 0; - g_atomic_int_inc(&id); return id; } + +void _socket_info_free(gpointer socket) +{ + datacontrol_socket_info *socket_info = (datacontrol_socket_info *)socket; + + if (socket_info != NULL) { + if (socket_info->socket_fd != 0) { + shutdown(socket_info->socket_fd, SHUT_RDWR); + LOGE("shutdown socketpair !!!! %d ", socket_info->socket_fd); + } + if (socket_info->gio_read != NULL) { + g_io_channel_unref(socket_info->gio_read); + socket_info->gio_read = NULL; + } + if (socket_info->g_src_id != 0) { + g_source_remove(socket_info->g_src_id); + socket_info->g_src_id = 0; + } + free(socket_info); + socket_info = NULL; + } + +} + +datacontrol_socket_info *_get_socket_info(const char *caller_id, const char *callee_id, const char *type, + GIOFunc cb, void *data) +{ + + int socketpair = 0; + datacontrol_socket_info *socket_info = NULL; + bundle *sock_bundle = bundle_create(); + bundle_add_str(sock_bundle, AUL_K_CALLER_APPID, caller_id); + bundle_add_str(sock_bundle, AUL_K_CALLEE_APPID, callee_id); + bundle_add_str(sock_bundle, "DATA_CONTOL_TYPE", type); + + aul_request_data_control_socket_pair(sock_bundle, &socketpair); + bundle_free(sock_bundle); + + LOGI("consumer socket pair : %d", socketpair); + + if (socketpair > 0) { + GIOChannel *gio_read = NULL; + gio_read = g_io_channel_unix_new(socketpair); + if (!gio_read) { + LOGE("Error is %s\n", strerror(errno)); + return NULL; + } + + int g_src_id = g_io_add_watch(gio_read, G_IO_IN | G_IO_HUP, + cb, data); + + if (g_src_id == 0) { + g_io_channel_unref(gio_read); + LOGE("fail to add watch on socket"); + return NULL; + } + + socket_info = (datacontrol_socket_info *)calloc(1, sizeof(datacontrol_socket_info)); + if (socket_info == NULL) { + g_io_channel_unref(gio_read); + g_source_remove(g_src_id); + LOGE("fail to calloc socket_info"); + return NULL; + } + socket_info->socket_fd = socketpair; + socket_info->gio_read = gio_read; + socket_info->g_src_id = g_src_id; + LOGI("Watch on socketpair done."); + } else { + LOGE("fail to get socket pair"); + return NULL; + } + return socket_info; +} + +int _request_appsvc_run(const char *caller_id, const char *callee_id) +{ + + int pid = -1; + int count = 0; + const int TRY_COUNT = 4; + const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 }; + bundle *arg_list = bundle_create(); + + if (!arg_list) { + LOGE("unable to create bundle: %d", errno); + return DATACONTROL_ERROR_OUT_OF_MEMORY; + } + + appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT); + appsvc_set_appid(arg_list, callee_id); + bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP); + bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL); + bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_id); + bundle_add_str(arg_list, AUL_K_CALLEE_APPID, callee_id); + bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1"); + LOGI("caller_id %s, callee_id %s", caller_id, callee_id); + + // For DataControl CAPI + bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE"); + + do { + + pid = appsvc_run_service(arg_list, 0, NULL, NULL); + + if (pid >= 0) { + LOGI("Launch the provider app successfully: %d", pid); + bundle_free(arg_list); + break; + + } else if (pid == APPSVC_RET_EINVAL) { + LOGE("not able to launch service: %d", pid); + bundle_free(arg_list); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } + + count++; + + nanosleep(&TRY_SLEEP_TIME, 0); + } while (count < TRY_COUNT); + + if (count >= TRY_COUNT) { + LOGE("unable to launch service: %d", pid); + return DATACONTROL_ERROR_IO_ERROR; + } + return DATACONTROL_ERROR_NONE; + +} + diff --git a/src/data-control-internal.h b/src/data-control-internal.h old mode 100644 new mode 100755 index 9e5a74c..280d157 --- a/src/data-control-internal.h +++ b/src/data-control-internal.h @@ -18,6 +18,7 @@ * @file data-control-internal.h * @brief This is the header file for private keys of the data-control. */ +#include #ifndef _APPFW_DATA_CONTROL_INTERNAL_H_ #define _APPFW_DATA_CONTROL_INTERNAL_H_ @@ -39,14 +40,13 @@ #define OSP_K_DATACONTROL_PROTOCOL_VERSION "__OSP_DATACONTROL_PROTOCOL_VERSION__" #define OSP_K_CALLER_TYPE "__OSP_CALLER_TYPE__" -#define DATACONTROL_SELECT_STATEMENT "DATACONTROL_SELECT_STATEMENT" +#define DATACONTROL_SELECT_STATEMENT "DATACONTROL_SELECT_STATEMENT" -#define DATACONTROL_EMPTY "NULL" +#define DATACONTROL_EMPTY "NULL" #define DATACONTROL_SELECT_EXTRA_COUNT 6 // data id, column count, where, order, page, per_page +#define DATACONTROL_RESULT_NO_DATA -1 - - -#define OSP_V_LAUNCH_TYPE_DATACONTROL "datacontrol" +#define OSP_V_LAUNCH_TYPE_DATACONTROL "datacontrol" #define OSP_V_VERSION_2_1_0_3 "ver_2.1.0.3" #define OSP_V_CALLER_TYPE_OSP "osp" @@ -72,14 +72,42 @@ typedef enum DATACONTROL_TYPE_MAX = 255 } datacontrol_request_type; -int -datacontrol_sql_set_cursor(const char *path); +typedef struct datacontrol_pkt { + int len; + unsigned char data[1]; +} datacontrol_pkt_s; + +typedef struct datacontrol_socket { + GIOChannel *gio_read; + int g_src_id; + int socket_fd; +} datacontrol_socket_info; + +typedef struct datacontrol_consumer_request { + int request_id; + datacontrol_request_type type; +} datacontrol_consumer_request_info; + +int _consumer_request_compare_cb(gconstpointer a, gconstpointer b); + +int _datacontrol_sql_set_cursor(const char *path); + +char *_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, + const char *where, const char *order, int page_number, int count_per_page); + +int _datacontrol_create_request_id(void); + +int _datacontrol_send_async(int sockfd, bundle *kb, datacontrol_request_type type, void *data); +int _read_socket(int fd, char *buffer, unsigned int nbytes, unsigned int *bytes_read); +int _write_socket(int fd, void *buffer, unsigned int nbytes, unsigned int *bytes_write); + +gboolean _datacontrol_recv_message(GIOChannel *channel, GIOCondition cond, gpointer data); +int _get_gdbus_shared_connection(GDBusConnection **connection, char *provider_id); +void _socket_info_free (gpointer socket); +datacontrol_socket_info * _get_socket_info(const char *caller_id, const char *callee_id, const char *type, GIOFunc cb, void *data); +int _request_appsvc_run(const char *caller_id, const char *callee_id); -char* -_datacontrol_create_select_statement(char *data_id, const char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page); -int -_datacontrol_create_request_id(void); #endif /* _APPFW_DATA_CONTROL_INTERNAL_H_ */ diff --git a/src/data-control-map.c b/src/data-control-map.c old mode 100644 new mode 100755 index 70c7411..ee0408c --- a/src/data-control-map.c +++ b/src/data-control-map.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -22,32 +23,31 @@ struct datacontrol_s { char *data_id; }; -typedef struct -{ - char *provider_id; - char *app_id; - char *data_id; - char *access_info; - void *user_data; - datacontrol_map_response_cb *map_response_cb; +typedef struct { + char *provider_id; + char *app_id; + char *data_id; + char *access_info; + void *user_data; + GList *request_info_list; + datacontrol_map_response_cb *map_response_cb; } map_response_cb_s; static void *datacontrol_map_tree_root = NULL; static const int MAX_ARGUMENT_SIZE = 16384; // 16KB +static GHashTable *__socket_pair_hash = NULL; -static void -datacontrol_map_call_cb(const char *provider_id, int request_id, datacontrol_request_type type, - const char *data_id, bool provider_result, const char *error, char **result_value_list, int result_value_count, void* data) +static void __map_call_cb(const char *provider_id, int request_id, datacontrol_request_type type, + const char *data_id, bool provider_result, const char *error, char **result_value_list, int result_value_count, void *data) { - LOGI("datacontrol_map_call_cb, dataID: %s", data_id); + LOGI("__map_call_cb, dataID: %s", data_id); datacontrol_map_response_cb *callback = NULL; map_response_cb_s *map_dc = NULL; map_dc = (map_response_cb_s *)data; callback = map_dc->map_response_cb; - if (!callback) - { + if (!callback) { LOGE("no listener set"); return; } @@ -58,76 +58,59 @@ datacontrol_map_call_cb(const char *provider_id, int request_id, datacontrol_req datacontrol_map_set_provider_id(provider, provider_id); datacontrol_map_set_data_id(provider, data_id); - switch (type) + switch (type) { + + case DATACONTROL_TYPE_MAP_GET: { - case DATACONTROL_TYPE_MAP_GET: - { - LOGI("GET VALUE"); - if (callback != NULL && callback->get != NULL) - { - callback->get(request_id, provider, result_value_list, result_value_count, provider_result, error, map_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } + LOGI("GET VALUE"); + if (callback != NULL && callback->get != NULL) + callback->get(request_id, provider, result_value_list, result_value_count, provider_result, error, map_dc->user_data); + else + LOGI("No registered callback function"); - break; - } - case DATACONTROL_TYPE_MAP_SET: - { - LOGI("SET VALUE"); - if (callback != NULL && callback->set != NULL) - { - callback->set(request_id, provider, provider_result, error, map_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } + break; + } + case DATACONTROL_TYPE_MAP_SET: + { + LOGI("SET VALUE"); + if (callback != NULL && callback->set != NULL) + callback->set(request_id, provider, provider_result, error, map_dc->user_data); + else + LOGI("No registered callback function"); - break; - } - case DATACONTROL_TYPE_MAP_ADD: - { - LOGI("ADD VALUE"); - if (callback != NULL && callback->add!= NULL) - { - callback->add(request_id, provider, provider_result, error, map_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } + break; + } + case DATACONTROL_TYPE_MAP_ADD: + { + LOGI("ADD VALUE"); + if (callback != NULL && callback->add != NULL) + callback->add(request_id, provider, provider_result, error, map_dc->user_data); + else + LOGI("No registered callback function"); - break; - } - case DATACONTROL_TYPE_MAP_REMOVE: - { - LOGI("REMOVE VALUE"); - if (callback != NULL && callback->remove != NULL) - { - callback->remove(request_id, provider, provider_result, error, map_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } - break; - } - default: - break; + break; + } + case DATACONTROL_TYPE_MAP_REMOVE: + { + LOGI("REMOVE VALUE"); + if (callback != NULL && callback->remove != NULL) + callback->remove(request_id, provider, provider_result, error, map_dc->user_data); + else + LOGI("No registered callback function"); + + break; + } + default: + break; } datacontrol_map_destroy(provider); } -static void -datacontrol_map_instance_free(void *datacontrol_map_instance) +static void __map_instance_free(void *datacontrol_map_instance) { map_response_cb_s *dc = (map_response_cb_s *)datacontrol_map_instance; - if (dc) - { + if (dc) { free(dc->provider_id); free(dc->data_id); free(dc->app_id); @@ -138,141 +121,120 @@ datacontrol_map_instance_free(void *datacontrol_map_instance) return; } -static int -datacontrol_map_instance_compare(const void *l_datacontrol_map_instance, const void *r_datacontrol_map_instance) +static int __map_instance_compare(const void *l_datacontrol_map_instance, const void *r_datacontrol_map_instance) { map_response_cb_s *dc_left = (map_response_cb_s *)l_datacontrol_map_instance; map_response_cb_s *dc_right = (map_response_cb_s *)r_datacontrol_map_instance; return strcmp(dc_left->provider_id, dc_right->provider_id); } -static char** -datacontrol_map_get_value_list(const char *path, int count) +static char **__map_get_value_list(int fd, int *value_count) { char **value_list = NULL; int i = 0; - int fd = 0; - int ret = 0; + int count = 0; + int nbytes = 0; + unsigned int nb = 0; - value_list = (char **) calloc(count, sizeof(char *)); - if (value_list == NULL) - { - LOGE("Failed to create value list"); + if (_read_socket(fd, (char *)&count, sizeof(count), &nb)) { + LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd); return NULL; } - SECURE_LOGI("The result file of GET: %s", path); - /* TODO - shoud be changed to solve security concerns */ - fd = open(path, O_RDONLY, 0644); - if (fd == -1) - { - SECURE_LOGE("unable to open update_map file: %d", errno); - goto ERROR; + + value_list = (char **)calloc(count, sizeof(char *)); + if (value_list == NULL) { + LOGE("Failed to create value list"); + return NULL; } - while (count) - { - int length = 0; - int size = read(fd, &length, sizeof(int)); - if (size <= 0) - { - SECURE_LOGE("unable to read the result value file: %d", errno); - goto ERROR; + for (i = 0; i < count; i++) { + if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) { + LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd); + goto ERROR; } - value_list[i] = (char *) calloc(length + 1, sizeof(char)); + LOGI("nbytes : %d %d" , nbytes , nb); + value_list[i] = (char *)calloc(nbytes + 1, sizeof(char)); - size = read(fd, value_list[i], length); - if (size <= 0) - { - SECURE_LOGE("unable to read the result value file: %d", errno); - ++i; + if (_read_socket(fd, value_list[i], nbytes, &nb)) { + LOGE("datacontrol_recv_map_get_value_list : ...from %d: fail to read\n", fd); goto ERROR; } - - LOGI("value_list[%d] = %s", i, value_list[i]); - ++i; - --count; - } - - close(fd); - ret = remove(path); - if (ret == -1) - { - SECURE_LOGE("unable to remove the result value file(%s). errno = %d", path, errno); + LOGI("value_list[i] : %s %d" , value_list[i] , nb); } + *value_count = count; return value_list; ERROR: - if (value_list) - { + if (value_list) { int j; - for (j = 0; j < i; j++) - { - free(value_list[j]); + for (j = 0; j < i; j++) { + if (value_list[j] != NULL) + free(value_list[j]); } free(value_list); } - close(fd); - ret = remove(path); - if (ret == -1) - { - SECURE_LOGE("unable to remove the result value file(%s). errno = %d", path, errno); - } return NULL; } -static int -datacontrol_map_handle_cb(bundle* b, int request_code, appsvc_result_val res, void* data) +static void __remove_map_request_info(int request_id, map_response_cb_s *map_dc) +{ + + datacontrol_consumer_request_info temp_request_info; + temp_request_info.request_id = request_id; + GList *list = g_list_find_custom(map_dc->request_info_list, &temp_request_info, + (GCompareFunc)_consumer_request_compare_cb); + if (list != NULL) + map_dc->request_info_list = g_list_remove(map_dc->request_info_list, list->data); + +} + +static int __map_handle_cb(int fd, bundle *b, int request_type, appsvc_result_val res, void *data) { - LOGI("datacontrol_map_handle_cb, request_code: %d, result: %d", request_code, res); + LOGI("__map_handle_cb, request_type: %d", request_type); int ret = 0; - const char** result_list = NULL; - const char* provider_id = NULL; - const char* data_id = NULL; - const char* error_message = NULL; - datacontrol_request_type request_type = 0; + const char **result_list = NULL; + const char *provider_id = NULL; + const char *data_id = NULL; + const char *error_message = NULL; int request_id = -1; int result_list_len = 0; int provider_result = 0; int value_count = 0; - const char* result_path = NULL; - char** value_list = NULL; - const char* p = NULL; + char **value_list = NULL; + const char *p = NULL; + map_response_cb_s *map_dc = (map_response_cb_s *)data; - if (!b) - { + if (!b) { LOGE("the bundle returned from datacontrol-provider-service is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - p = appsvc_get_data(b, OSP_K_REQUEST_ID); - if (!p) - { + p = bundle_get_val(b, OSP_K_REQUEST_ID); + if (!p) { LOGE("Invalid Bundle: request_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; - } - else - { + } else { request_id = atoi(p); } - SECURE_LOGI("Request ID: %d", request_id); + LOGI("Request ID: %d", request_id); + + __remove_map_request_info(request_id, map_dc); // result list - result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len); - if (!result_list) - { + result_list = bundle_get_str_array(b, OSP_K_ARG, &result_list_len); + if (!result_list) { LOGE("Invalid Bundle: arguement list is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } p = result_list[0]; // result list[0] = provider_result - if (!p) - { + if (!p) { LOGE("Invalid Bundle: provider_result is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -282,136 +244,256 @@ datacontrol_map_handle_cb(bundle* b, int request_code, appsvc_result_val res, vo provider_result = atoi(p); error_message = result_list[1]; // result list[1] = error - if (!error_message) - { + if (!error_message) { LOGE("Invalid Bundle: error_message is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } LOGI("Error message: %s", error_message); - p = appsvc_get_data(b, OSP_K_DATACONTROL_REQUEST_TYPE); - if (!p) - { - LOGE("Invalid Bundle: data-control request type is null"); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - - request_type = (datacontrol_request_type)atoi(p); - - provider_id = appsvc_get_data(b, OSP_K_DATACONTROL_PROVIDER); - if (!provider_id) - { + provider_id = bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER); + if (!provider_id) { LOGE("Invalid Bundle: provider_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - data_id = appsvc_get_data(b, OSP_K_DATACONTROL_DATA); - if (!data_id) - { + data_id = bundle_get_val(b, OSP_K_DATACONTROL_DATA); + if (!data_id) { LOGE("Invalid Bundle: data_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type); + LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type); - switch (request_type) + switch (request_type) { + case DATACONTROL_TYPE_MAP_GET: { - case DATACONTROL_TYPE_MAP_GET: - { - LOGI("GET RESPONSE"); - if (provider_result) - { - value_count = atoi(result_list[2]); - result_path = result_list[3]; - if (!result_path) - { - LOGE("map query result path is null"); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - value_list = datacontrol_map_get_value_list(result_path, value_count); + LOGI("GET RESPONSE"); + if (provider_result) { + value_list = __map_get_value_list(fd, &value_count); + + if (value_list == NULL && value_count != 0) { + LOGE("Invalid data: value_list is null"); + return DATACONTROL_ERROR_INVALID_PARAMETER; } - break; } - case DATACONTROL_TYPE_MAP_SET: - case DATACONTROL_TYPE_MAP_ADD: - case DATACONTROL_TYPE_MAP_REMOVE: - { - LOGI("SET or ADD or REMOVE RESPONSE"); - break; - } - - default: - break; + break; } - - if (request_type >= DATACONTROL_TYPE_MAP_GET && request_type <= DATACONTROL_TYPE_MAP_REMOVE) + case DATACONTROL_TYPE_MAP_SET: + case DATACONTROL_TYPE_MAP_ADD: + case DATACONTROL_TYPE_MAP_REMOVE: { - datacontrol_map_call_cb(provider_id, request_id, request_type, data_id, provider_result, error_message, value_list, value_count, data); - ret = DATACONTROL_ERROR_NONE; + LOGI("SET or ADD or REMOVE RESPONSE"); + break; } - else - { - ret = DATACONTROL_ERROR_INVALID_PARAMETER; + default: + break; } + if (request_type >= DATACONTROL_TYPE_MAP_GET && request_type <= DATACONTROL_TYPE_MAP_REMOVE) { + __map_call_cb(provider_id, request_id, request_type, data_id, provider_result, + error_message, value_list, value_count, data); + ret = DATACONTROL_ERROR_NONE; + } else + ret = DATACONTROL_ERROR_INVALID_PARAMETER; + + return ret; } -static void -app_svc_res_cb_map(bundle* b, int request_code, appsvc_result_val res, void* data) +static int __datacontrol_send_map_async(int sockfd, bundle *kb, datacontrol_request_type type, void *data) { - LOGI("app_svc_res_cb_map, request_code: %d, result: %d", request_code, res); - if (data) - { - datacontrol_map_handle_cb(b, request_code, res, data); + LOGI("send async ~~~"); + + bundle_raw *kb_data = NULL; + int ret = DATACONTROL_ERROR_NONE; + int datalen; + char *buf = NULL; + int total_len; + unsigned int nb = 0; + + bundle_encode_raw(kb, &kb_data, &datalen); + if (kb_data == NULL) { + LOGE("bundle encode error"); + return DATACONTROL_ERROR_INVALID_PARAMETER; } - else - { - LOGE("error: listener information is null"); + + // encoded bundle + encoded bundle size + buf = (char *)calloc(datalen + sizeof(datalen), sizeof(char)); + if (buf == NULL) { + LOGE("Malloc failed!!"); + bundle_free_encoded_rawdata(&kb_data); + return DATACONTROL_ERROR_OUT_OF_MEMORY; + } + + memcpy(buf, &datalen, sizeof(datalen)); + memcpy(buf + sizeof(datalen), kb_data, datalen); + + total_len = sizeof(datalen) + datalen; + + LOGI("write : %d", datalen); + if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGI("write data fail"); + ret = DATACONTROL_ERROR_IO_ERROR; } + free(buf); + bundle_free_encoded_rawdata(&kb_data); + return ret; } -static int -datacontrol_map_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *arg_list, int request_id) +static gboolean __recv_map_message(GIOChannel *channel, + GIOCondition cond, + gpointer data) { - SECURE_LOGI("Map Data control request, type: %d, request id: %d", type, request_id); + + gint fd = g_io_channel_unix_get_fd(channel); + gboolean retval = TRUE; + + LOGI("__recv_map_message: ...from %d:%s%s%s%s\n", fd, + (cond & G_IO_ERR) ? " ERR" : "", + (cond & G_IO_HUP) ? " HUP" : "", + (cond & G_IO_IN) ? " IN" : "", + (cond & G_IO_PRI) ? " PRI" : ""); + + if (cond & (G_IO_ERR | G_IO_HUP)) + goto error; + + if (cond & G_IO_IN) { + char *buf; + int nbytes; + guint nb; + int request_type = 0; + const char *request_code = NULL; + + if (_read_socket(fd, (char *)&nbytes, sizeof(nbytes), &nb)) { + LOGE("Fail to read nbytes from socket"); + goto error; + } + LOGI("nbytes : %d", nbytes); + + if (nb == 0) { + LOGE("__recv_map_message: ...from %d: socket closed\n", fd); + goto error; + } + + LOGI("__recv_map_message: ...from %d: %d bytes\n", fd, nbytes); + if (nbytes > 0) { + bundle *kb = NULL; + + buf = (char *) calloc(nbytes + 1, sizeof(char)); + if (buf == NULL) { + LOGE("Malloc failed!!"); + goto error; + } + if (_read_socket(fd, buf, nbytes, &nb)) { + free(buf); + LOGE("Fail to read buf from socket"); + goto error; + } + + if (nb == 0) { + free(buf); + LOGE("__recv_map_message: ...from %d: socket closed\n", fd); + goto error; + } + + kb = bundle_decode_raw((bundle_raw *)buf, nbytes); + if (kb == NULL) { + free(buf); + LOGE("__recv_map_message: Unable to decode the bundle\n"); + goto error; + } + + LOGI("__recv_map_message: ...from %d: OK\n", fd); + LOGI("__recv_map_message: ...caller appid %s: OK\n", bundle_get_val(kb, AUL_K_CALLER_APPID)); + + if (data) { + request_code = bundle_get_val(kb, OSP_K_DATACONTROL_REQUEST_TYPE); + if (!request_code) { + LOGE("Invalid Bundle: data-control request type is null"); + free(buf); + bundle_free(kb); + goto error; + } + request_type = atoi(request_code); + + if (__map_handle_cb(fd, kb, request_type, 0, data) != DATACONTROL_ERROR_NONE) { + free(buf); + bundle_free(kb); + goto error; + } + + } else { + LOGE("error: listener information is null"); + free(buf); + bundle_free(kb); + goto error; + } + free(buf); + bundle_free(kb); + } + } + return retval; +error: + if (((map_response_cb_s *)data) != NULL) { + + map_response_cb_s *map_dc = (map_response_cb_s *)data; + g_hash_table_remove(__socket_pair_hash, map_dc->provider_id); + + GList *itr = g_list_first(map_dc->request_info_list); + while (itr != NULL) { + datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)itr->data; + __map_call_cb(map_dc->provider_id, request_info->request_id, request_info->type, map_dc->data_id, false, + "provider IO Error", NULL, 0, data); + itr = g_list_next(itr); + } + if (map_dc->request_info_list) { + LOGI("free map request_info_list"); + g_list_free_full(map_dc->request_info_list, free); + map_dc->request_info_list = NULL; + } + } + return FALSE; +} + +static int __map_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *request_data, int request_id) +{ + LOGI("Map Data control request, type: %d, request id: %d", type, request_id); char *app_id = NULL; void *data = NULL; + int ret = DATACONTROL_ERROR_NONE; - if (type < DATACONTROL_TYPE_MAP_GET || type > DATACONTROL_TYPE_MAP_REMOVE) - { + if (type < DATACONTROL_TYPE_MAP_GET || type > DATACONTROL_TYPE_MAP_REMOVE) { LOGE("Invalid request type: %d", (int)type); return DATACONTROL_ERROR_INVALID_PARAMETER; } - if (!datacontrol_map_tree_root) - { + if (__socket_pair_hash == NULL) + __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free); + + if (!datacontrol_map_tree_root) { LOGE("The listener tree is empty"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s),1); - if (!map_dc_temp) - { + map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s)); + if (!map_dc_temp) { LOGE("Failed to create map datacontrol"); return DATACONTROL_ERROR_OUT_OF_MEMORY; } map_dc_temp->provider_id = strdup(provider->provider_id); - if (!map_dc_temp->provider_id) - { + if (!map_dc_temp->provider_id) { LOGE("Failed to assign provider id to map data control: %d", errno); free(map_dc_temp); return DATACONTROL_ERROR_OUT_OF_MEMORY; } map_dc_temp->data_id = strdup(provider->data_id); - if (!map_dc_temp->data_id) - { + if (!map_dc_temp->data_id) { LOGE("Failed to assign data id to map data control: %d", errno); free(map_dc_temp->provider_id); free(map_dc_temp); @@ -424,94 +506,88 @@ datacontrol_map_request_provider(datacontrol_h provider, datacontrol_request_typ map_dc_temp->map_response_cb = NULL; void *map_dc_returned = NULL; - map_dc_returned = tfind(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare); + map_dc_returned = tfind(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare); - datacontrol_map_instance_free(map_dc_temp); + __map_instance_free(map_dc_temp); - if (!map_dc_returned) - { + if (!map_dc_returned) { LOGE("Finding the map datacontrol in the listener tree is failed."); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_INVALID_PARAMETER; } map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned; app_id = map_dc->app_id; + datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)calloc(sizeof(datacontrol_consumer_request_info), 1); + request_info->request_id = request_id; + request_info->type = type; + map_dc->request_info_list = g_list_append(map_dc->request_info_list, request_info); data = map_dc; - SECURE_LOGI("Map datacontrol appid: %s", map_dc->app_id); + LOGI("Map datacontrol appid: %s", map_dc->app_id); char caller_app_id[255]; pid_t pid = getpid(); - if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) - { - SECURE_LOGE("Failed to get appid by pid(%d).", pid); + if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) { + LOGE("Failed to get appid by pid(%d).", pid); return DATACONTROL_ERROR_INVALID_PARAMETER; } - appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT); - appsvc_set_appid(arg_list, app_id); - bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP); - bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL); - bundle_add_str(arg_list, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3); - bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_app_id); - bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1"); + bundle_add_str(request_data, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3); + bundle_add_str(request_data, AUL_K_CALLER_APPID, caller_app_id); char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, }; snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type)); - bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation); + bundle_add_str(request_data, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation); - char req_id[32] = {0, }; + char req_id[32] = {0,}; snprintf(req_id, 32, "%d", request_id); - bundle_add_str(arg_list, OSP_K_REQUEST_ID, req_id); + bundle_add_str(request_data, OSP_K_REQUEST_ID, req_id); - // For DataControl CAPI - bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE"); + int count = 0; + const int TRY_COUNT = 2; + const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 }; + LOGI("caller_id %s, app_id %s", caller_app_id, app_id); - SECURE_LOGI("Map data control request - provider id: %s, data id: %s, provider appid: %s, request ID: %s", provider->provider_id, provider->data_id, app_id, req_id); + do { + datacontrol_socket_info *socket_info = g_hash_table_lookup(__socket_pair_hash, provider->provider_id); - pid = -1; - int count = 0; - const int TRY_COUNT = 4; - const int TRY_SLEEP_TIME = 65000; - do - { - pid = appsvc_run_service(arg_list, request_id, app_svc_res_cb_map, data); - if (pid >= 0) - { - SECURE_LOGI("Launch the provider app successfully: %d", pid); - return DATACONTROL_ERROR_NONE; - } - else if (pid == APPSVC_RET_EINVAL) - { - SECURE_LOGE("not able to launch service: %d", pid); - return DATACONTROL_ERROR_INVALID_PARAMETER; + if (socket_info == NULL) { + ret = _request_appsvc_run(caller_app_id, app_id); + if(ret != DATACONTROL_ERROR_NONE) + return ret; + + socket_info = _get_socket_info(caller_app_id, app_id, "consumer", __recv_map_message, data); + if (socket_info == NULL) + return DATACONTROL_ERROR_IO_ERROR; + + g_hash_table_insert(__socket_pair_hash, strdup(provider->provider_id), socket_info); } + LOGI("send data from consumer !!!"); + ret = __datacontrol_send_map_async(socket_info->socket_fd, request_data, type, NULL); + if(ret != DATACONTROL_ERROR_NONE) + g_hash_table_remove(__socket_pair_hash, provider->provider_id); + else + break; count++; + nanosleep(&TRY_SLEEP_TIME, 0); - usleep(TRY_SLEEP_TIME); - } - while (count < TRY_COUNT); + } while (ret != DATACONTROL_ERROR_NONE && count < TRY_COUNT); + + return ret; - SECURE_LOGE("unable to launch service: %d", pid); - return DATACONTROL_ERROR_IO_ERROR; } -int -datacontrol_map_create(datacontrol_h *provider) +int datacontrol_map_create(datacontrol_h *provider) { struct datacontrol_s *request; if (provider == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } request = malloc(sizeof(struct datacontrol_s)); if (request == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } request->provider_id = NULL; request->data_id = NULL; @@ -521,155 +597,114 @@ datacontrol_map_create(datacontrol_h *provider) return 0; } -int -datacontrol_map_destroy(datacontrol_h provider) +int datacontrol_map_destroy(datacontrol_h provider) { if (provider == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->provider_id != NULL) - { free(provider->provider_id); - } if (provider->data_id != NULL) - { free(provider->data_id); - } free(provider); return 0; } -int -datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id) +int datacontrol_map_set_provider_id(datacontrol_h provider, const char *provider_id) { if (provider == NULL || provider_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->provider_id != NULL) - { free(provider->provider_id); - } provider->provider_id = strdup(provider_id); if (provider->provider_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } return 0; } -int -datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id) +int datacontrol_map_get_provider_id(datacontrol_h provider, char **provider_id) { if (provider == NULL || provider_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (provider->provider_id != NULL) - { + if (provider->provider_id != NULL) { *provider_id = strdup(provider->provider_id); if (*provider_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } - } - else - { + + } else *provider_id = NULL; - } return 0; } -int -datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id) +int datacontrol_map_set_data_id(datacontrol_h provider, const char *data_id) { if (provider == NULL || data_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->data_id != NULL) - { free(provider->data_id); - } provider->data_id = strdup(data_id); if (provider->data_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } return 0; } -int -datacontrol_map_get_data_id(datacontrol_h provider, char **data_id) +int datacontrol_map_get_data_id(datacontrol_h provider, char **data_id) { if (provider == NULL || data_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (provider->data_id != NULL) - { + if (provider->data_id != NULL) { *data_id = strdup(provider->data_id); if (*data_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } - } - else - { + + } else *data_id = NULL; - } + return 0; } -int -datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb* callback, void *user_data) +int datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_response_cb *callback, void *user_data) { int ret = 0; - char* app_id = NULL; - char* access = NULL; + char *app_id = NULL; + char *access = NULL; ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Map", getuid(), &app_id, &access); - if (ret != PMINFO_R_OK) - { + if (ret != PMINFO_R_OK) { LOGE("unable to get map data control information: %d", ret); return DATACONTROL_ERROR_IO_ERROR; } - SECURE_LOGI("data control provider appid = %s", app_id); + LOGI("data control provider appid = %s", app_id); - map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s), 1); - if (!map_dc_temp) - { + map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s)); + if (!map_dc_temp) { LOGE("unable to create a temporary map data control"); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } map_dc_temp->provider_id = strdup(provider->provider_id); - if (!map_dc_temp->provider_id) - { + if (!map_dc_temp->provider_id) { LOGE("unable to assign provider_id to map data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } map_dc_temp->data_id = strdup(provider->data_id); - if (!map_dc_temp->data_id) - { + if (!map_dc_temp->data_id) { LOGE("unable to assign data_id to map data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; @@ -681,15 +716,14 @@ datacontrol_map_register_response_cb(datacontrol_h provider, datacontrol_map_res map_dc_temp->map_response_cb = callback; void *map_dc_returned = NULL; - map_dc_returned = tsearch(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare); + map_dc_returned = tsearch(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare); map_response_cb_s *map_dc = *(map_response_cb_s **)map_dc_returned; - if (map_dc != map_dc_temp) - { + if (map_dc != map_dc_temp) { map_dc->map_response_cb = callback; map_dc->user_data = user_data; LOGI("the data control is already set"); - datacontrol_map_instance_free(map_dc_temp); + __map_instance_free(map_dc_temp); } return DATACONTROL_ERROR_NONE; @@ -699,8 +733,7 @@ EXCEPTION: free(access); if (app_id) free(app_id); - if (map_dc_temp) - { + if (map_dc_temp) { if (map_dc_temp->provider_id) free(map_dc_temp->provider_id); if (map_dc_temp->data_id) @@ -711,23 +744,21 @@ EXCEPTION: return ret; } -int -datacontrol_map_unregister_response_cb(datacontrol_h provider) +int datacontrol_map_unregister_response_cb(datacontrol_h provider) { int ret = DATACONTROL_ERROR_NONE; - map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(sizeof(map_response_cb_s),1); + map_response_cb_s *map_dc_temp = (map_response_cb_s *)calloc(1, sizeof(map_response_cb_s)); + g_hash_table_remove(__socket_pair_hash, provider->provider_id); - if (!map_dc_temp) - { + if (!map_dc_temp) { LOGE("unable to create a temporary map data control"); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } map_dc_temp->provider_id = strdup(provider->provider_id); - if (!map_dc_temp->provider_id) - { + if (!map_dc_temp->provider_id) { LOGE("unable to assign provider_id to map data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; @@ -735,9 +766,8 @@ datacontrol_map_unregister_response_cb(datacontrol_h provider) void *map_dc_returned = NULL; - map_dc_returned = tdelete(map_dc_temp, &datacontrol_map_tree_root, datacontrol_map_instance_compare); - if (map_dc_returned == NULL) - { + map_dc_returned = tdelete(map_dc_temp, &datacontrol_map_tree_root, __map_instance_compare); + if (map_dc_returned == NULL) { LOGE("invalid parameter"); ret = DATACONTROL_ERROR_INVALID_PARAMETER; goto EXCEPTION; @@ -745,8 +775,7 @@ datacontrol_map_unregister_response_cb(datacontrol_h provider) EXCEPTION: - if (map_dc_temp) - { + if (map_dc_temp) { if (map_dc_temp->provider_id) free(map_dc_temp->provider_id); free(map_dc_temp); @@ -755,61 +784,54 @@ EXCEPTION: return ret; } -int -datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id) +int datacontrol_map_get(datacontrol_h provider, const char *key, int *request_id) { return datacontrol_map_get_with_page(provider, key, request_id, 1, 20); } -int -datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page) +int datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *request_id, int page_number, int count_per_page) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL) - { + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Gets the value list from provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); + LOGI("Gets the value list from provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); long long arg_size = (strlen(provider->data_id) + strlen(key)) * sizeof(wchar_t); - if (arg_size > MAX_ARGUMENT_SIZE) - { + if (arg_size > MAX_ARGUMENT_SIZE) { LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size); return DATACONTROL_ERROR_MAX_EXCEEDED; } int ret = 0; bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_INVALID_PARAMETER; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); - const char* arg_list[4]; + const char *arg_list[4]; arg_list[0] = provider->data_id; arg_list[1] = key; char page_no_str[32] = {0, }; ret = snprintf(page_no_str, 32, "%d", page_number); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert page no to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } char count_per_page_str[32] = {0, }; ret = snprintf(count_per_page_str, 32, "%d", count_per_page); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert count per page no to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } arg_list[2] = page_no_str; @@ -821,41 +843,37 @@ datacontrol_map_get_with_page(datacontrol_h provider, const char *key, int *requ int reqId = _datacontrol_create_request_id(); *request_id = reqId; - ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_GET, b, reqId); + ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_GET, b, reqId); bundle_free(b); return ret; } -int -datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id) +int datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_value, const char *new_value, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || old_value == NULL || new_value == NULL) - { + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || old_value == NULL || new_value == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Sets the old value to new value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); + LOGI("Sets the old value to new value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(old_value) + strlen(new_value)) * sizeof(wchar_t); - if (arg_size > MAX_ARGUMENT_SIZE) - { + if (arg_size > MAX_ARGUMENT_SIZE) { LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size); return DATACONTROL_ERROR_MAX_EXCEEDED; } bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); - const char* arg_list[4]; + const char *arg_list[4]; arg_list[0] = provider->data_id; arg_list[1] = key; arg_list[2] = old_value; @@ -867,41 +885,37 @@ datacontrol_map_set(datacontrol_h provider, const char *key, const char *old_val int reqId = _datacontrol_create_request_id(); *request_id = reqId; - int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_SET, b, reqId); + int ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_SET, b, reqId); bundle_free(b); return ret; } -int -datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id) +int datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) - { + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Adds the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); + LOGI("Adds the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t); - if (arg_size > MAX_ARGUMENT_SIZE) - { + if (arg_size > MAX_ARGUMENT_SIZE) { LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size); return DATACONTROL_ERROR_MAX_EXCEEDED; } bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); - const char* arg_list[3]; + const char *arg_list[3]; arg_list[0] = provider->data_id; arg_list[1] = key; arg_list[2] = value; @@ -912,41 +926,37 @@ datacontrol_map_add(datacontrol_h provider, const char *key, const char *value, int reqId = _datacontrol_create_request_id(); *request_id = reqId; - int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_ADD, b, reqId); + int ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_ADD, b, reqId); bundle_free(b); return ret; } -int -datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id) +int datacontrol_map_remove(datacontrol_h provider, const char *key, const char *value, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) - { + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || key == NULL || value == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Removes the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); + LOGI("Removes the value in provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); long long arg_size = (strlen(provider->data_id) + strlen(key) + strlen(value)) * sizeof(wchar_t); - if (arg_size > MAX_ARGUMENT_SIZE) - { + if (arg_size > MAX_ARGUMENT_SIZE) { LOGE("The size of sending argument (%lld) exceeds the maximum limit.", arg_size); return DATACONTROL_ERROR_MAX_EXCEEDED; } bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); - const char* arg_list[3]; + const char *arg_list[3]; arg_list[0] = provider->data_id; arg_list[1] = key; arg_list[2] = value; @@ -957,7 +967,7 @@ datacontrol_map_remove(datacontrol_h provider, const char *key, const char *valu int reqId = _datacontrol_create_request_id(); *request_id = reqId; - int ret = datacontrol_map_request_provider(provider, DATACONTROL_TYPE_MAP_REMOVE, b, reqId); + int ret = __map_request_provider(provider, DATACONTROL_TYPE_MAP_REMOVE, b, reqId); bundle_free(b); return ret; diff --git a/src/data-control-provider.c b/src/data-control-provider.c old mode 100644 new mode 100755 index 4c71e8d..16b8fb2 --- a/src/data-control-provider.c +++ b/src/data-control-provider.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,7 @@ #include "data-control-internal.h" #define ROW_ID_SIZE 32 -#define RESULT_PATH_MAX 512 +#define RESULT_PATH_MAX 512 #define RESULT_PAGE_NUMBER "RESULT_PAGE_NUMBER" #define MAX_COUNT_PER_PAGE "MAX_COUNT_PER_PAGE" @@ -39,7 +40,7 @@ #define PACKET_INDEX_COLUMNCOUNT 1 #define PACKET_INDEX_MAP 2 -#define PACKET_INDEX_UPDATEWHERE 3 +#define PACKET_INDEX_UPDATEWHERE 2 #define PACKET_INDEX_DELETEWHERE 1 #define PACKET_INDEX_MAP_KEY 1 @@ -48,7 +49,8 @@ #define PACKET_INDEX_MAP_PAGE_NO 2 #define PACKET_INDEX_MAP_COUNT_PER_PAGE 3 -static GHashTable *request_table = NULL; +static GHashTable *__request_table = NULL; +static GHashTable *__socket_pair_hash = NULL; //static pthread_mutex_t provider_lock = PTHREAD_MUTEX_INITIALIZER; @@ -58,649 +60,553 @@ struct datacontrol_s { }; -typedef int (*provider_handler_cb) (bundle * b, int request_id, void *data); +typedef int (*provider_handler_cb) (bundle *b, int request_id, void *data); -static datacontrol_provider_sql_cb* provider_sql_cb = NULL; -static datacontrol_provider_map_cb* provider_map_cb = NULL; -static void* provider_map_user_data = NULL; -static void* provider_sql_user_data = NULL; +static datacontrol_provider_sql_cb *provider_sql_cb = NULL; +static datacontrol_provider_map_cb *provider_map_cb = NULL; +static void *provider_map_user_data = NULL; +static void *provider_sql_user_data = NULL; -static void -__free_data(gpointer data) +static void __free_data(gpointer data) { - if (data) - { + if (data) { free(data); data = NULL; } } -static void -__initialize_provider(void) +static void __initialize_provider(void) { - request_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_data, __free_data); + __request_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_data, __free_data); + __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free); } -static int -__provider_new_request_id(void) +static int __provider_new_request_id(void) { static int id = 0; - g_atomic_int_inc(&id); - return id; } -static char* -__get_client_pkgid(bundle *b) -{ - const char *caller_appid = NULL; - char *caller_pkgid = NULL; - pkgmgrinfo_appinfo_h app_info_handle = NULL; - - caller_appid = bundle_get_val(b, AUL_K_CALLER_APPID); - pkgmgrinfo_appinfo_get_usr_appinfo(caller_appid, getuid(), &app_info_handle); - pkgmgrinfo_appinfo_get_pkgname(app_info_handle, &caller_pkgid); - SECURE_LOGI("client pkg id : %s", caller_pkgid); - - return caller_pkgid ? strdup(caller_pkgid) : NULL; -} - -static bundle* -__get_data_sql(const char *path, int column_count) +static int __send_select_result(int fd, bundle *b, void *data) { - bundle* b = bundle_create(); - - int len = 0; - int i = 0; - size_t size = 0; - char *key = NULL; - char *value = NULL; - int fd = 0; - int ret = 0; - - SECURE_LOGI("The request file of INSERT/UPDATE: %s", path); - - /* TODO - shoud be changed to solve security concerns */ - fd = open(path, O_RDONLY, 0644); - if (fd == -1) { - SECURE_LOGE("unable to open insert_map file: %d", errno); - return b; - } - - for (i = 0; i < column_count; i++) - { - size = read(fd, &len, sizeof(int)); - if (size < sizeof(int) || len < 0 || len == INT_MAX) - { - SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size); - break; - } - - key = calloc(len + 1, sizeof(char)); - size = read(fd, key, len); // key - if (size < 0) - { - SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size); - free(key); - break; - } - - size = read(fd, &len, sizeof(int)); - if (size < sizeof(int) || len < 0 || len == INT_MAX) - { - SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size); - free(key); - break; - } - - value = calloc(len + 1, sizeof(char)); - size = read(fd, value, len); // value - if (size < 0) - { - SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size); - free(key); - free(value); - break; - } - - LOGI("key: %s, value: %s", key, value); - - bundle_add_str(b, key, value); - - free(key); - free(value); - } - - fsync(fd); - close(fd); - ret = remove(path); - if (ret == -1) - { - SECURE_LOGE("unable to remove the request file of INSERT/UPDATE(%s). errno = %d", path, errno); - } - - return b; -} -static int -__set_select_result(bundle* b, const char* path, void* data) -{ - LOGI("__set_select_result"); - // The provider application should call the sqlite3_open(). - // and it also should call the sqlite3_prepare_v2() in datacontrol_provider_sql_select_request_cb(). - // and then, it should call the datacontrol_provider_send_select_result() with a pointer to sqlite3_stmt. - // The 3rd param 'data' is the pointer to sqlite3_stmt. + LOGI("__send_select_result"); - // In this function, the result set is written in specified file path as specific form. - // [sizeof(int)] row count + // In this function, the result set is written in socket as specific form. // [sizeof(int)] column count - // [sieeof(int)] total size of column names // [sizeof(int)] column type x N - // [ variant ] column name x N - // [sizeof(int)] type - // [sizeof(int)] size - // [ varient ] content + // [ variant ] (column name leng, column name) x N + // [sieeof(int)] total size of column names + // [sizeof(int)] row count + // [ variant ] (type, size, content) x N - int column_count = 0; + sqlite3_stmt *state = (sqlite3_stmt *)data; + int column_count = DATACONTROL_RESULT_NO_DATA; int i = 0; char *column_name = NULL; int total_len_of_column_names = 0; int count_per_page = 0; - int row_count = 0; - sqlite3_stmt *state = (sqlite3_stmt *)data; - int fd = 0; - char *client_pkgid = NULL; + int page_number = 1; + int offset = 0; + sqlite3_int64 offset_idx = 0; + sqlite3_int64 row_count = 0; + unsigned int nb = 0; - if (b ==NULL || path == NULL || data == NULL) - { + if (b == NULL || data == NULL) { LOGE("The input param is invalid."); return DATACONTROL_ERROR_INVALID_PARAMETER; } - if (sqlite3_reset(state) != SQLITE_OK) - { + if (sqlite3_reset(state) != SQLITE_OK) { LOGE("sqlite3_reset() is failed."); return DATACONTROL_ERROR_INVALID_PARAMETER; } - if (sqlite3_step(state) != SQLITE_ROW) - { + if (sqlite3_step(state) != SQLITE_ROW) { LOGE("The DB does not have another row."); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - - client_pkgid = __get_client_pkgid(b); - - /* TODO - shoud be changed to solve security concerns */ - fd = open(path, O_WRONLY | O_CREAT, 0644); - if (fd == -1) { - SECURE_LOGE("unable to open insert_map file: %d", errno); - free(client_pkgid); - return DATACONTROL_ERROR_IO_ERROR; + if (_write_socket(fd, &column_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("Writing a column_count to a file descriptor is failed."); + return DATACONTROL_ERROR_IO_ERROR; + } + return DATACONTROL_ERROR_NONE; } - free(client_pkgid); // 1. column count column_count = sqlite3_column_count(state); - if (lseek(fd, sizeof(int), SEEK_SET) == -1) - { - LOGE("lseek is failed. errno = %d", errno); - } - if (write(fd, &column_count, sizeof(int)) == -1) - { + if (_write_socket(fd, &column_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; } + LOGI("Writing a column_count %d", column_count); + // 2. column type x column_count // #define SQLITE_INTEGER 1 // #define SQLITE_FLOAT 2 // #define SQLITE_TEXT 3 // #define SQLITE_BLOB 4 // #define SQLITE_NULL 5 - if (lseek(fd, sizeof(int), SEEK_CUR) == -1) - { - LOGE("lseek is failed. errno = %d", errno); - } - - for (i = 0; i < column_count; ++i) - { + for (i = 0; i < column_count; i++) { int type = sqlite3_column_type(state, i); - if (write(fd, &type, sizeof(int)) == -1) - { - LOGE("Writing a type to a file descriptor is failed. errno = %d", errno); + if (_write_socket(fd, &type, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { + LOGI("Writing a type to a file descriptor is failed."); + return DATACONTROL_ERROR_IO_ERROR; } + LOGI("Writing a column_type %d", type); } // 3. column name x column_count - for (i = 0; i < column_count; i++) - { + for (i = 0; i < column_count; i++) { column_name = (char *)sqlite3_column_name(state, i); - column_name = strcat(column_name, "\n"); - if (write(fd, column_name, strlen(column_name)) == -1) - { - LOGE("Writing a column_name to a file descriptor is failed. errno = %d", errno); + if (column_name == NULL) { + LOGI("sqlite3_column_name is failed. errno = %d", errno); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } else { + int column_name_len = strlen(column_name); + if (_write_socket(fd, &column_name_len, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { + LOGI("Writing a column_name_len to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; + } + + LOGI("Writing a column_name_len %d", column_name_len); + + if (_write_socket(fd, column_name, column_name_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGI("Writing a column_name to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; + } + total_len_of_column_names += strlen(column_name); + LOGI("Writing a column_name %s", column_name); } - total_len_of_column_names += strlen(column_name); } // 4. total length of column names - if (lseek(fd, sizeof(int) * 2, SEEK_SET) == -1) - { - LOGE("lseek is failed. errno = %d", errno); - } - if (write(fd, &total_len_of_column_names, sizeof(int)) == -1) - { - LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno); + if (_write_socket(fd, &total_len_of_column_names, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { + LOGI("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; } + + LOGI("Writing a total_len_of_column_names %d", total_len_of_column_names); + + + const char *page_number_str = bundle_get_val(b, RESULT_PAGE_NUMBER); + const char *count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE); + + LOGI("page_number: %s, per_page: %s", page_number_str, count_per_page_str); + // 5. type, size and value of each element - if (lseek(fd, (sizeof(int) * column_count) + total_len_of_column_names, SEEK_CUR) == -1) - { - LOGE("lseek is failed. errno = %d", errno); + if (page_number_str != NULL) + page_number = atoi(page_number_str); + else + page_number = 1; + + if (count_per_page_str != NULL) + count_per_page = atoi(count_per_page_str); + else + count_per_page = 20; + + offset = (page_number - 1) * count_per_page; + + LOGI("page_number: %d, count_per_page: %d, offset: %d", page_number, count_per_page, offset); + + if (sqlite3_reset(state) != SQLITE_OK) { + LOGE("sqlite3_reset() is failed."); + return DATACONTROL_ERROR_INVALID_PARAMETER; } - count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE)); - do - { - for (i = 0; i < column_count; ++i) - { - int type = 0; - int size = 0; - void* value = NULL; - bool is_null_type = false; - int column_type = sqlite3_column_type(state, i); - long long tmp_long = 0; - double tmp_double = 0.0; - switch (column_type) - { + + if (sqlite3_step(state) != SQLITE_ROW) { + LOGE("The DB does not have another row."); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } + do { + offset_idx++; + if (offset_idx > offset) + ++row_count; + } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page); + + // 6. row count + if (_write_socket(fd, &row_count, sizeof(row_count), &nb) != DATACONTROL_ERROR_NONE) { + LOGI("Writing a row_count to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; + } + LOGI("Writing a row_count %d", row_count); + + row_count = 0; + offset_idx = 0; + if (sqlite3_reset(state) != SQLITE_OK) { + LOGI("sqlite3_reset() is failed."); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } + + if (sqlite3_step(state) != SQLITE_ROW) { + LOGE("The DB does not have another row."); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } + do { + offset_idx++; + if (offset_idx > offset) { + ++row_count; + for (i = 0; i < column_count; ++i) { + int type = 0; + int size = 0; + void *value = NULL; + int column_type = sqlite3_column_type(state, i); + long long tmp_long = 0; + double tmp_double = 0.0; + void *buf = NULL; + int buf_len = 0; + switch (column_type) { case SQLITE_INTEGER: - { type = 1; size = sizeof(long long); tmp_long = sqlite3_column_int64(state, i); value = &tmp_long; break; - } case SQLITE_FLOAT: - { type = 2; size = sizeof(double); tmp_double = sqlite3_column_double(state, i); - value =&tmp_double; + value = &tmp_double; break; - } case SQLITE_TEXT: - { type = 3; value = (char *)sqlite3_column_text(state, i); - size = strlen(value); + size = strlen(value) + 1; break; - } case SQLITE_BLOB: - { type = 4; size = sqlite3_column_bytes(state, i); value = (char *)sqlite3_column_blob(state, i); break; - } case SQLITE_NULL: - { type = 5; size = 0; - is_null_type = true; break; - } default: - { - LOGE("The column type is invalid."); + LOGI("The column type is invalid."); break; } - } - if (write(fd, &type, sizeof(int)) == -1) - { - LOGE("Writing a type to a file descriptor is failed. errno = %d", errno); - } - if (write(fd, &size, sizeof(int)) == -1) - { - LOGE("Writing a size to a file descriptor is failed. errno = %d", errno); - } - if (size > 0 && !is_null_type) - { - if (write(fd, value, size) == -1) - { - LOGE("Writing a value to a file descriptor is failed. errno = %d", errno); + if (value == NULL) + return DATACONTROL_ERROR_IO_ERROR; + + buf_len = sizeof(int) * 2 + size; + buf = calloc(buf_len, sizeof(void)); + if (buf == NULL) { + LOGE("calloc failed"); + return DATACONTROL_ERROR_OUT_OF_MEMORY; + } + memcpy(buf, &type, sizeof(int)); + memcpy(buf + sizeof(int), &size, sizeof(int)); + if (size > 0) + memcpy(buf + sizeof(int) + sizeof(int), value, size); + + if (_write_socket(fd, buf, buf_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGE("Writing a size to a file descriptor is failed. errno = %d", errno); + free(buf); + return DATACONTROL_ERROR_IO_ERROR; } + + free(buf); + } - } - ++row_count; - } while(sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page); + LOGI("row_count ~~~~ %d", row_count); - // 6. row count - if (lseek(fd, 0, SEEK_SET) == -1) - { - LOGE("lseek is failed. errno = %d", errno); - } - if (write(fd, &row_count, sizeof(int)) == -1) - { - LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno); - } - close(fd); + } + } while (sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page); return DATACONTROL_ERROR_NONE; } -static int -__set_get_value_result(bundle *b, const char* path, char **value_list) +static int __send_get_value_result(int fd, bundle *b, void *data) { + int i = 0; - int fd = -1; - char *client_pkgid = NULL; + char **value_list = (char **)data; - if (b == NULL || path == NULL || value_list == NULL) - { - LOGE("The input param is invalid."); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } + const char *page_num_str = bundle_get_val(b, RESULT_PAGE_NUMBER); + const char *count_per_page_str = bundle_get_val(b, MAX_COUNT_PER_PAGE); + const char *value_count_str = bundle_get_val(b, RESULT_VALUE_COUNT); - int page_number = atoi(bundle_get_val(b, RESULT_PAGE_NUMBER)); - int count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE)); - int value_count = atoi(bundle_get_val(b, RESULT_VALUE_COUNT)); + LOGI("page num: %s, count_per_page: %s, value_count %s", page_num_str, count_per_page_str, value_count_str); + + int page_number = atoi(page_num_str); + int count_per_page = atoi(count_per_page_str); + int value_count = atoi(value_count_str); int current_offset = (page_number - 1) * count_per_page; int remain_count = value_count - current_offset; + unsigned int nb; + remain_count = (remain_count > 0) ? remain_count : 0; // round off to zero if the negative num is found - int add_value_count = (count_per_page > remain_count) ? remain_count : count_per_page; - if (add_value_count < value_count) - { - bundle_del(b, RESULT_VALUE_COUNT); - char value_count_str[32] = {0,}; - snprintf(value_count_str, 32, "%d", add_value_count); - bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str); - } + int add_value_count = (count_per_page > remain_count) ? remain_count : count_per_page; - if (add_value_count <= 0) - { - LOGI("There is no value list."); - return DATACONTROL_ERROR_NONE; - } + LOGI("add_value_count: %d, current_offset: %d, remain_count %d", add_value_count, current_offset, remain_count); - client_pkgid = __get_client_pkgid(b); - /* TODO - shoud be changed to solve security concerns */ - fd = open(path, O_WRONLY | O_CREAT, 0644); - if (fd == -1) { - SECURE_LOGE("unable to open insert_map file: %d", errno); - free(client_pkgid); + if (_write_socket(fd, &add_value_count, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("Writing a length to a file descriptor is failed. errno = %d", errno); return DATACONTROL_ERROR_IO_ERROR; } - free(client_pkgid); - for (i = 0; i < add_value_count; ++i) - { - int length = strlen(value_list[current_offset + i]); - if (write(fd, &length, sizeof(int)) == -1) - { + add_value_count += current_offset; + + for (i = current_offset; i < add_value_count; i++) { + int length = strlen(value_list[i]); + LOGI("length = %d", length); + if (_write_socket(fd, &length, sizeof(int), &nb) != DATACONTROL_ERROR_NONE) { LOGE("Writing a length to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; } - if (write(fd, value_list[current_offset + i], length) == -1) - { + + LOGI("value_list = %s", value_list[i]); + if (_write_socket(fd, value_list[i], length, &nb) != DATACONTROL_ERROR_NONE) { LOGE("Writing a value_list to a file descriptor is failed. errno = %d", errno); + return DATACONTROL_ERROR_IO_ERROR; } } - - fsync(fd); - close(fd); return DATACONTROL_ERROR_NONE; } -static char* -__get_result_file_path(bundle *b) +int __datacontrol_send_async(int sockfd, bundle *kb, datacontrol_request_type type, void *data) { - LOGI("__get_result_file_path"); - const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID); - if (!caller) - { - LOGE("caller appid is NULL."); - return NULL; + LOGI("send async ~~~"); + + bundle_raw *kb_data = NULL; + int ret = DATACONTROL_ERROR_NONE; + int datalen = 0; + char *buf = NULL; + int total_len = 0; + unsigned int nb = 0; + + bundle_encode_raw(kb, &kb_data, &datalen); + if (kb_data == NULL) { + LOGE("bundle encode error"); + return DATACONTROL_ERROR_OUT_OF_MEMORY; + } + + // encoded bundle + encoded bundle len + buf = (char *)calloc(datalen + 4, sizeof(char)); + memcpy(buf, &datalen, sizeof(datalen)); + memcpy(buf + sizeof(datalen), kb_data, datalen); + + total_len = sizeof(datalen) + datalen; + + LOGI("write : %d", datalen); + if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGI("write data fail "); + ret = DATACONTROL_ERROR_IO_ERROR; + goto out; } - const char *caller_req_id = bundle_get_val(b, OSP_K_REQUEST_ID); + if (DATACONTROL_TYPE_SQL_SELECT == type) + ret = __send_select_result(sockfd, kb, data); + else if (DATACONTROL_TYPE_MAP_GET == type) + ret = __send_get_value_result(sockfd, kb, data); - char *result_path = calloc(RESULT_PATH_MAX, sizeof(char)); - snprintf(result_path, RESULT_PATH_MAX, "%s%s%s", DATACONTROL_RESULT_FILE_PREFIX, caller, caller_req_id); +out: + if (buf) + free(buf); + bundle_free_encoded_rawdata(&kb_data); - SECURE_LOGI("result file path: %s", result_path); + return ret; +} - return result_path; +static bundle *__get_data_sql(int fd) +{ + bundle *b = bundle_create(); + int len = 0; + + int ret = read(fd, &len, sizeof(int)); + if (ret < sizeof(int)) { + LOGE("read error :%d", ret); + if (b) + bundle_free(b); + return NULL; + } + + if (len > 0) { + char *buf = (char *)calloc(len, sizeof(char)); + if (buf == NULL) { + LOGE("calloc fail"); + return NULL; + } + ret = read(fd, buf, len); + b = bundle_decode_raw((bundle_raw *)buf, len); + + if (buf) + free(buf); + } else + LOGE("__get_data_sql read count : %d", len); + + return b; } -static bundle* -__set_result(bundle* b, datacontrol_request_type type, void* data) +static bundle *__set_result(bundle *b, datacontrol_request_type type, void *data) { - bundle* res; - aul_create_result_bundle(b, &res); + + bundle *res = bundle_create(); // Set the type char type_str[MAX_LEN_DATACONTROL_REQ_TYPE] = {0,}; - if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR) - { - char *request_type = (char*)bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE); + + if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR) { + char *request_type = (char *)bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE); strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE); LOGI("type is %s", type_str); - } - else - { + + } else snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type); - } + bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str); // Set the provider id - char *provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER); + char *provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER); bundle_add_str(res, OSP_K_DATACONTROL_PROVIDER, provider_id); // Set the data id - char *data_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_DATA); + char *data_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_DATA); bundle_add_str(res, OSP_K_DATACONTROL_DATA, data_id); // Set the caller request id - char *request_id = (char*)bundle_get_val(b, OSP_K_REQUEST_ID); + char *request_id = (char *)bundle_get_val(b, OSP_K_REQUEST_ID); bundle_add_str(res, OSP_K_REQUEST_ID, request_id); - switch(type) + char *caller_appid = (char *)bundle_get_val(b, AUL_K_CALLER_APPID); + bundle_add_str(res, AUL_K_CALLER_APPID, caller_appid); + + switch (type) { + case DATACONTROL_TYPE_SQL_SELECT: { - case DATACONTROL_TYPE_SQL_SELECT: - { - const char* list[3]; - - list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result - list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - - char *path = __get_result_file_path(b); - if (path != NULL) - { - int ret = __set_select_result(b, path, data); - if (ret < 0) - { - memset(path, 0, RESULT_PATH_MAX); - strcpy(path, "NoResultSet"); - LOGI("Empty ResultSet"); - } - list[PACKET_INDEX_SELECT_RESULT_FILE] = path; - } - else - { - list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY; - } + const char *list[3]; - bundle_add_str_array(res, OSP_K_ARG, list, 3); + list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result + list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; + list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY; - if (path != NULL) - { - free(path); - } + const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER); + const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE); - break; - } + LOGI("page num: %s, count_per_page: %s", page_num, count_per_page); - case DATACONTROL_TYPE_SQL_INSERT: - { - long long row_id = *(long long*)data; + bundle_add_str(res, RESULT_PAGE_NUMBER, page_num); + bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page); - const char* list[3]; - list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result - list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; + bundle_add_str_array(res, OSP_K_ARG, list, 3); - // Set the row value - char row_str[ROW_ID_SIZE] = {0,}; - snprintf(row_str, ROW_ID_SIZE, "%lld", row_id); + break; + } - list[PACKET_INDEX_ROW_ID] = row_str; + case DATACONTROL_TYPE_SQL_INSERT: + { + long long row_id = *(long long *)data; - bundle_add_str_array(res, OSP_K_ARG, list, 3); - break; - } - case DATACONTROL_TYPE_SQL_UPDATE: - case DATACONTROL_TYPE_SQL_DELETE: - { - const char* list[2]; - list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result - list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - - bundle_add_str_array(res, OSP_K_ARG, list, 2); - break; - } - case DATACONTROL_TYPE_MAP_GET: - { - const char* list[4]; - - list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result - list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - - char *path = __get_result_file_path(b); - if (path != NULL) - { - char **value_list = (char **)data; - __set_get_value_result(b, path, value_list); - list[PACKET_INDEX_VALUE_COUNT] = bundle_get_val(b, RESULT_VALUE_COUNT); // value count - list[PACKET_INDEX_GET_RESULT_FILE] = path; - } - else - { - list[PACKET_INDEX_VALUE_COUNT] = 0; // value count - list[PACKET_INDEX_GET_RESULT_FILE] = DATACONTROL_EMPTY; - } + const char *list[3]; + list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result + list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - bundle_add_str_array(res, OSP_K_ARG, list, 4); + // Set the row value + char row_str[ROW_ID_SIZE] = {0,}; + snprintf(row_str, ROW_ID_SIZE, "%lld", row_id); - if (path != NULL) - { - free(path); - } + list[PACKET_INDEX_ROW_ID] = row_str; + bundle_add_str_array(res, OSP_K_ARG, list, 3); + break; + } + case DATACONTROL_TYPE_SQL_UPDATE: + case DATACONTROL_TYPE_SQL_DELETE: + { + const char *list[2]; + list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result + list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - break; - } - case DATACONTROL_TYPE_UNDEFINED: // DATACONTROL_TYPE_MAP_SET || ADD || REMOVE - { - const char* list[2]; - list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result - list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; - - bundle_add_str_array(res, OSP_K_ARG, list, 2); - break; - } - default: // Error - { - const char* list[2]; - list[PACKET_INDEX_REQUEST_RESULT] = "0"; // request result - list[PACKET_INDEX_ERROR_MSG] = (char*)data; // error string - - bundle_add_str_array(res, OSP_K_ARG, list, 2); - break; - } + bundle_add_str_array(res, OSP_K_ARG, list, 2); + break; + } + case DATACONTROL_TYPE_MAP_GET: + { + const char *list[4]; + list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result + list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; + + bundle_add_str_array(res, OSP_K_ARG, list, 2); + const char *page_num = bundle_get_val(b, RESULT_PAGE_NUMBER); + const char *count_per_page = bundle_get_val(b, MAX_COUNT_PER_PAGE); + const char *value_count = bundle_get_val(b, RESULT_VALUE_COUNT); + + bundle_add_str(res, RESULT_PAGE_NUMBER, page_num); + bundle_add_str(res, MAX_COUNT_PER_PAGE, count_per_page); + bundle_add_str(res, RESULT_VALUE_COUNT, value_count); + + break; + } + case DATACONTROL_TYPE_UNDEFINED: // DATACONTROL_TYPE_MAP_SET || ADD || REMOVE + { + const char *list[2]; + list[PACKET_INDEX_REQUEST_RESULT] = "1"; // request result + list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY; + + bundle_add_str_array(res, OSP_K_ARG, list, 2); + break; + } + default: // Error + { + const char *list[2]; + list[PACKET_INDEX_REQUEST_RESULT] = "0"; // request result + list[PACKET_INDEX_ERROR_MSG] = (char *)data; // error string + + bundle_add_str_array(res, OSP_K_ARG, list, 2); + break; + } } return res; } -static int -__send_result(bundle* b, datacontrol_request_type type) +static int __send_result(bundle *b, datacontrol_request_type type, void *data) { - int ret = aul_send_service_result(b); - if (ret < 0) - { - LOGE("Fail to send a result to caller"); + datacontrol_socket_info *socket_info; + char *caller_app_id = (char *)bundle_get_val(b, AUL_K_CALLER_APPID); - int index = 0; + LOGI("__datacontrol_send_async caller_app_id : %s ", caller_app_id); - switch (type) - { - case DATACONTROL_TYPE_SQL_SELECT: - { - index = PACKET_INDEX_SELECT_RESULT_FILE; - break; - } - case DATACONTROL_TYPE_MAP_GET: - { - index = PACKET_INDEX_GET_RESULT_FILE; - break; - } - default: - { - bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; - } - } + socket_info = g_hash_table_lookup(__socket_pair_hash, caller_app_id); + int ret = __datacontrol_send_async(socket_info->socket_fd, b, type, data); - int len = 0; - const char **str_arr = bundle_get_str_array(b, OSP_K_ARG, &len); - SECURE_LOGI("result file: %s (%d)", str_arr[index], index); - ret = remove(str_arr[index]); - if (ret == -1) - { - SECURE_LOGE("unable to remove the result file. errno = %d", errno); - } + LOGI("__datacontrol_send_async result : %d ", ret); - bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; - } + if (ret != DATACONTROL_ERROR_NONE) + g_hash_table_remove(__socket_pair_hash, caller_app_id); bundle_free(b); - return DATACONTROL_ERROR_NONE; + return ret; } -int -__datacontrol_handler_cb(bundle *b, int request_id, void* data) -{ - LOGI("datacontrol_handler_cb"); +int __provider_process(bundle *b, int fd) +{ const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE); - if (request_type == NULL) - { + if (request_type == NULL) { LOGE("Invalid data control request"); return DATACONTROL_ERROR_INVALID_PARAMETER; } // Get the request type datacontrol_request_type type = atoi(request_type); - if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_DELETE) - { - if (provider_sql_cb == NULL) - { + if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_DELETE) { + if (provider_sql_cb == NULL) { LOGE("SQL callback is not registered."); return DATACONTROL_ERROR_INVALID_PARAMETER; } - } - else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_REMOVE) - { - if (provider_map_cb == NULL) - { + + } else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_REMOVE) { + if (provider_map_cb == NULL) { LOGE("Map callback is not registered."); return DATACONTROL_ERROR_INVALID_PARAMETER; } - } - else - { + + } else { LOGE("Invalid requeste type"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -709,209 +615,270 @@ __datacontrol_handler_cb(bundle *b, int request_id, void* data) const char **arg_list = bundle_get_str_array(b, OSP_K_ARG, &len); datacontrol_h provider = malloc(sizeof(struct datacontrol_s)); + if (provider == NULL) { + LOGE("Out of memory. fail to alloc provider."); + return DATACONTROL_ERROR_IO_ERROR; + } // Set the provider ID - provider->provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER); + provider->provider_id = (char *)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER); // Set the data ID - provider->data_id = (char*)arg_list[PACKET_INDEX_DATAID]; + provider->data_id = (char *)arg_list[PACKET_INDEX_DATAID]; // Set the request ID int provider_req_id = __provider_new_request_id(); - SECURE_LOGI("Provider ID: %s, data ID: %s, request type: %s", provider->provider_id, provider->data_id, request_type); + LOGI("Provider ID: %s, data ID: %s, request type: %s", provider->provider_id, provider->data_id, request_type); // Add the data to the table int *key = malloc(sizeof(int)); + if (key == NULL) { + LOGE("Out of memory. fail to malloc key"); + return DATACONTROL_ERROR_IO_ERROR; + } *key = provider_req_id; bundle *value = bundle_dup(b); - g_hash_table_insert(request_table, key, value); + if (value == NULL) { + LOGE("Fail to dup value"); + return DATACONTROL_ERROR_IO_ERROR; + } + g_hash_table_insert(__request_table, key, value); - switch (type) + switch (type) { + case DATACONTROL_TYPE_SQL_SELECT: { - case DATACONTROL_TYPE_SQL_SELECT: - { - int i = 1; - int current = 0; - int column_count = atoi(arg_list[i++]); // Column count - - LOGI("SELECT column count: %d", column_count); + int i = 1; + int current = 0; + int column_count = atoi(arg_list[i++]); // Column count + + LOGI("SELECT column count: %d", column_count); + const char **column_list = (const char **)malloc(column_count * (sizeof(char *))); + if (column_list == NULL) { + LOGE("Out of memory. Fail to malloc column_list."); + return DATACONTROL_ERROR_IO_ERROR; + } - const char** column_list = (const char**)malloc(column_count * (sizeof(char *))); + while (current < column_count) { + column_list[current++] = arg_list[i++]; // Column data + LOGI("Column %d: %s", current, column_list[current-1]); + } - while (current < column_count) - { - column_list[current++] = arg_list[i++]; // Column data + const char *where = arg_list[i++]; // where + const char *order = arg_list[i++]; // order + LOGI("where: %s, order: %s", where, order); - LOGI("Column %d: %s", current, column_list[current-1]); - } + if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) + where = NULL; - const char *where = arg_list[i++]; // where - const char *order = arg_list[i++]; // order + if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) + order = NULL; - LOGI("where: %s, order: %s", where, order); + const char *page_number = arg_list[i++]; + const char *per_page = arg_list[i]; - if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) - { - where = NULL; - } + LOGI("page_number: %s, per_page: %s", page_number, per_page); + bundle_add_str(value, RESULT_PAGE_NUMBER, page_number); + bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page); + provider_sql_cb->select(provider_req_id, provider, column_list, column_count, where, order, provider_sql_user_data); + free(column_list); + break; + } + case DATACONTROL_TYPE_SQL_INSERT: + case DATACONTROL_TYPE_SQL_UPDATE: + { + LOGI("INSERT / UPDATE handler"); + bundle *sql = __get_data_sql(fd); + if (sql == NULL) + return DATACONTROL_ERROR_IO_ERROR; + if (type == DATACONTROL_TYPE_SQL_INSERT) + provider_sql_cb->insert(provider_req_id, provider, sql, provider_sql_user_data); + else { + const char *where = arg_list[PACKET_INDEX_UPDATEWHERE]; + LOGI("UPDATE from where: %s", where); + if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) + where = NULL; + provider_sql_cb->update(provider_req_id, provider, sql, where, provider_sql_user_data); + } + bundle_free(sql); + break; + } + case DATACONTROL_TYPE_SQL_DELETE: + { + const char *where = arg_list[PACKET_INDEX_DELETEWHERE]; + LOGI("DELETE from where: %s", where); + if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) + where = NULL; + provider_sql_cb->delete(provider_req_id, provider, where, provider_sql_user_data); + break; + } + case DATACONTROL_TYPE_MAP_GET: + { + const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; + const char *page_number = arg_list[PACKET_INDEX_MAP_PAGE_NO]; + const char *count_per_page = arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE]; + bundle_add_str(value, RESULT_PAGE_NUMBER, page_number); + bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page); + LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key); + provider_map_cb->get(provider_req_id, provider, map_key, provider_map_user_data); + break; + } + case DATACONTROL_TYPE_MAP_SET: + { + const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; + const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; + const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND]; + LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value); + provider_map_cb->set(provider_req_id, provider, map_key, old_value, new_value, provider_map_user_data); + break; + } + case DATACONTROL_TYPE_MAP_ADD: + { + const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; + const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; + LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value); + provider_map_cb->add(provider_req_id, provider, map_key, map_value, provider_map_user_data); + break; + } + case DATACONTROL_TYPE_MAP_REMOVE: + { + const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; + const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; + LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value); + provider_map_cb->remove(provider_req_id, provider, map_key, map_value, provider_map_user_data); + break; + } + default: + break; + } - if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) - { - order = NULL; - } + free(provider); - const char *page_number = arg_list[i++]; - const char *per_page = arg_list[i]; + return DATACONTROL_ERROR_NONE; +} - bundle_add_str(value, RESULT_PAGE_NUMBER, page_number); - bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page); +gboolean __provider_recv_message(GIOChannel *channel, + GIOCondition cond, + gpointer data) { - char *statement = _datacontrol_create_select_statement(provider->data_id, column_list, column_count, where, order, atoi(page_number), atoi(per_page)); + gint fd = g_io_channel_unix_get_fd(channel); + gboolean retval = TRUE; - // Add a select statement to the bundle - bundle_add_str(value, DATACONTROL_SELECT_STATEMENT, statement); + LOGI("__provider_recv_message : ...from %d:%s%s%s%s\n", fd, + (cond & G_IO_ERR) ? " ERR" : "", + (cond & G_IO_HUP) ? " HUP" : "", + (cond & G_IO_IN) ? " IN" : "", + (cond & G_IO_PRI) ? " PRI" : ""); - free(statement); + if (cond & (G_IO_ERR | G_IO_HUP)) + goto error; - provider_sql_cb->select(provider_req_id, provider, column_list, column_count, where, order, provider_sql_user_data); + if (cond & G_IO_IN) { + char *buf; + int data_len; + guint nb; - free(column_list); + if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail : data_len"); + goto error; + } - break; - } - case DATACONTROL_TYPE_SQL_INSERT: - case DATACONTROL_TYPE_SQL_UPDATE: - { - int column_count = atoi(arg_list[PACKET_INDEX_COLUMNCOUNT]); - const char *sql_path = arg_list[PACKET_INDEX_MAP]; + LOGI("data_len : %d", data_len); - LOGI("INSERT / UPDATE handler"); - SECURE_LOGI("Data path: %s, Column count: %d", sql_path, column_count); + if (nb == 0) { + LOGI("__provider_recv_message : ...from %d: EOF\n", fd); + goto error; + } - bundle* sql = __get_data_sql(sql_path, column_count); + LOGI("__provider_recv_message: ...from %d: %d bytes\n", fd, data_len); + if (data_len > 0) { + bundle *kb = NULL; - if (type == DATACONTROL_TYPE_SQL_INSERT) - { - SECURE_LOGI("INSERT column count: %d, sql_path: %s", column_count, sql_path); - provider_sql_cb->insert(provider_req_id, provider, sql, provider_sql_user_data); - } - else - { - const char *where = arg_list[PACKET_INDEX_UPDATEWHERE]; - LOGI("UPDATE from where: %s", where); - - if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) - { - where = NULL; - } - provider_sql_cb->update(provider_req_id, provider, sql, where, provider_sql_user_data); - } + buf = (char *) calloc(data_len + 1, sizeof(char)); + if (buf == NULL) { + LOGE("calloc failed"); + goto error; + } - bundle_free(sql); - break; + if (_read_socket(fd, buf, data_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGI("read socket fail : data_len\n"); + goto error; } - case DATACONTROL_TYPE_SQL_DELETE: - { - const char *where = arg_list[PACKET_INDEX_DELETEWHERE]; - - LOGI("DELETE from where: %s", where); - if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0) - { - where = NULL; - } - provider_sql_cb->delete(provider_req_id, provider, where, provider_sql_user_data); - break; + + if (nb == 0) { + LOGI("__provider_recv_message: nb 0 : EOF\n"); + free(buf); + goto error; } - case DATACONTROL_TYPE_MAP_GET: - { - const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; - const char *page_number= arg_list[PACKET_INDEX_MAP_PAGE_NO]; - const char *count_per_page = arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE]; - bundle_add_str(value, RESULT_PAGE_NUMBER, page_number); - bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page); - - LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key); - - provider_map_cb->get(provider_req_id, provider, map_key, provider_map_user_data); - break; + + kb = bundle_decode_raw((bundle_raw *)buf, data_len); + free(buf); + if (__provider_process(kb, fd) != DATACONTROL_ERROR_NONE) { + bundle_free(kb); + goto error; } - case DATACONTROL_TYPE_MAP_SET: - { - const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; - const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; - const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND]; + bundle_free(kb); + } + } + return retval; +error: + if (((char *)data) != NULL) + g_hash_table_remove(__socket_pair_hash, (char *)data); - LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value); + return FALSE; +} - provider_map_cb->set(provider_req_id, provider, map_key, old_value, new_value, provider_map_user_data); - break; - } - case DATACONTROL_TYPE_MAP_ADD: - { - const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; - const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; +int __datacontrol_handler_cb(bundle *b, int request_id, void *data) +{ + LOGI("datacontrol_handler_cb"); + datacontrol_socket_info *socket_info; - LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value); + char *caller = (char *)bundle_get_val(b, AUL_K_CALLER_APPID); + char *callee = (char *)bundle_get_val(b, AUL_K_CALLEE_APPID); - provider_map_cb->add(provider_req_id, provider, map_key, map_value, provider_map_user_data); - break; - } - case DATACONTROL_TYPE_MAP_REMOVE: - { - const char *map_key = arg_list[PACKET_INDEX_MAP_KEY]; - const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST]; + socket_info = g_hash_table_lookup(__socket_pair_hash, caller); - LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value); + if (socket_info != NULL) + g_hash_table_remove(__socket_pair_hash, caller); - provider_map_cb->remove(provider_req_id, provider, map_key, map_value, provider_map_user_data); - break; - } - default: - break; - } + socket_info = _get_socket_info(caller, callee, "provider", __provider_recv_message, caller); + if (socket_info == NULL) + return DATACONTROL_ERROR_IO_ERROR; - free(provider); + g_hash_table_insert(__socket_pair_hash, strdup(caller), socket_info); return DATACONTROL_ERROR_NONE; } -int -datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data) +int datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data) { int ret = DATACONTROL_ERROR_NONE; if (callback == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } LOGI("datacontrol_provider_sql_register_cb"); provider_sql_cb = callback; provider_sql_user_data = user_data; - if (provider_map_cb == NULL) // If the provider_map_cb was registered(not NULL), __datacontrol_handler_cb is set already. - { + // If the provider_map_cb was registered(not NULL), __datacontrol_handler_cb is set already. + if (provider_map_cb == NULL) ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb); - } return ret; } -int -datacontrol_provider_sql_unregister_cb(void) +int datacontrol_provider_sql_unregister_cb(void) { - if (provider_map_cb == NULL) // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. - { + // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. + if (provider_map_cb == NULL) aul_unset_data_control_provider_cb(); - } + provider_sql_cb = NULL; provider_sql_user_data = NULL; @@ -923,215 +890,176 @@ int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, int ret = DATACONTROL_ERROR_NONE; if (callback == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } LOGI("datacontrol_provider_map_register_cb"); provider_map_cb = callback; provider_map_user_data = user_data; - if (provider_sql_cb == NULL) // If the provider_sql_cb was registered(not NULL), __datacontrol_handler_cb is set already. - { + // If the provider_sql_cb was registered(not NULL), __datacontrol_handler_cb is set already. + if (provider_sql_cb == NULL) ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb); - } return ret; } int datacontrol_provider_map_unregister_cb(void) { - if (provider_sql_cb == NULL) // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. - { + // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible. + if (provider_sql_cb == NULL) aul_unset_data_control_provider_cb(); - } + provider_map_cb = NULL; provider_map_user_data = NULL; return DATACONTROL_ERROR_NONE; } -int -datacontrol_provider_get_client_appid(int request_id, char **appid) +int datacontrol_provider_get_client_appid(int request_id, char **appid) { - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID); - if (!caller) - { - SECURE_LOGE("No appid for the request id: %d", request_id); + if (!caller) { + LOGE("No appid for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Request ID: %d, caller appid: %s", request_id, caller); + LOGI("Request ID: %d, caller appid: %s", request_id, caller); *appid = strdup(caller); return DATACONTROL_ERROR_NONE; } -int -datacontrol_provider_send_select_result(int request_id, void *db_handle) +int datacontrol_provider_send_select_result(int request_id, void *db_handle) { - SECURE_LOGI("Send a select result for request id: %d", request_id); + LOGI("Send a select result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle); - - return __send_result(res, DATACONTROL_TYPE_SQL_SELECT); + bundle *res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle); + return __send_result(res, DATACONTROL_TYPE_SQL_SELECT, db_handle); } -int -datacontrol_provider_send_insert_result(int request_id, long long row_id) +int datacontrol_provider_send_insert_result(int request_id, long long row_id) { - SECURE_LOGI("Send an insert result for request id: %d", request_id); + LOGI("Send an insert result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void*)&row_id); + bundle *res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void *)&row_id); - return __send_result(res, DATACONTROL_TYPE_SQL_INSERT); + return __send_result(res, DATACONTROL_TYPE_SQL_INSERT, NULL); } -int -datacontrol_provider_send_update_result(int request_id) +int datacontrol_provider_send_update_result(int request_id) { - SECURE_LOGI("Send an update result for request id: %d", request_id); + LOGI("Send an update result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL); + bundle *res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL); - return __send_result(res, DATACONTROL_TYPE_SQL_UPDATE); + return __send_result(res, DATACONTROL_TYPE_SQL_UPDATE, NULL); } -int -datacontrol_provider_send_delete_result(int request_id) +int datacontrol_provider_send_delete_result(int request_id) { - SECURE_LOGI("Send a delete result for request id: %d", request_id); + LOGI("Send a delete result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL); + bundle *res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL); - return __send_result(res, DATACONTROL_TYPE_SQL_DELETE); + return __send_result(res, DATACONTROL_TYPE_SQL_DELETE, NULL); } -int -datacontrol_provider_send_error(int request_id, const char *error) +int datacontrol_provider_send_error(int request_id, const char *error) { - SECURE_LOGI("Send an error for request id: %d", request_id); + LOGI("Send an error for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_ERROR, (void*)error); + bundle *res = __set_result(b, DATACONTROL_TYPE_ERROR, (void *)error); - return __send_result(res, DATACONTROL_TYPE_ERROR); + return __send_result(res, DATACONTROL_TYPE_ERROR, NULL); } -int -datacontrol_provider_send_map_result(int request_id) +int datacontrol_provider_send_map_result(int request_id) { - SECURE_LOGI("Send a set/add/remove result for request id: %d", request_id); + LOGI("Send a set/add/remove result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } - bundle* res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL); + bundle *res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL); - return __send_result(res, DATACONTROL_TYPE_UNDEFINED); + return __send_result(res, DATACONTROL_TYPE_UNDEFINED, NULL); } -int -datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count) +int datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count) { - SECURE_LOGI("Send a get result for request id: %d", request_id); + LOGI("Send a get result for request id: %d", request_id); - if (request_table == NULL) - { + if (__request_table == NULL) __initialize_provider(); - } - bundle* b = g_hash_table_lookup(request_table, &request_id); - if (!b) - { - SECURE_LOGE("No data for the request id: %d", request_id); + bundle *b = g_hash_table_lookup(__request_table, &request_id); + if (!b) { + LOGE("No data for the request id: %d", request_id); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -1139,7 +1067,7 @@ datacontrol_provider_send_map_get_value_result(int request_id, char **value_list snprintf(value_count_str, 32, "%d", value_count); bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str); - bundle* res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list); + bundle *res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list); - return __send_result(res, DATACONTROL_TYPE_MAP_GET); + return __send_result(res, DATACONTROL_TYPE_MAP_GET, value_list); } diff --git a/src/data-control-sql-cursor.c b/src/data-control-sql-cursor.c old mode 100644 new mode 100755 index f09aa34..81a7587 --- a/src/data-control-sql-cursor.c +++ b/src/data-control-sql-cursor.c @@ -14,157 +14,37 @@ #define LOG_TAG "DATA_CONTROL" #endif -static int *row_offset_list = NULL; +#define MAX_ROW_COUNT 1024 -resultset_cursor* datacontrol_sql_get_cursor(const char * path) +resultset_cursor *datacontrol_sql_get_cursor() { - resultset_cursor *cursor = (resultset_cursor *)calloc(sizeof(resultset_cursor), 1); - if (!cursor) - { + resultset_cursor *cursor = (resultset_cursor *)calloc(1, sizeof(resultset_cursor)); + if (!cursor) { LOGE("unable to create cursor"); return NULL; } - - cursor->resultset_row_count = 0; - cursor->resultset_col_count = 0; - cursor->resultset_col_type_offset = 0; - cursor->resultset_col_name_offset = 0; - cursor->resultset_content_offset = 0; - cursor->resultset_current_offset = 0; - cursor->resultset_current_row_count = 0; - /* TODO - shoud be changed to solve security concerns */ - cursor->resultset_fd = open(path, O_RDONLY, 0644); - if (cursor->resultset_fd == -1) - { - SECURE_LOGE("unable to open resultset file(%s): %d", path, errno); - goto EXCEPTION; - } - - cursor->resultset_path = strdup(path); - if (!cursor->resultset_path) - { - SECURE_LOGE("unable to assign path to resultset file: %d", errno); - close(cursor->resultset_fd); - goto EXCEPTION; - } - return cursor; -EXCEPTION: - free(cursor); - return NULL; } int datacontrol_sql_step_next(resultset_cursor *cursor) { - int total_col_name_size = 0; - int ret = 0; - int fd = cursor->resultset_fd; - if (cursor->resultset_current_offset == 0) - { - ret = lseek(fd, 0, SEEK_SET); - if (ret < 0) - { - LOGE("unable to seek to beginning in the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - ret = read(fd, &(cursor->resultset_row_count), sizeof(int)); - if (ret <= 0) - { - LOGE("unable to read the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - ret = read(fd, &(cursor->resultset_col_count), sizeof(int)); - if (ret <= 0) - { - LOGE("unable to read the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - ret = read(fd, &(total_col_name_size), sizeof(int)); - if (ret <= 0) - { - LOGE("unable to read the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - cursor->resultset_col_type_offset = sizeof(int) * 3; - cursor->resultset_col_name_offset = cursor->resultset_col_type_offset + (cursor->resultset_col_count) * sizeof(int); - cursor->resultset_content_offset = cursor->resultset_col_name_offset + total_col_name_size; + if (cursor == NULL || cursor->resultset_row_count == 0) { + LOGE("Reached to the end of the result set"); + return DATACONTROL_ERROR_IO_ERROR; + } + if (cursor->resultset_current_offset == 0) cursor->resultset_current_offset = cursor->resultset_content_offset; - - row_offset_list = (int *)malloc((cursor->resultset_row_count) * (sizeof(int))); - if (!row_offset_list) - { - LOGE("unable to create row_offset_list"); - return DATACONTROL_ERROR_OUT_OF_MEMORY; - } - - int counter = 0; - for (counter = 0; counter < cursor->resultset_row_count; counter++) - { - row_offset_list[counter] = 0; - } - row_offset_list[cursor->resultset_current_row_count] = cursor->resultset_current_offset; - } - else - { - if (!(cursor->resultset_current_row_count < (cursor->resultset_row_count -1))) - { + else { + if (!(cursor->resultset_current_row_count < (cursor->resultset_row_count - 1))) { LOGE("Reached to the end of the result set"); return DATACONTROL_ERROR_IO_ERROR; } - ret = row_offset_list[cursor->resultset_current_row_count + 1]; - if (ret == 0) // Move to next offset - { - int size = 0; - int i = 0; - - ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { - LOGE("unable to seek in the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - for (i = 0; i < cursor->resultset_col_count; i++) - { - ret = lseek(fd, sizeof(int), SEEK_CUR); - if (ret < 0) - { - LOGE("unable to seek in the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { - LOGE("unable to read the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { - LOGE("unable to seek in the resultset file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - cursor->resultset_current_offset += sizeof(int) * 2 + size; - } - - row_offset_list[cursor->resultset_current_row_count + 1] = cursor->resultset_current_offset; - } - else - { - cursor->resultset_current_offset = row_offset_list[cursor->resultset_current_row_count + 1]; - } + cursor->resultset_current_offset = + cursor->row_offset_list[cursor->resultset_current_row_count + 1]; cursor->resultset_current_row_count++; - } return DATACONTROL_ERROR_NONE; } @@ -172,39 +52,26 @@ int datacontrol_sql_step_next(resultset_cursor *cursor) int datacontrol_sql_step_last(resultset_cursor *cursor) { int ret = 0; - if (cursor->resultset_current_row_count == (cursor->resultset_row_count - 1)) - { return DATACONTROL_ERROR_NONE; // Already @ last row - } - if (!row_offset_list) - { + if (!cursor->row_offset_list) { ret = datacontrol_sql_step_next(cursor); // make a first move if (ret != DATACONTROL_ERROR_NONE) - { return ret; - } } // check if the rowOffsetList contains last row offset - if (row_offset_list && row_offset_list[cursor->resultset_row_count - 1] != 0) - { - cursor->resultset_current_offset = row_offset_list[cursor->resultset_row_count - 1]; + if (cursor->row_offset_list && cursor->row_offset_list[cursor->resultset_row_count - 1] != 0) { + cursor->resultset_current_offset = cursor->row_offset_list[cursor->resultset_row_count - 1]; cursor->resultset_current_row_count = cursor->resultset_row_count - 1; - } - else - { + } else { int i = 0; // Move till last row offset. - for (i = (cursor->resultset_current_row_count + 1); i < cursor->resultset_row_count; i++) - { + for (i = (cursor->resultset_current_row_count + 1); i < cursor->resultset_row_count; i++) { ret = datacontrol_sql_step_next(cursor); // move till last row data offset if (ret != DATACONTROL_ERROR_NONE) - { return ret; - } - } } @@ -214,8 +81,7 @@ int datacontrol_sql_step_last(resultset_cursor *cursor) int datacontrol_sql_step_first(resultset_cursor *cursor) { - if (cursor->resultset_current_offset > 0) - { + if (cursor->resultset_current_offset > 0) { cursor->resultset_current_offset = cursor->resultset_content_offset; cursor->resultset_current_row_count = 0; return DATACONTROL_ERROR_NONE; @@ -229,12 +95,11 @@ int datacontrol_sql_step_first(resultset_cursor *cursor) int datacontrol_sql_step_previous(resultset_cursor *cursor) { - if ((cursor->resultset_current_row_count - 1) < 0) - { + if ((cursor->resultset_current_row_count - 1) < 0) { LOGE("invalid request"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - cursor->resultset_current_offset = row_offset_list[cursor->resultset_current_row_count - 1]; + cursor->resultset_current_offset = cursor->row_offset_list[cursor->resultset_current_row_count - 1]; cursor->resultset_current_row_count--; return DATACONTROL_ERROR_NONE; @@ -252,24 +117,20 @@ int datacontrol_sql_get_column_name(resultset_cursor *cursor, int column_index, int i = 0; int ret = 0; FILE *fp = fdopen(dup(cursor->resultset_fd), "r"); - if (fp == NULL) - { + if (fp == NULL) { LOGE("unable to open resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = fseek(fp, cursor->resultset_col_name_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); fclose(fp); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index + 1; i++) - { - if (!(fgets(col_name, 4096, fp))) - { + for (i = 0; i < column_index + 1; i++) { + if (!(fgets(col_name, 4096, fp))) { LOGE("unable to read a line in the resultset file: %s", strerror(errno)); fclose(fp); return DATACONTROL_ERROR_IO_ERROR; @@ -296,46 +157,41 @@ int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_in int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { - LOGE("unable to seek in the resultset file: %s", strerror(errno)); + if (ret < 0) { + LOGE("unable to seek in the resultset file: %d %s", cursor->resultset_current_offset, + strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } @@ -344,7 +200,8 @@ int datacontrol_sql_get_column_item_size(resultset_cursor *cursor, int column_in } -int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index, datacontrol_sql_column_type* col_type) +int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_index, + datacontrol_sql_column_type *col_type) { int type = -1; int i = 0; @@ -354,45 +211,39 @@ int datacontrol_sql_get_column_item_type(resultset_cursor *cursor, int column_in int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - switch (type) - { + switch (type) { case DATACONTROL_SQL_COLUMN_TYPE_INT64: *col_type = DATACONTROL_SQL_COLUMN_TYPE_INT64; break; @@ -432,64 +283,55 @@ int datacontrol_sql_get_blob_data(resultset_cursor *cursor, int column_index, vo int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_BLOB) - { + if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_BLOB) { LOGE("type mismatch: requested for BLOB type but %d present:", type); return DATACONTROL_ERROR_INVALID_PARAMETER; } ret = read(fd, &size, sizeof(int)); - if (size > data_size) - { + if (size > data_size) { LOGE("size is more than the size requested"); return DATACONTROL_ERROR_MAX_EXCEEDED; //overflow } - if (size > 0) - { - char *data = (char*)malloc((size + 1) * (sizeof(char))); + if (size > 0) { + char *data = (char *)malloc((size + 1) * (sizeof(char))); memset(data, 0, size + 1); ret = read(fd, data, size); - if (ret < size) - { + if (ret < size) { LOGE("unable to read in the resultset file: %s", strerror(errno)); free(data); return DATACONTROL_ERROR_IO_ERROR; @@ -509,9 +351,7 @@ int datacontrol_sql_get_int_data(resultset_cursor *cursor, int column_index, int ret = datacontrol_sql_get_int64_data(cursor, column_index, &long_value); if (ret == 0) - { *data = (int) long_value; - } return ret; } @@ -527,59 +367,51 @@ int datacontrol_sql_get_int64_data(resultset_cursor *cursor, int column_index, l int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_INT64) - { + if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_INT64) { LOGE("type mismatch: requested for int type but %d present:", type); return DATACONTROL_ERROR_INVALID_PARAMETER; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, data, size); - if (ret < size) - { + if (ret < size) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } @@ -597,59 +429,51 @@ int datacontrol_sql_get_double_data(resultset_cursor *cursor, int column_index, int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_DOUBLE) - { + if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_DOUBLE) { LOGE("type mismatch: requested for double type but %d present:", type); return DATACONTROL_ERROR_INVALID_PARAMETER; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, data, size); - if (ret < size) - { + if (ret < size) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } @@ -668,69 +492,60 @@ int datacontrol_sql_get_text_data(resultset_cursor *cursor, int column_index, ch int fd = cursor->resultset_fd; ret = lseek(fd, cursor->resultset_current_offset, SEEK_SET); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - for (i = 0; i < column_index; i++) // move to column index - { + // move to column index + for (i = 0; i < column_index; i++) { ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } ret = lseek(fd, size, SEEK_CUR); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to seek in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } } ret = read(fd, &type, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_TEXT) - { - LOGE("type mismatch: requested for text type but %d present:", type); + if (type != (int)DATACONTROL_SQL_COLUMN_TYPE_TEXT) { + LOGE("type mismatch: requested for text type but %d present %d", type, + cursor->resultset_current_offset); return DATACONTROL_ERROR_INVALID_PARAMETER; } ret = read(fd, &size, sizeof(int)); - if (ret == 0) - { + if (ret == 0) { LOGE("unable to read in the resultset file: %s", strerror(errno)); return DATACONTROL_ERROR_IO_ERROR; } - if (size > 0) - { - char *data = (char*)malloc((size + 1) * (sizeof(char))); - if(!data) - { + if (size > 0) { + char *data = (char *)malloc((size + 1) * (sizeof(char))); + if(!data) { LOGE("unable to create buffer to read"); return DATACONTROL_ERROR_OUT_OF_MEMORY; } memset(data, 0, size + 1); ret = read(fd, data, size); - if (ret < size) - { + if (ret < size) { LOGE("unable to read in the resultset file: %s", strerror(errno)); free(data); return DATACONTROL_ERROR_IO_ERROR; @@ -750,15 +565,14 @@ int datacontrol_sql_remove_cursor(resultset_cursor *cursor) int ret = remove(cursor->resultset_path); if (ret == -1) - { LOGE("unable to remove map query result file: %d", ret); - } - - free(row_offset_list); - row_offset_list = 0; - free(cursor->resultset_path); - free(cursor); + if (cursor->row_offset_list) + free(cursor->row_offset_list); + if (cursor->resultset_path) + free(cursor->resultset_path); + if (cursor) + free(cursor); return DATACONTROL_ERROR_NONE; } diff --git a/src/data-control-sql.c b/src/data-control-sql.c old mode 100644 new mode 100755 index 35a4ac0..cb48862 --- a/src/data-control-sql.c +++ b/src/data-control-sql.c @@ -10,6 +10,10 @@ #include #include +#include + +#include + #include #include #include @@ -18,7 +22,7 @@ #include "data-control-sql.h" #include "data-control-internal.h" -#define REQUEST_PATH_MAX 512 +#define REQUEST_PATH_MAX 512 #define MAX_REQUEST_ARGUMENT_SIZE 1048576 // 1MB struct datacontrol_s { @@ -26,32 +30,30 @@ struct datacontrol_s { char *data_id; }; -typedef struct -{ - char *provider_id; - char *app_id; - char *data_id; - char *access_info; - void *user_data; - datacontrol_sql_response_cb *sql_response_cb; +typedef struct { + char *provider_id; + char *app_id; + char *data_id; + char *access_info; + void *user_data; + GList *request_info_list; + datacontrol_sql_response_cb *sql_response_cb; } sql_response_cb_s; - static void *datacontrol_sql_tree_root = NULL; +static GHashTable *__socket_pair_hash = NULL; -static void -datacontrol_sql_call_cb(const char *provider_id, int request_id, datacontrol_request_type type - , const char *data_id, bool provider_result, const char *error, long long insert_rowid, resultset_cursor* cursor, void* data) +static void __sql_call_cb(const char *provider_id, int request_id, datacontrol_request_type type, + const char *data_id, bool provider_result, const char *error, long long insert_rowid, resultset_cursor *cursor, void *data) { - SECURE_LOGI("datacontrol_sql_call_cb, dataID: %s", data_id); + LOGI("__sql_call_cb, dataID !!!: %s", data_id); datacontrol_sql_response_cb *callback = NULL; sql_response_cb_s *sql_dc = NULL; sql_dc = (sql_response_cb_s *)data; callback = sql_dc->sql_response_cb; - if (!callback) - { + if (!callback) { LOGE("no listener set"); return; } @@ -62,76 +64,56 @@ datacontrol_sql_call_cb(const char *provider_id, int request_id, datacontrol_req datacontrol_sql_set_provider_id(provider, provider_id); datacontrol_sql_set_data_id(provider, data_id); - switch (type) + switch (type) { + case DATACONTROL_TYPE_SQL_SELECT: { - case DATACONTROL_TYPE_SQL_SELECT: - { - LOGI("SELECT"); - if (callback != NULL && callback->select != NULL) - { - callback->select(request_id, provider, cursor, provider_result, error, sql_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } - - break; - } - case DATACONTROL_TYPE_SQL_INSERT: - { - SECURE_LOGI("INSERT row_id: %lld", insert_rowid); - if (callback != NULL && callback->insert != NULL) - { - callback->insert(request_id, provider, insert_rowid, provider_result, error, sql_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } + LOGI("SELECT"); + if (callback != NULL && callback->select != NULL) + callback->select(request_id, provider, cursor, provider_result, error, sql_dc->user_data); + else + LOGI("No registered callback function"); - break; - } - case DATACONTROL_TYPE_SQL_UPDATE: - { - LOGI("UPDATE"); - if (callback != NULL && callback->update != NULL) - { - callback->update(request_id, provider, provider_result, error, sql_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } + break; + } + case DATACONTROL_TYPE_SQL_INSERT: + { + LOGI("INSERT row_id: %lld", insert_rowid); + if (callback != NULL && callback->insert != NULL) + callback->insert(request_id, provider, insert_rowid, provider_result, error, sql_dc->user_data); + else + LOGI("No registered callback function"); - break; - } - case DATACONTROL_TYPE_SQL_DELETE: - { - LOGI("DELETE"); - if (callback != NULL && callback->delete != NULL) - { - callback->delete(request_id, provider, provider_result, error, sql_dc->user_data); - } - else - { - LOGI("No registered callback function"); - } - break; - } - default: - break; + break; + } + case DATACONTROL_TYPE_SQL_UPDATE: + { + LOGI("UPDATE"); + if (callback != NULL && callback->update != NULL) + callback->update(request_id, provider, provider_result, error, sql_dc->user_data); + else + LOGI("No registered callback function"); + break; + } + case DATACONTROL_TYPE_SQL_DELETE: + { + LOGI("DELETE"); + if (callback != NULL && callback->delete != NULL) + callback->delete(request_id, provider, provider_result, error, sql_dc->user_data); + else + LOGI("No registered callback function"); + break; + } + default: + break; } datacontrol_sql_destroy(provider); } -static void -datacontrol_sql_instance_free(void *datacontrol_sql_instance) +static void __sql_instance_free(void *datacontrol_sql_instance) { sql_response_cb_s *dc = (sql_response_cb_s *)datacontrol_sql_instance; - if (dc) - { + if (dc) { free(dc->provider_id); free(dc->data_id); free(dc->app_id); @@ -142,60 +124,62 @@ datacontrol_sql_instance_free(void *datacontrol_sql_instance) return; } -static int -datacontrol_sql_instance_compare(const void *l_datacontrol_sql_instance, const void *r_datacontrol_sql_instance) +static int __sql_instance_compare(const void *l_datacontrol_sql_instance, const void *r_datacontrol_sql_instance) { sql_response_cb_s *dc_left = (sql_response_cb_s *)l_datacontrol_sql_instance; sql_response_cb_s *dc_right = (sql_response_cb_s *)r_datacontrol_sql_instance; return strcmp(dc_left->provider_id, dc_right->provider_id); } - -static int -datacontrol_sql_handle_cb(bundle* b, int request_code, appsvc_result_val res, void* data) +static void __remove_sql_request_info(int request_id, sql_response_cb_s *sql_dc) { - SECURE_LOGI("datacontrol_sql_handle_cb, request_code: %d, result: %d", request_code, res); + datacontrol_consumer_request_info temp_request_info; + temp_request_info.request_id = request_id; + GList *list = g_list_find_custom(sql_dc->request_info_list, &temp_request_info, + (GCompareFunc)_consumer_request_compare_cb); + if (list != NULL) + sql_dc->request_info_list = g_list_remove(sql_dc->request_info_list, list->data); + +} + +static int __sql_handle_cb(bundle *b, void *data, resultset_cursor *cursor) +{ int ret = 0; - const char** result_list = NULL; - resultset_cursor *cursor = NULL; - const char* provider_id = NULL; - const char* data_id = NULL; - const char* error_message = NULL; + const char **result_list = NULL; + const char *provider_id = NULL; + const char *data_id = NULL; + const char *error_message = NULL; long long insert_rowid = -1; datacontrol_request_type request_type = 0; int request_id = -1; int result_list_len = 0; int provider_result = 0; - const char* resultset_path = NULL; - const char* p = NULL; + const char *p = NULL; + sql_response_cb_s *sql_dc = (sql_response_cb_s *)data; - if (b) - { + if (b) { p = appsvc_get_data(b, OSP_K_REQUEST_ID); - if (!p) - { + if (!p) { LOGE("Invalid Bundle: request_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; - } - else - { + + } else request_id = atoi(p); - } - SECURE_LOGI("Request ID: %d", request_id); + LOGI("Request ID: %d", request_id); + + __remove_sql_request_info(request_id, sql_dc); // result list result_list = appsvc_get_data_array(b, OSP_K_ARG, &result_list_len); - if (!result_list) - { + if (!result_list) { LOGE("Invalid Bundle: arguement list is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } p = result_list[0]; // result list[0] = provider_result - if (!p) - { + if (!p) { LOGE("Invalid Bundle: provider_result is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -205,8 +189,7 @@ datacontrol_sql_handle_cb(bundle* b, int request_code, appsvc_result_val res, vo provider_result = atoi(p); error_message = result_list[1]; // result list[1] = error - if (!error_message) - { + if (!error_message) { LOGE("Invalid Bundle: error_message is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -214,8 +197,7 @@ datacontrol_sql_handle_cb(bundle* b, int request_code, appsvc_result_val res, vo LOGI("Error message: %s", error_message); p = appsvc_get_data(b, OSP_K_DATACONTROL_REQUEST_TYPE); - if (!p) - { + if (!p) { LOGE("Invalid Bundle: data-control request type is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -223,157 +205,517 @@ datacontrol_sql_handle_cb(bundle* b, int request_code, appsvc_result_val res, vo request_type = (datacontrol_request_type)atoi(p); provider_id = appsvc_get_data(b, OSP_K_DATACONTROL_PROVIDER); - if (!provider_id) - { + if (!provider_id) { LOGE("Invalid Bundle: provider_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } data_id = appsvc_get_data(b, OSP_K_DATACONTROL_DATA); - if (!data_id) - { + if (!data_id) { LOGE("Invalid Bundle: data_id is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type); + LOGI("Provider ID: %s, Data ID: %s, Operation type: %d", provider_id, data_id, request_type); - switch (request_type) + switch (request_type) { + + case DATACONTROL_TYPE_SQL_INSERT: { - case DATACONTROL_TYPE_SQL_SELECT: - { - LOGI("SELECT RESPONSE"); - if (provider_result) - { - resultset_path = result_list[2]; // result list[2] - if (!resultset_path) - { - LOGE("sql query result path is null"); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - - SECURE_LOGI("resultset_path: %s", resultset_path); - - if (strcmp(resultset_path, "NoResultSet") != 0) // Result set exists - { - cursor = datacontrol_sql_get_cursor(resultset_path); - if (!cursor) - { - LOGE("failed to get cursor on sql query resultset"); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - } - } - break; - } - case DATACONTROL_TYPE_SQL_INSERT: - { - LOGI("INSERT RESPONSE"); - if (provider_result) - { - p = result_list[2]; // result list[2] - if (!p) - { - LOGE("Invalid Bundle: insert row_id is null"); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - - insert_rowid = atoll(p); + LOGI("INSERT RESPONSE"); + if (provider_result) { + p = result_list[2]; // result list[2] + if (!p) { + LOGE("Invalid Bundle: insert row_id is null"); + return DATACONTROL_ERROR_INVALID_PARAMETER; } - break; - } - case DATACONTROL_TYPE_SQL_UPDATE: - case DATACONTROL_TYPE_SQL_DELETE: - { - LOGI("UPDATE or DELETE RESPONSE"); - break; - } - default: - break; + insert_rowid = atoll(p); + } + break; + } + case DATACONTROL_TYPE_SQL_UPDATE: + case DATACONTROL_TYPE_SQL_DELETE: + { + LOGI("UPDATE or DELETE RESPONSE"); + break; + } + default: + break; } - } - else - { + } else { LOGE("the bundle returned from datacontrol-provider-service is null"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - if (request_type >= DATACONTROL_TYPE_SQL_SELECT && request_type <= DATACONTROL_TYPE_SQL_DELETE) - { - datacontrol_sql_call_cb(provider_id, request_id, request_type, data_id, provider_result, error_message, insert_rowid, cursor, data); + if (request_type >= DATACONTROL_TYPE_SQL_SELECT && request_type <= DATACONTROL_TYPE_SQL_DELETE) { + + __sql_call_cb(provider_id, request_id, request_type, data_id, provider_result, error_message, insert_rowid, cursor, data); + if ((request_type == DATACONTROL_TYPE_SQL_SELECT) && (cursor)) - { datacontrol_sql_remove_cursor(cursor); - } ret = DATACONTROL_ERROR_NONE; - } - else - { + + } else ret = DATACONTROL_ERROR_INVALID_PARAMETER; - } return ret; } -static void -app_svc_res_cb_sql(bundle* b, int request_code, appsvc_result_val res, void* data) +static int __recv_sql_select_process(bundle *kb, int fd, resultset_cursor *cursor) { - LOGI("app_svc_res_cb_sql, request_code: %d, result: %d", request_code, res); - if (data) - { - datacontrol_sql_handle_cb(b, request_code, res, data); + int column_count = 0; + int column_type = 0; + int column_name_len = 0; + char *column_name = NULL; + int total_len_of_column_names = 0; + sqlite3_int64 row_count = 0; + int type; + int size; + void *value = NULL; + sqlite3_int64 i = 0; + int j = 0; + char select_map_file[REQUEST_PATH_MAX] = {0,}; + char *req_id = (char *)bundle_get_val(kb, OSP_K_REQUEST_ID); + int result_fd = 0; + guint nb; + int retval = DATACONTROL_ERROR_NONE; + + LOGI("req_id : %s", req_id); + LOGI("SELECT RESPONSE"); + + size = snprintf(select_map_file, REQUEST_PATH_MAX, "%s%s%s", DATACONTROL_REQUEST_FILE_PREFIX, + (char *)bundle_get_val(kb, AUL_K_CALLER_APPID), req_id); + if (size < 0) { + LOGE("unable to write formatted output to select_map_file. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + LOGI("select_map_file : %s", select_map_file); + + /* TODO - shoud be changed to solve security concerns */ + result_fd = open(select_map_file, O_RDWR | O_CREAT, 0644); + if (result_fd == -1) { + LOGE("unable to open insert_map file: %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + + } + cursor->resultset_path = strdup(select_map_file); + if (cursor->resultset_path == NULL) { + LOGE("Out of memory. can not dup select map file."); + return DATACONTROL_ERROR_IO_ERROR; } - else - { - LOGE("error: listener information is null"); + cursor->resultset_fd = result_fd; + if (_read_socket(fd, (char *)&column_count, sizeof(column_count), &nb) != DATACONTROL_ERROR_NONE) { + retval = DATACONTROL_ERROR_IO_ERROR; + LOGE("read socket fail: column_count"); + goto out; + } + + cursor->resultset_col_count = column_count; + LOGI("column_count : %d", column_count); + // no data check. + if (column_count == DATACONTROL_RESULT_NO_DATA) { + LOGE("No result"); + return DATACONTROL_ERROR_NONE; } + + if (write(result_fd, &column_count, sizeof(int)) == -1) { + LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + cursor->resultset_col_type_offset = sizeof(int); + for (i = 0; i < column_count; i++) { + if (_read_socket(fd, (char *)&column_type, sizeof(column_type), &nb) != DATACONTROL_ERROR_NONE) { + retval = DATACONTROL_ERROR_IO_ERROR; + LOGE("read socket fail: column_type"); + goto out; + } + + LOGE("column_type : %d", column_type); + if (write(result_fd, &column_type, sizeof(int)) == -1) { + LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + + } + } + + cursor->resultset_col_name_offset = cursor->resultset_col_type_offset + + (cursor->resultset_col_count) * sizeof(int); + for (i = 0; i < column_count; i++) { + + if (_read_socket(fd, (char *)&column_name_len, sizeof(column_name_len), &nb) + != DATACONTROL_ERROR_NONE) { + retval = DATACONTROL_ERROR_IO_ERROR; + LOGE("read socket fail: column_name_len"); + goto out; + } + + LOGE("column_name_len : %d", column_name_len); + if (write(result_fd, &column_name_len, sizeof(int)) == -1) { + LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + column_name = (char *)calloc(column_name_len, sizeof(char)); + if (column_name == NULL) { + LOGE("Out of memory."); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + if (_read_socket(fd, (char *)column_name, column_name_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: column_name"); + free(column_name); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + column_name[column_name_len - 1] = '\0'; + LOGE("column_name read : %d", nb); + LOGE("column_name : %s", column_name); + if (write(result_fd, column_name, column_name_len) == -1) { + LOGE("Writing a column_type to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + free(column_name); + goto out; + } + + free(column_name); + + } + + if (_read_socket(fd, (char *)&total_len_of_column_names, sizeof(total_len_of_column_names), &nb) + != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: total_len_of_column_names"); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + LOGE("total_len_of_column_names : %d", total_len_of_column_names); + if (write(result_fd, &total_len_of_column_names, sizeof(int)) == -1) { + LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + if (_read_socket(fd, (char *)&row_count, sizeof(row_count), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: row_count"); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + LOGE("row_count : %d", row_count); + if (write(result_fd, &row_count, sizeof(int)) == -1) { + LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + cursor->resultset_row_count = row_count; + cursor->row_offset_list = (off_t *)calloc(row_count, sizeof(int)); + if (cursor->row_offset_list == NULL) { + LOGE("Out of memory. can not alloc row_offset_list."); + goto out; + } + + cursor->row_offset_list[0] = lseek(result_fd, 0, SEEK_CUR); + cursor->resultset_content_offset = cursor->row_offset_list[0]; + + LOGE("resultset_content_offset : %d", cursor->resultset_content_offset); + + sqlite3_int64 row_offset = 0; + for (i = 0; i < row_count; i++) { + row_offset = 0; + for (j = 0; j < column_count; j++) { + if (_read_socket(fd, (char *)&type, sizeof(type), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: type"); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + LOGE("type : %d", type); + if (write(result_fd, &type, sizeof(int)) == -1) { + LOGE("Writing a type to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + if (_read_socket(fd, (char *)&size, sizeof(size), &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: size"); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + LOGE("size : %d", size); + if (write(result_fd, &size, sizeof(int)) == -1) { + LOGE("Writing a size to a file descriptor is failed. errno = %d", errno); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + if (size > 0) { + value = (void *) malloc(sizeof(void) * size); + if (value == NULL) { + LOGE("Out of mememory"); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + if (_read_socket(fd, (char *)value, size, &nb) != DATACONTROL_ERROR_NONE) { + LOGE("read socket fail: value"); + free(value); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + LOGE("value : %s", value); + if (write(result_fd, value, sizeof(void) * size) == -1) { + LOGE("Writing a value to a file descriptor is failed. errno = %d", errno); + free(value); + retval = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + + free(value); + + } + row_offset += sizeof(int) * 2 + size; + + } + if (i + 1 < row_count) + cursor->row_offset_list[i + 1] = cursor->row_offset_list[i] + row_offset; + } + return retval; + +out: + if (column_name) + free(column_name); + if (value) + free(value); + + datacontrol_sql_remove_cursor(cursor); + return retval; + } +static gboolean __consumer_recv_sql_message(GIOChannel *channel, + GIOCondition cond, + gpointer data) { + + gint fd = g_io_channel_unix_get_fd(channel); + gboolean retval = TRUE; + resultset_cursor *cursor = NULL; + char *buf = NULL; + + LOGI("__consumer_recv_sql_message: ...from %d:%s%s%s%s\n", fd, + (cond & G_IO_ERR) ? " ERR" : "", + (cond & G_IO_HUP) ? " HUP" : "", + (cond & G_IO_IN) ? " IN" : "", + (cond & G_IO_PRI) ? " PRI" : ""); + + if (cond & (G_IO_ERR | G_IO_HUP)) + goto error; + + if (cond & G_IO_IN) { + int data_len; + guint nb; + datacontrol_request_type request_type = 0; + const char *p = NULL; + + if (_read_socket(fd, (char *)&data_len, sizeof(data_len), &nb) != DATACONTROL_ERROR_NONE) + goto error; + LOGI("data_len : %d", data_len); + + if (nb == 0) { + LOGE("__consumer_recv_sql_message: ...from %d: EOF\n", fd); + goto error; + } + if (data_len > 0) { + bundle *kb = NULL; + buf = (char *) calloc(data_len + 1, sizeof(char)); + if (buf == NULL) { + LOGE("Out of memory."); + goto error; + } + + if (_read_socket(fd, buf, data_len, &nb) != DATACONTROL_ERROR_NONE) { + + LOGE("Out of memory."); + goto error; + } + + if (nb == 0) { + LOGE("__consumer_recv_sql_message: ...from %d: EOF\n", fd); + goto error; + } + + kb = bundle_decode_raw((bundle_raw *)buf, data_len); + LOGE("__consumer_recv_sql_message: ...from %d: OK\n", fd); + if (buf) + free(buf); -static int -datacontrol_sql_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *arg_list, int request_id) + p = bundle_get_val(kb, OSP_K_DATACONTROL_REQUEST_TYPE); + if (!p) { + LOGE("Invalid Bundle: data-control request type is null"); + goto error; + } + LOGI("request_type : %s", p); + request_type = (datacontrol_request_type)atoi(p); + if (request_type == DATACONTROL_TYPE_SQL_SELECT) { + cursor = datacontrol_sql_get_cursor(); + if (!cursor) { + LOGE("failed to get cursor on sql query resultset"); + goto error; + } + if (__recv_sql_select_process(kb, fd, cursor) + != DATACONTROL_ERROR_NONE) + goto error; + } + + if (__sql_handle_cb(kb, data, cursor) + != DATACONTROL_ERROR_NONE) + goto error; + } + + } + return retval; + +error: + if (buf) + free(buf); + + if(((sql_response_cb_s *)data) != NULL) { + LOGE("g_hash_table_remove"); + g_hash_table_remove(__socket_pair_hash, ((sql_response_cb_s *)data)->provider_id); + + sql_response_cb_s *sql_dc = (sql_response_cb_s *)data; + g_hash_table_remove(__socket_pair_hash, sql_dc->provider_id); + + GList *itr = g_list_first(sql_dc->request_info_list); + while(itr != NULL) { + datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)itr->data; + __sql_call_cb(sql_dc->provider_id, request_info->request_id, request_info->type, sql_dc->data_id, false, + "provider IO Error", -1, NULL, data); + itr = g_list_next(itr); + } + if (sql_dc->request_info_list) { + LOGE("free sql request_info_list"); + g_list_free_full(sql_dc->request_info_list, free); + sql_dc->request_info_list = NULL; + } + } + + return FALSE; +} + +int __datacontrol_send_sql_async(int sockfd, bundle *kb, bundle *extra_kb, datacontrol_request_type type, void *data) +{ + + LOGE("send async ~~~"); + bundle_raw *kb_data = NULL; + bundle_raw *extra_kb_data = NULL; + int ret = DATACONTROL_ERROR_NONE; + int datalen = 0; + int extra_datalen = 0; + char *buf = NULL; + int total_len = 0; + unsigned int nb = 0; + + bundle_encode_raw(kb, &kb_data, &datalen); + if (kb_data == NULL) { + LOGE("bundle encode error"); + return DATACONTROL_ERROR_INVALID_PARAMETER; + } + + if (DATACONTROL_TYPE_SQL_INSERT == type || + DATACONTROL_TYPE_SQL_UPDATE == type) { + bundle_encode_raw(extra_kb, &extra_kb_data, &extra_datalen); + if (extra_kb_data == NULL) { + LOGE("bundle encode error"); + goto out; + } + } + + total_len = sizeof(datalen) + datalen + sizeof(extra_datalen) + extra_datalen; + + // encoded bundle + encoded bundle size + buf = (char *)calloc(total_len, sizeof(char)); + if (buf == NULL) { + bundle_free_encoded_rawdata(&kb_data); + LOGE("Out of memory."); + goto out; + } + + memcpy(buf, &datalen, sizeof(datalen)); + memcpy(buf + sizeof(datalen), kb_data, datalen); + + if(extra_datalen > 0) { + memcpy(buf + sizeof(datalen) + datalen, &extra_datalen, sizeof(extra_datalen)); + memcpy(buf + sizeof(datalen) + datalen + sizeof(extra_datalen), extra_kb_data, extra_datalen); + } + + + LOGI("write : %d", total_len); + if (_write_socket(sockfd, buf, total_len, &nb) != DATACONTROL_ERROR_NONE) { + LOGI("write data fail"); + ret = DATACONTROL_ERROR_IO_ERROR; + goto out; + } + +out: + if (buf) + free(buf); + bundle_free_encoded_rawdata(&kb_data); + bundle_free_encoded_rawdata(&extra_kb_data); + + return ret; +} + +static int __sql_request_provider(datacontrol_h provider, datacontrol_request_type type, bundle *request_data, bundle *extra_kb, int request_id) { - SECURE_LOGI("SQL Data control request, type: %d, request id: %d", type, request_id); + LOGI("SQL Data control request, type: %d, request id: %d", type, request_id); char *app_id = NULL; void *data = NULL; + int ret = DATACONTROL_ERROR_NONE; - if ((int)type <= (int)DATACONTROL_TYPE_SQL_DELETE) - { - if ((int)type < (int)DATACONTROL_TYPE_SQL_SELECT) - { + if (__socket_pair_hash == NULL) + __socket_pair_hash = g_hash_table_new_full(g_str_hash, g_str_equal, free, _socket_info_free); + + if ((int)type <= (int)DATACONTROL_TYPE_SQL_DELETE) { + + if ((int)type < (int)DATACONTROL_TYPE_SQL_SELECT) { LOGE("invalid request type: %d", (int)type); return DATACONTROL_ERROR_INVALID_PARAMETER; } - if (!datacontrol_sql_tree_root) - { + if (!datacontrol_sql_tree_root) { LOGE("the listener tree is empty"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1); - if (!sql_dc_temp) - { + sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s)); + if (!sql_dc_temp) { LOGE("failed to create sql datacontrol"); return DATACONTROL_ERROR_OUT_OF_MEMORY; } sql_dc_temp->provider_id = strdup(provider->provider_id); - if (!sql_dc_temp->provider_id) - { + if (!sql_dc_temp->provider_id) { LOGE("failed to assign provider id to sql data control: %d", errno); free(sql_dc_temp); return DATACONTROL_ERROR_OUT_OF_MEMORY; } sql_dc_temp->data_id = strdup(provider->data_id); - if (!sql_dc_temp->data_id) - { + if (!sql_dc_temp->data_id) { LOGE("failed to assign data id to sql data control: %d", errno); free(sql_dc_temp->provider_id); free(sql_dc_temp); @@ -386,96 +728,99 @@ datacontrol_sql_request_provider(datacontrol_h provider, datacontrol_request_typ sql_dc_temp->sql_response_cb = NULL; void *sql_dc_returned = NULL; - sql_dc_returned = tfind(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare); + sql_dc_returned = tfind(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare); - datacontrol_sql_instance_free(sql_dc_temp); + __sql_instance_free(sql_dc_temp); - if (!sql_dc_returned) - { + if (!sql_dc_returned) { LOGE("sql datacontrol returned after tfind is null"); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_INVALID_PARAMETER; } sql_response_cb_s *sql_dc = *(sql_response_cb_s **)sql_dc_returned; app_id = sql_dc->app_id; + + datacontrol_consumer_request_info *request_info = (datacontrol_consumer_request_info *)calloc(sizeof(datacontrol_consumer_request_info), 1); + request_info->request_id = request_id; + request_info->type = type; + sql_dc->request_info_list = g_list_append(sql_dc->request_info_list, request_info); + data = sql_dc; - SECURE_LOGI("SQL datacontrol appid: %s", sql_dc->app_id); + LOGI("SQL datacontrol appid: %s", sql_dc->app_id); } char caller_app_id[255]; pid_t pid = getpid(); - if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) - { - SECURE_LOGE("Failed to get appid by pid(%d).", pid); + if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) { + LOGE("Failed to get appid by pid(%d).", pid); return DATACONTROL_ERROR_INVALID_PARAMETER; } - appsvc_set_operation(arg_list, APPSVC_OPERATION_DEFAULT); - appsvc_set_appid(arg_list, app_id); - bundle_add_str(arg_list, OSP_K_CALLER_TYPE, OSP_V_CALLER_TYPE_OSP); - bundle_add_str(arg_list, OSP_K_LAUNCH_TYPE, OSP_V_LAUNCH_TYPE_DATACONTROL); - bundle_add_str(arg_list, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3); - bundle_add_str(arg_list, AUL_K_CALLER_APPID, caller_app_id); - bundle_add_str(arg_list, AUL_K_NO_CANCEL, "1"); - + bundle_add_str(request_data, OSP_K_DATACONTROL_PROTOCOL_VERSION, OSP_V_VERSION_2_1_0_3); + bundle_add_str(request_data, AUL_K_CALLER_APPID, caller_app_id); char datacontrol_request_operation[MAX_LEN_DATACONTROL_REQ_TYPE] = {0, }; snprintf(datacontrol_request_operation, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)(type)); - bundle_add_str(arg_list, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation); + bundle_add_str(request_data, OSP_K_DATACONTROL_REQUEST_TYPE, datacontrol_request_operation); char req_id[32] = {0, }; snprintf(req_id, 32, "%d", request_id); - bundle_add_str(arg_list, OSP_K_REQUEST_ID, req_id); + bundle_add_str(request_data, OSP_K_REQUEST_ID, req_id); - // For DataControl CAPI - bundle_add_str(arg_list, AUL_K_DATA_CONTROL_TYPE, "CORE"); + int count = 0; + const int TRY_COUNT = 2; + const struct timespec TRY_SLEEP_TIME = { 0, 1000 * 1000 * 1000 }; - SECURE_LOGI("SQL data control request - provider id: %s, data id: %s, provider appid: %s, request ID: %s", provider->provider_id, provider->data_id, app_id, req_id); + do { + datacontrol_socket_info *socket_info = g_hash_table_lookup(__socket_pair_hash, provider->provider_id); - pid = -1; - int count = 0; - const int TRY_COUNT = 4; - const int TRY_SLEEP_TIME = 65000; - do - { - pid = appsvc_run_service(arg_list, request_id, app_svc_res_cb_sql, data); - if (pid >= 0) - { - SECURE_LOGI("Launch the provider app successfully: %d", pid); - return DATACONTROL_ERROR_NONE; - } - else if (pid == APPSVC_RET_EINVAL) - { - SECURE_LOGE("not able to launch service: %d", pid); - return DATACONTROL_ERROR_INVALID_PARAMETER; + if (socket_info == NULL) { + ret = _request_appsvc_run(caller_app_id, app_id); + if (ret != DATACONTROL_ERROR_NONE) { + LOGE("_request_appsvc_run error !!!"); + return ret; + } + + socket_info = _get_socket_info(caller_app_id, app_id, "consumer", __consumer_recv_sql_message, data); + if (socket_info == NULL) { + LOGE("_get_socket_info error !!!"); + return DATACONTROL_ERROR_IO_ERROR; + } + + char *socket_info_key = strdup(provider->provider_id); + if (socket_info_key == NULL) { + LOGE("Out of memory. can not dup select map file."); + return DATACONTROL_ERROR_IO_ERROR; + } + g_hash_table_insert(__socket_pair_hash, socket_info_key, socket_info); } + LOGE("send data from consumer"); + ret = __datacontrol_send_sql_async(socket_info->socket_fd, request_data, extra_kb, type, NULL); + if (ret != DATACONTROL_ERROR_NONE) + g_hash_table_remove(__socket_pair_hash, provider->provider_id); + else + break; + count++; + nanosleep(&TRY_SLEEP_TIME, 0); + } while (ret != DATACONTROL_ERROR_NONE && count < TRY_COUNT); - usleep(TRY_SLEEP_TIME); - } - while (count < TRY_COUNT); + return ret; - SECURE_LOGE("unable to launch service: %d", pid); - return DATACONTROL_ERROR_IO_ERROR; } -int -datacontrol_sql_create(datacontrol_h *provider) +int datacontrol_sql_create(datacontrol_h *provider) { struct datacontrol_s *request; if (provider == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } request = malloc(sizeof(struct datacontrol_s)); if (request == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } request->provider_id = NULL; request->data_id = NULL; @@ -485,154 +830,116 @@ datacontrol_sql_create(datacontrol_h *provider) return 0; } -int -datacontrol_sql_destroy(datacontrol_h provider) +int datacontrol_sql_destroy(datacontrol_h provider) { if (provider == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->provider_id != NULL) - { free(provider->provider_id); - } if (provider->data_id != NULL) - { free(provider->data_id); - } free(provider); return 0; } -int -datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id) +int datacontrol_sql_set_provider_id(datacontrol_h provider, const char *provider_id) { if (provider == NULL || provider_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->provider_id != NULL) - { free(provider->provider_id); - } provider->provider_id = strdup(provider_id); if (provider->provider_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } return 0; } -int -datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id) +int datacontrol_sql_get_provider_id(datacontrol_h provider, char **provider_id) { if (provider == NULL || provider_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (provider->provider_id != NULL) - { + if (provider->provider_id != NULL) { + *provider_id = strdup(provider->provider_id); if (*provider_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } - } - else - { + + } else *provider_id = NULL; - } return 0; } -int -datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id) +int datacontrol_sql_set_data_id(datacontrol_h provider, const char *data_id) { if (provider == NULL || data_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } if (provider->data_id != NULL) - { free(provider->data_id); - } provider->data_id = strdup(data_id); if (provider->data_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } return 0; } -int -datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id) +int datacontrol_sql_get_data_id(datacontrol_h provider, char **data_id) { if (provider == NULL || data_id == NULL) - { return DATACONTROL_ERROR_INVALID_PARAMETER; - } - if (provider->data_id != NULL) - { + if (provider->data_id != NULL) { + *data_id = strdup(provider->data_id); if (*data_id == NULL) - { return DATACONTROL_ERROR_OUT_OF_MEMORY; - } - } - else - { + + } else *data_id = NULL; - } + return 0; } -int -datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb* callback, void *user_data) +int datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_response_cb *callback, void *user_data) { + int ret = 0; - char* app_id = NULL; - char* access = NULL; + char *app_id = NULL; + char *access = NULL; ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider->provider_id, "Sql", getuid(), &app_id, &access); - if (ret != PMINFO_R_OK) - { + if (ret != PMINFO_R_OK) { LOGE("unable to get sql data control information: %d", ret); return DATACONTROL_ERROR_IO_ERROR; } - SECURE_LOGI("data control provider appid = %s", app_id); + LOGI("data control provider appid = %s", app_id); - sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1); - if (!sql_dc_temp) - { + sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s)); + if (!sql_dc_temp) { LOGE("unable to create a temporary sql data control"); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } sql_dc_temp->provider_id = strdup(provider->provider_id); - if (!sql_dc_temp->provider_id) - { + if (!sql_dc_temp->provider_id) { LOGE("unable to assign provider_id to sql data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } sql_dc_temp->data_id = strdup(provider->data_id); - if (!sql_dc_temp->data_id) - { + if (!sql_dc_temp->data_id) { LOGE("unable to assign data_id to sql data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; @@ -644,15 +951,14 @@ datacontrol_sql_register_response_cb(datacontrol_h provider, datacontrol_sql_res sql_dc_temp->sql_response_cb = callback; void *sql_dc_returned = NULL; - sql_dc_returned = tsearch(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare); + sql_dc_returned = tsearch(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare); sql_response_cb_s *sql_dc = *(sql_response_cb_s **)sql_dc_returned; - if (sql_dc != sql_dc_temp) - { + if (sql_dc != sql_dc_temp) { sql_dc->sql_response_cb = callback; sql_dc->user_data = user_data; LOGI("the data control is already set"); - datacontrol_sql_instance_free(sql_dc_temp); + __sql_instance_free(sql_dc_temp); } return DATACONTROL_ERROR_NONE; @@ -662,8 +968,8 @@ EXCEPTION: free(access); if (app_id) free(app_id); - if (sql_dc_temp) - { + + if (sql_dc_temp) { if (sql_dc_temp->provider_id) free(sql_dc_temp->provider_id); if (sql_dc_temp->data_id) @@ -674,267 +980,136 @@ EXCEPTION: return ret; } -int -datacontrol_sql_unregister_response_cb(datacontrol_h provider) +int datacontrol_sql_unregister_response_cb(datacontrol_h provider) { + int ret = DATACONTROL_ERROR_NONE; + LOGE("g_hash_table_remove"); - sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(sizeof(sql_response_cb_s),1); + g_hash_table_remove(__socket_pair_hash, provider->provider_id); - if (!sql_dc_temp) - { + sql_response_cb_s *sql_dc_temp = (sql_response_cb_s *)calloc(1, sizeof(sql_response_cb_s)); + + if (!sql_dc_temp) { LOGE("unable to create a temporary sql data control"); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } sql_dc_temp->provider_id = strdup(provider->provider_id); - if (!sql_dc_temp->provider_id) - { + if (!sql_dc_temp->provider_id) { LOGE("unable to assign provider_id to sql data control: %d", errno); ret = DATACONTROL_ERROR_OUT_OF_MEMORY; goto EXCEPTION; } - void *sql_dc_returned = NULL; - - sql_dc_returned = tdelete(sql_dc_temp, &datacontrol_sql_tree_root, datacontrol_sql_instance_compare); - if (sql_dc_returned == NULL) - { + sql_dc_returned = tdelete(sql_dc_temp, &datacontrol_sql_tree_root, __sql_instance_compare); + if (sql_dc_returned == NULL) { LOGE("invalid parameter"); ret = DATACONTROL_ERROR_INVALID_PARAMETER; goto EXCEPTION; } - EXCEPTION: - if (sql_dc_temp) - { + if (sql_dc_temp) { if (sql_dc_temp->provider_id) free(sql_dc_temp->provider_id); free(sql_dc_temp); - } + } return ret; } -static void -bundle_foreach_check_arg_size_cb(const char *key, const int type, const bundle_keyval_t *kv, void *arg_size) -{ - char *value = NULL; - size_t value_len = 0; - bundle_keyval_get_basic_val((bundle_keyval_t*)kv, (void**)&value, &value_len); - - arg_size += (strlen(key) + value_len) * sizeof(wchar_t); - return; -} - -static void -bundle_foreach_cb(const char *key, const int type, const bundle_keyval_t *kv, void *user_data) -{ - if (!key || !kv || !user_data) - { - return; - } - - int fd = *(int *)user_data; +static void bundle_foreach_check_arg_size_cb(const char *key, const int type, + const bundle_keyval_t *kv, void *arg_size) { - int key_len = strlen(key); char *value = NULL; size_t value_len = 0; - bundle_keyval_get_basic_val((bundle_keyval_t*)kv, (void**)&value, &value_len); - - // Write a key - if (write(fd, &key_len, sizeof(int)) == -1) - { - LOGE("Writing a key_len to a file descriptor is failed. errno = %d", errno); - } - if (write(fd, key, key_len) == -1) - { - LOGE("Writing a key to a file descriptor is failed. errno = %d", errno); - } - // Write a value - if (write(fd, &value_len, sizeof(int)) == -1) - { - LOGE("Writing a value_len to a file descriptor is failed. errno = %d", errno); - } - if (write(fd, value, value_len) == -1) - { - LOGE("Writing a value to a file descriptor is failed. errno = %d", errno); - } + bundle_keyval_get_basic_val((bundle_keyval_t *)kv, (void **)&value, &value_len); + arg_size += (strlen(key) + value_len) * sizeof(wchar_t); return; } -char * -__get_provider_pkgid(char* provider_id) -{ - char* access = NULL; - char *provider_appid = NULL; - char *provider_pkgid = NULL; - pkgmgrinfo_appinfo_h app_info_handle = NULL; - - int ret = pkgmgrinfo_appinfo_usr_get_datacontrol_info(provider_id, "Sql", getuid(), &provider_appid, &access); - if (ret != PMINFO_R_OK) - { - LOGE("unable to get sql data control information: %d", ret); - return NULL; - } - - pkgmgrinfo_appinfo_get_usr_appinfo(provider_appid, getuid(), &app_info_handle); - pkgmgrinfo_appinfo_get_pkgname(app_info_handle, &provider_pkgid); - SECURE_LOGI("provider pkg id : %s", provider_pkgid); - - if (access) - { - free(access); - } - if (provider_appid) - { - free(provider_appid); - } - return provider_pkgid ? strdup(provider_pkgid) : NULL; -} - -int -datacontrol_sql_insert(datacontrol_h provider, const bundle* insert_data, int *request_id) +int datacontrol_sql_insert(datacontrol_h provider, const bundle *insert_data, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || insert_data == NULL) - { + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || insert_data == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } - SECURE_LOGI("SQL data control, insert to provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); + LOGI("SQL data control, insert to provider_id: %s, data_id: %s", provider->provider_id, provider->data_id); int ret = 0; - char caller_app_id[256] = {0, }; - pid_t pid = getpid(); - - if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) - { - SECURE_LOGE("Failed to get appid by pid(%d).", pid); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - // Check size of arguments long long arg_size = 0; - bundle_foreach((bundle*)insert_data, bundle_foreach_check_arg_size_cb, &arg_size); + bundle_foreach((bundle *)insert_data, bundle_foreach_check_arg_size_cb, &arg_size); arg_size += strlen(provider->data_id) * sizeof(wchar_t); - if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) - { + if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) { LOGE("The size of the request argument exceeds the limit, 1M."); return DATACONTROL_ERROR_MAX_EXCEEDED; } - int reqId = _datacontrol_create_request_id(); - SECURE_LOGI("request id: %d", reqId); - char insert_map_file[REQUEST_PATH_MAX] = {0, }; - ret = snprintf(insert_map_file, REQUEST_PATH_MAX, "%s%s%d", DATACONTROL_REQUEST_FILE_PREFIX, caller_app_id, reqId); - if (ret < 0) - { - LOGE("unable to write formatted output to insert_map_file. errno = %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - SECURE_LOGI("insert_map_file : %s", insert_map_file); - - int fd = 0; - char *provider_pkgid = __get_provider_pkgid(provider->provider_id); - - /* TODO - shoud be changed to solve security concerns */ - fd = open(insert_map_file, O_WRONLY | O_CREAT, 0644); - if (fd == -1) { - SECURE_LOGE("unable to open insert_map file: %d", errno); - free(provider_pkgid); - return DATACONTROL_ERROR_IO_ERROR; - } - - free(provider_pkgid); - - int count = bundle_get_count((bundle*)insert_data); - LOGI("Insert column counts: %d", count); - - bundle_foreach((bundle*)insert_data, bundle_foreach_cb, &fd); - - fsync(fd); - close(fd); - bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); char insert_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, }; + int count = bundle_get_count((bundle *)insert_data); ret = snprintf(insert_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert insert column count to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } - const char* arg_list[3]; + const char *arg_list[2]; arg_list[0] = provider->data_id; arg_list[1] = insert_column_count; - arg_list[2] = insert_map_file; - bundle_add_str_array(b, OSP_K_ARG, arg_list, 3); + bundle_add_str_array(b, OSP_K_ARG, arg_list, 2); // Set the request id - *request_id = reqId; + *request_id = _datacontrol_create_request_id(); + LOGI("request id : %d", *request_id); - ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_INSERT, b, reqId); - if (ret != DATACONTROL_ERROR_NONE) - { - ret = remove(insert_map_file); - if (ret == -1) - { - SECURE_LOGE("unable to remove the insert_map_file. errno = %d", errno); - } - } + ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_INSERT, b, (bundle *)insert_data, *request_id); bundle_free(b); return ret; } -int -datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id) +int datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) - { + + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); - const char* arg_list[2]; + const char *arg_list[2]; arg_list[0] = provider->data_id; if (where) - { arg_list[1] = where; - } else - { arg_list[1] = DATACONTROL_EMPTY; - } bundle_add_str_array(b, OSP_K_ARG, arg_list, 2); @@ -942,30 +1117,27 @@ datacontrol_sql_delete(datacontrol_h provider, const char *where, int *request_i int reqId = _datacontrol_create_request_id(); *request_id = reqId; - int ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_DELETE, b, reqId); + int ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_DELETE, b, NULL, reqId); bundle_free(b); return ret; } -int -datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int *request_id) -{ +int datacontrol_sql_select(datacontrol_h provider, char **column_list, int column_count, + const char *where, const char *order, int *request_id) { return datacontrol_sql_select_with_page(provider, column_list, column_count, where, order, 1, 20, request_id); } -int -datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count, const char *where, const char *order, int page_number, int count_per_page, int *request_id) -{ - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) - { +int datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int column_count, + const char *where, const char *order, int page_number, int count_per_page, int *request_id) { + + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } LOGI("SQL data control, select to provider_id: %s, data_id: %s, col_count: %d, where: %s, order: %s, page_number: %d, per_page: %d", provider->provider_id, provider->data_id, column_count, where, order, page_number, count_per_page); - if (column_list == NULL) - { + if (column_list == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } @@ -974,10 +1146,9 @@ datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int int ret = 0; bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); @@ -985,39 +1156,35 @@ datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int char page[32] = {0, }; ret = snprintf(page, 32, "%d", page_number); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert page no to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } char count_per_page_no[32] = {0, }; ret = snprintf(count_per_page_no, 32, "%d", count_per_page); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert count per page no to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } total_arg_count = column_count + DATACONTROL_SELECT_EXTRA_COUNT; - const char** arg_list = (const char**)malloc(total_arg_count * (sizeof(char *))); + const char **arg_list = (const char **)malloc(total_arg_count * (sizeof(char *))); LOGI("total arg count %d", total_arg_count); arg_list[0] = provider->data_id; // arg[0]: data ID int i = 1; - if (column_list) - { + if (column_list) { char select_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, }; ret = snprintf(select_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", column_count); - if(ret < 0) - { + if (ret < 0) { LOGE("unable to convert select col count to string: %d", errno); free(arg_list); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } @@ -1026,33 +1193,20 @@ datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int ++i; int select_col = 0; while (select_col < column_count) - { arg_list[i++] = column_list[select_col++]; - } - } - else - { + + } else arg_list[i++] = DATACONTROL_EMPTY; - } if (where) // arg: where clause - { arg_list[i++] = where; - } else - { arg_list[i++] = DATACONTROL_EMPTY; - } - if (order) // arg: order clause - { + if (order)// arg: order clause arg_list[i++] = order; - } else - { arg_list[i++] = DATACONTROL_EMPTY; - } - arg_list[i++] = page; // arg: page number @@ -1064,112 +1218,58 @@ datacontrol_sql_select_with_page(datacontrol_h provider, char **column_list, int int reqId = _datacontrol_create_request_id(); *request_id = reqId; - ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_SELECT, b, reqId); + ret = __sql_request_provider(provider, DATACONTROL_TYPE_SQL_SELECT, b, NULL, reqId); bundle_free(b); return ret; } -int -datacontrol_sql_update(datacontrol_h provider, const bundle* update_data, const char *where, int *request_id) +int datacontrol_sql_update(datacontrol_h provider, const bundle *update_data, const char *where, int *request_id) { - if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || update_data == NULL || where == NULL) - { + + if (provider == NULL || provider->provider_id == NULL || provider->data_id == NULL || update_data == NULL || where == NULL) { LOGE("Invalid parameter"); return DATACONTROL_ERROR_INVALID_PARAMETER; } int ret = 0; - char caller_app_id[256] = {0, }; - pid_t pid = getpid(); - - if (aul_app_get_appid_bypid(pid, caller_app_id, sizeof(caller_app_id)) != 0) - { - SECURE_LOGE("Failed to get appid by pid(%d).", pid); - return DATACONTROL_ERROR_INVALID_PARAMETER; - } - // Check size of arguments long long arg_size = 0; - bundle_foreach((bundle*)update_data, bundle_foreach_check_arg_size_cb, &arg_size); + bundle_foreach((bundle *)update_data, bundle_foreach_check_arg_size_cb, &arg_size); arg_size += strlen(provider->data_id) * sizeof(wchar_t); - if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) - { + if (arg_size > MAX_REQUEST_ARGUMENT_SIZE) { LOGE("The size of the request argument exceeds the limit, 1M."); return DATACONTROL_ERROR_MAX_EXCEEDED; } - int reqId = _datacontrol_create_request_id(); - - char update_map_file[REQUEST_PATH_MAX] = {0, }; - ret = snprintf(update_map_file, REQUEST_PATH_MAX, "%s%s%d", DATACONTROL_REQUEST_FILE_PREFIX, caller_app_id, reqId); - if (ret < 0) - { - LOGE("unable to write formatted output to update_map_file: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; - } - - SECURE_LOGI("update_map_file : %s", update_map_file); - - int fd = 0; - char *provider_pkgid = __get_provider_pkgid(provider->provider_id); - - /* TODO - shoud be changed to solve security concerns */ - fd = open(update_map_file, O_WRONLY | O_CREAT, 0644); - if (fd == -1) - { - SECURE_LOGE("unable to open update_map file: %d", errno); - free(provider_pkgid); - return DATACONTROL_ERROR_IO_ERROR; - } - - free(provider_pkgid); - - int count = bundle_get_count((bundle*)update_data); - bundle_foreach((bundle*)update_data, bundle_foreach_cb, &fd); - - fsync(fd); - close(fd); - bundle *b = bundle_create(); - if (!b) - { + if (!b) { LOGE("unable to create bundle: %d", errno); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } bundle_add_str(b, OSP_K_DATACONTROL_PROVIDER, provider->provider_id); bundle_add_str(b, OSP_K_DATACONTROL_DATA, provider->data_id); char update_column_count[MAX_LEN_DATACONTROL_COLUMN_COUNT] = {0, }; + int count = bundle_get_count((bundle *)update_data); ret = snprintf(update_column_count, MAX_LEN_DATACONTROL_COLUMN_COUNT, "%d", count); - if (ret < 0) - { + if (ret < 0) { LOGE("unable to convert update col count to string: %d", errno); bundle_free(b); - return DATACONTROL_ERROR_IO_ERROR; + return DATACONTROL_ERROR_OUT_OF_MEMORY; } - const char* arg_list[4]; + const char *arg_list[4]; arg_list[0] = provider->data_id; // list(0): data ID arg_list[1] = update_column_count; - arg_list[2] = update_map_file; - arg_list[3] = where; - - bundle_add_str_array(b, OSP_K_ARG, arg_list, 4); + arg_list[2] = where; + bundle_add_str_array(b, OSP_K_ARG, arg_list, 3); - *request_id = reqId; + *request_id = _datacontrol_create_request_id(); + __sql_request_provider(provider, DATACONTROL_TYPE_SQL_UPDATE, b, (bundle *)update_data, *request_id); - ret = datacontrol_sql_request_provider(provider, DATACONTROL_TYPE_SQL_UPDATE, b, reqId); - if (ret != DATACONTROL_ERROR_NONE) - { - ret = remove(update_map_file); - if (ret == -1) - { - SECURE_LOGE("unable to remove the update_map file: %d", errno); - } - } bundle_free(b); return ret; } diff --git a/src/data_control_internal.c b/src/data_control_internal.c old mode 100644 new mode 100755 index f1f9b7b..46688af --- a/src/data_control_internal.c +++ b/src/data_control_internal.c @@ -48,6 +48,12 @@ int datacontrol_check_privilege(privilege_type check_type) { char uid[10] = {0,}; char *client_session = ""; + static bool checked_privilege = FALSE; + + if (checked_privilege) { + return DATA_CONTROL_ERROR_NONE; + } + ret = cynara_initialize(&p_cynara, NULL); if (ret != CYNARA_API_SUCCESS) { LOGE("cannot init cynara [%d] failed!", ret); @@ -91,6 +97,7 @@ int datacontrol_check_privilege(privilege_type check_type) { } ret = DATA_CONTROL_ERROR_NONE; + checked_privilege = TRUE; out: if (p_cynara) diff --git a/src/data_control_provider.c b/src/data_control_provider.c old mode 100644 new mode 100755 index 27766d6..36c656c --- a/src/data_control_provider.c +++ b/src/data_control_provider.c @@ -257,7 +257,7 @@ data_control_provider_create_insert_statement(data_control_h provider, bundle *i return NULL; } - key_val_pair *cols = (key_val_pair *) calloc(sizeof(key_val_pair), 1); + key_val_pair *cols = (key_val_pair *) calloc(1, sizeof(key_val_pair)); if (cols == NULL) { set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY); @@ -266,7 +266,7 @@ data_control_provider_create_insert_statement(data_control_h provider, bundle *i cols->no_of_elements = 0; cols->length = 0; - cols->keys = (char **) calloc(sizeof(char *), row_count); + cols->keys = (char **) calloc(row_count, sizeof(char *)); if (cols->keys == NULL) { free(cols); @@ -274,7 +274,7 @@ data_control_provider_create_insert_statement(data_control_h provider, bundle *i return NULL; } - cols->vals = (char **) calloc(sizeof(char *), row_count); + cols->vals = (char **) calloc(row_count, sizeof(char *)); if (cols->vals == NULL) { free(cols->keys); @@ -293,7 +293,7 @@ data_control_provider_create_insert_statement(data_control_h provider, bundle *i _LOGI("SQL statement length: %d", sql_len); - char* sql = (char *) calloc(sizeof(char), sql_len); + char* sql = (char *) calloc(sql_len, sizeof(char)); if (sql == NULL) { free(data_id); @@ -358,7 +358,7 @@ data_control_provider_create_delete_statement(data_control_h provider, const cha _LOGI("SQL statement length: %d", sql_len); - char* sql = (char *) calloc(sizeof(char), sql_len); + char* sql = (char *) calloc(sql_len, sizeof(char)); if (sql == NULL) { free(data_id); @@ -390,7 +390,7 @@ data_control_provider_create_update_statement(data_control_h provider, bundle *u return NULL; } - key_val_pair *cols = (key_val_pair *) calloc(sizeof(key_val_pair), 1); + key_val_pair *cols = (key_val_pair *) calloc(1, sizeof(key_val_pair)); if (cols == NULL) { set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY); @@ -399,14 +399,14 @@ data_control_provider_create_update_statement(data_control_h provider, bundle *u cols->no_of_elements = 0; cols->length = 0; - cols->keys = (char **) calloc(sizeof(char *), row_count); + cols->keys = (char **) calloc(row_count, sizeof(char *)); if (cols->keys == NULL) { free(cols); set_last_result(DATA_CONTROL_ERROR_OUT_OF_MEMORY); return NULL; } - cols->vals = (char **) calloc(sizeof(char *), row_count); + cols->vals = (char **) calloc(row_count, sizeof(char *)); if (cols->vals == NULL) { free(cols->keys); @@ -426,7 +426,7 @@ data_control_provider_create_update_statement(data_control_h provider, bundle *u _LOGI("SQL statement length: %d", sql_len); - char* sql = (char *) calloc(sizeof(char), sql_len); + char* sql = (char *) calloc(sql_len, sizeof(char)); if (sql == NULL) { free(data_id); @@ -509,7 +509,7 @@ data_control_provider_create_select_statement(data_control_h provider, const cha _LOGI("SQL statement length: %d", sql_len); - char* sql = (char *) calloc(sizeof(char), sql_len); + char* sql = (char *) calloc(sql_len, sizeof(char)); if (sql == NULL) { free(data_id); -- 2.7.4