58526492d85c4c8bf3033a791a31bd009a82f04a
[framework/appfw/data-control.git] / src / data-control-provider.c
1 #include <dlog.h>
2 #include <errno.h>
3 #include <search.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <glib.h>
9 #include <pthread.h>
10 #include <sqlite3.h>
11 #include <limits.h>
12
13 #include <appsvc/appsvc.h>
14 #include <aul/aul.h>
15 #include <bundle.h>
16 #include <pkgmgr-info.h>
17 #include <security-server.h>
18
19 #include "data-control-sql.h"
20 #include "data-control-provider.h"
21 #include "data-control-internal.h"
22
23 #define ROW_ID_SIZE             32
24 #define RESULT_PATH_MAX         512
25
26
27 #define RESULT_PAGE_NUMBER              "RESULT_PAGE_NUMBER"
28 #define MAX_COUNT_PER_PAGE              "MAX_COUNT_PER_PAGE"
29 #define RESULT_VALUE_COUNT                      "RESULT_VALUE_COUNT"
30
31 #define PACKET_INDEX_REQUEST_RESULT     0
32 #define PACKET_INDEX_ERROR_MSG          1
33 #define PACKET_INDEX_SELECT_RESULT_FILE 2
34 #define PACKET_INDEX_ROW_ID                     2
35 #define PACKET_INDEX_VALUE_COUNT                2
36 #define PACKET_INDEX_GET_RESULT_FILE    3
37
38 #define PACKET_INDEX_DATAID     0
39 #define PACKET_INDEX_COLUMNCOUNT        1
40 #define PACKET_INDEX_MAP        2
41
42 #define PACKET_INDEX_UPDATEWHERE        3
43 #define PACKET_INDEX_DELETEWHERE        1
44
45 #define PACKET_INDEX_MAP_KEY    1
46 #define PACKET_INDEX_MAP_VALUE_1ST      2
47 #define PACKET_INDEX_MAP_VALUE_2ND      3
48 #define PACKET_INDEX_MAP_PAGE_NO        2
49 #define PACKET_INDEX_MAP_COUNT_PER_PAGE 3
50
51 static const int MAX_ARGUMENT_SIZE = 16384; // 16KB
52 static GHashTable *request_table = NULL;
53
54 //static pthread_mutex_t provider_lock = PTHREAD_MUTEX_INITIALIZER;
55
56 struct datacontrol_s {
57         char *provider_id;
58         char *data_id;
59 };
60
61
62 typedef int (*provider_handler_cb) (bundle * b, int request_id, void *data);
63
64 static datacontrol_provider_sql_cb* provider_sql_cb = NULL;
65 static datacontrol_provider_map_cb* provider_map_cb = NULL;
66 static void* provider_map_user_data = NULL;
67 static void* provider_sql_user_data = NULL;
68
69 static void
70 __free_data(gpointer data)
71 {
72         if (data)
73         {
74                 free(data);
75                 data = NULL;
76         }
77 }
78
79 static void
80 __initialize_provider(void)
81 {
82         request_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_data, __free_data);
83 }
84
85 static int
86 __provider_new_request_id(void)
87 {
88         static int id = 0;
89
90         g_atomic_int_inc(&id);
91
92         return id;
93 }
94
95 static char*
96 __get_client_pkgid(bundle *b)
97 {
98         const char *caller_appid = NULL;
99         char *caller_pkgid = NULL;
100         pkgmgrinfo_appinfo_h app_info_handle = NULL;
101
102         caller_appid = bundle_get_val(b, AUL_K_CALLER_APPID);
103         pkgmgrinfo_appinfo_get_appinfo(caller_appid, &app_info_handle);
104         pkgmgrinfo_appinfo_get_pkgname(app_info_handle, &caller_pkgid);
105         SECURE_LOGI("client pkg id : %s", caller_pkgid);
106
107         return caller_pkgid ? strdup(caller_pkgid) : NULL;
108 }
109
110 static bundle*
111 __get_data_map(const char *path, int column_count)
112 {
113         bundle* b = bundle_create();
114
115         int len = 0;
116         int i = 0;
117         ssize_t size = 0;
118         char *key = NULL;
119         char *value = NULL;
120         int fd = 0;
121         int ret = 0;
122
123         SECURE_LOGI("The request file of INSERT/UPDATE: %s", path);
124         ret = security_server_shared_file_reopen(path, &fd);
125         if (ret != SECURITY_SERVER_API_SUCCESS)
126         {
127                 SECURE_LOGE("Opening the file(%s) is failed : %d", path, ret);
128                 return b;
129         }
130
131         for (i = 0; i < column_count; i++)
132         {
133                 size = read(fd, &len, sizeof(int));
134                 if ((unsigned int)size < sizeof(int) || len < 0 || len > MAX_ARGUMENT_SIZE)
135                 {
136                         SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size);
137                         break;
138                 }
139
140                 key = calloc(len + 1, sizeof(char));
141                 if (key == NULL) {
142                         SECURE_LOGE("out of memory");
143                         break;
144                 }
145
146                 size = read(fd, key, len);      // key
147                 if (size < 0)
148                 {
149                         SECURE_LOGE("key length:%d, read():%s, returned:%d", len, strerror(errno), size);
150                         free(key);
151                         break;
152                 }
153
154                 size = read(fd, &len, sizeof(int));
155                 if ((unsigned int)size < sizeof(int) || len < 0 || len > MAX_ARGUMENT_SIZE)
156                 {
157                         SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size);
158                         free(key);
159                         break;
160                 }
161
162                 value = calloc(len + 1, sizeof(char));
163                 if (value == NULL) {
164                         SECURE_LOGE("out of memory");
165                         free(key);
166                         break;
167                 }
168
169                 size = read(fd, value, len); // value
170                 if (size < 0)
171                 {
172                         SECURE_LOGE("value length:%d, read():%s, returned:%d", len, strerror(errno), size);
173                         free(key);
174                         free(value);
175                         break;
176                 }
177
178                 LOGI("key: %s, value: %s", key, value);
179
180                 bundle_add_str(b, key, value);
181
182                 free(key);
183                 free(value);
184         }
185
186         fsync(fd);
187         close(fd);
188         ret = security_server_shared_file_delete(path);
189         if (ret != SECURITY_SERVER_API_SUCCESS)
190         {
191                 SECURE_LOGE("unable to remove the request file of INSERT/UPDATE(%s): %d", path, ret);
192         }
193
194         return b;
195 }
196
197 static int
198 __set_select_result(bundle* b, const char* path, void* data)
199 {
200         LOGI("__set_select_result");
201         // The provider application should call the sqlite3_open().
202         // and it also should call the sqlite3_prepare_v2() in datacontrol_provider_sql_select_request_cb().
203         // and then, it should call the datacontrol_provider_send_select_result() with a pointer to sqlite3_stmt.
204         // The 3rd param 'data' is the pointer to sqlite3_stmt.
205
206         // In this function, the result set is written in specified file path as specific form.
207         // [sizeof(int)] row count
208         // [sizeof(int)] column count
209         // [sieeof(int)] total size of column names
210         // [sizeof(int)] column type x N
211         // [  variant  ] column name x N
212         // [sizeof(int)] type
213         // [sizeof(int)] size
214         // [  varient  ] content
215
216         int column_count = 0;
217         int i = 0;
218         char *column_name = NULL;
219         int total_len_of_column_names = 0;
220         int count_per_page = 0;
221         int page_number = 1;
222         int offset = 0;
223         int offset_idx = 0;
224         int row_count = 0;
225         sqlite3_stmt *state = (sqlite3_stmt *)data;
226         int ret = 0;
227         int fd = 0;
228         char *client_pkgid = NULL;
229
230         if (b ==NULL || path == NULL || data == NULL)
231         {
232                 LOGE("The input param is invalid.");
233                 return DATACONTROL_ERROR_INVALID_PARAMETER;
234         }
235
236         if (sqlite3_reset(state) != SQLITE_OK)
237         {
238                 LOGE("sqlite3_reset() is failed.");
239                 return DATACONTROL_ERROR_INVALID_PARAMETER;
240         }
241
242         if (sqlite3_step(state) != SQLITE_ROW)
243         {
244                 LOGE("The DB does not have another row.");
245                 return DATACONTROL_ERROR_INVALID_PARAMETER;
246         }
247
248         client_pkgid = __get_client_pkgid(b);
249         ret = security_server_shared_file_open(path, client_pkgid, &fd);
250         if (ret == SECURITY_SERVER_API_ERROR_FILE_EXIST) {
251                 SECURE_LOGE("The file(%s) already exist, delete and retry to open", path);
252                 int ret_temp = security_server_shared_file_delete(path);
253                 if (ret_temp != SECURITY_SERVER_API_SUCCESS) {
254                         SECURE_LOGE("Delete the file(%s) is failed : %d", path, ret_temp);
255                 } else {
256                         ret = security_server_shared_file_open(path, client_pkgid, &fd);
257                 }
258         }
259
260         if (ret != SECURITY_SERVER_API_SUCCESS)
261         {
262                 SECURE_LOGE("Opening the file(%s) is failed : %d", path, ret);
263                 free(client_pkgid);
264                 return DATACONTROL_ERROR_IO_ERROR;
265         }
266         free(client_pkgid);
267
268         // 1. column count
269         column_count = sqlite3_column_count(state);
270         if (lseek(fd, sizeof(int), SEEK_SET) == -1)
271         {
272                 LOGE("lseek is failed. errno =  %d", errno);
273         }
274         if (write(fd, &column_count, sizeof(int)) == -1)
275         {
276                 LOGE("Writing a column_count to a file descriptor is failed. errno = %d", errno);
277         }
278
279         // 2. column type x column_count
280         // #define SQLITE_INTEGER       1
281         // #define SQLITE_FLOAT 2
282         // #define SQLITE_TEXT  3
283         // #define SQLITE_BLOB  4
284         // #define SQLITE_NULL  5
285         if (lseek(fd, sizeof(int), SEEK_CUR) == -1)
286         {
287                 LOGE("lseek is failed. errno =  %d", errno);
288         }
289
290         for (i = 0; i < column_count; ++i)
291         {
292                 int type = sqlite3_column_type(state, i);
293                 if (write(fd, &type, sizeof(int)) == -1)
294                 {
295                         LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
296                 }
297         }
298
299         // 3. column name x column_count
300         for (i = 0; i < column_count; i++)
301         {
302                 column_name = (char *)sqlite3_column_name(state, i);
303                 if (column_name == NULL) {
304                         LOGE("sqlite3_column_name is failed. errno = %d", errno);
305                 } else {
306                         column_name = strcat(column_name, "\n");
307                         if (write(fd, column_name, strlen(column_name)) == -1)
308                         {
309                                 LOGE("Writing a column_name to a file descriptor is failed. errno = %d", errno);
310                         }
311                         total_len_of_column_names += strlen(column_name);
312                 }
313         }
314
315         // 4. total length of column names
316         if (lseek(fd, sizeof(int) * 2, SEEK_SET) == -1)
317         {
318                 LOGE("lseek is failed. errno =  %d", errno);
319         }
320         if (write(fd, &total_len_of_column_names, sizeof(int)) == -1)
321         {
322                 LOGE("Writing a total_len_of_column_names to a file descriptor is failed. errno = %d", errno);
323         }
324         // 5. type, size and value of each element
325         if (lseek(fd, (sizeof(int) * column_count) + total_len_of_column_names, SEEK_CUR) == -1)
326         {
327                 LOGE("lseek is failed. errno =  %d", errno);
328         }
329
330         page_number = atoi(bundle_get_val(b, RESULT_PAGE_NUMBER));
331         count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE));
332         offset = (page_number - 1) * count_per_page;
333
334         LOGI("page_number: %d, count_per_page: %d, offset: %d", page_number, count_per_page, offset);
335         do
336         {
337
338                 offset_idx ++;
339                 if (offset_idx > offset) {
340
341                         for (i = 0; i < column_count; ++i)
342                         {
343                                 int type = 0;
344                                 int size = 0;
345                                 void* value = NULL;
346                                 bool is_null_type = false;
347                                 int column_type = sqlite3_column_type(state, i);
348                                 long long tmp_long = 0;
349                                 double tmp_double = 0.0;
350                                 switch (column_type)
351                                 {
352                                         case SQLITE_INTEGER:
353                                                 {
354                                                         type = 1;
355                                                         size = sizeof(long long);
356                                                         tmp_long = sqlite3_column_int64(state, i);
357                                                         value = &tmp_long;
358                                                         break;
359                                                 }
360                                         case SQLITE_FLOAT:
361                                                 {
362                                                         type = 2;
363                                                         size = sizeof(double);
364                                                         tmp_double = sqlite3_column_double(state, i);
365                                                         value =&tmp_double;
366                                                         break;
367                                                 }
368                                         case SQLITE_TEXT:
369                                                 {
370                                                         type = 3;
371                                                         value = (char *)sqlite3_column_text(state, i);
372                                                         size = strlen(value);
373                                                         break;
374                                                 }
375                                         case SQLITE_BLOB:
376                                                 {
377                                                         type = 4;
378                                                         size = sqlite3_column_bytes(state, i);
379                                                         value = (char *)sqlite3_column_blob(state, i);
380                                                         break;
381                                                 }
382                                         case SQLITE_NULL:
383                                                 {
384                                                         type = 5;
385                                                         size = 0;
386                                                         is_null_type = true;
387                                                         break;
388                                                 }
389                                         default:
390                                                 {
391                                                         LOGE("The column type is invalid.");
392                                                         break;
393                                                 }
394                                 }
395
396                                 if (write(fd, &type, sizeof(int)) == -1)
397                                 {
398                                         LOGE("Writing a type to a file descriptor is failed. errno = %d", errno);
399                                 }
400                                 if (write(fd, &size, sizeof(int)) == -1)
401                                 {
402                                         LOGE("Writing a size to a file descriptor is failed. errno = %d", errno);
403                                 }
404                                 if (size > 0 && size < INT_MAX && !is_null_type)
405                                 {
406                                         if (write(fd, value, size) == -1)
407                                         {
408                                                 LOGE("Writing a value to a file descriptor is failed. errno = %d", errno);
409                                         }
410                                 }
411                         }
412                         ++row_count;
413                 }
414
415         } while(sqlite3_step(state) == SQLITE_ROW && row_count < count_per_page);
416
417         // 6. row count
418         if (lseek(fd, 0, SEEK_SET) == -1)
419         {
420                 LOGE("lseek is failed. errno =  %d", errno);
421         }
422         if (write(fd, &row_count, sizeof(int)) == -1)
423         {
424                 LOGE("Writing a row_count to a file descriptor is failed. errno = %d", errno);
425         }
426         close(fd);
427
428
429         return DATACONTROL_ERROR_NONE;
430 }
431
432 static int
433 __set_get_value_result(bundle *b, const char* path, char **value_list)
434 {
435         int i = 0;
436         int fd = -1;
437         int ret = -1;
438         char *client_pkgid = NULL;
439
440         if (b == NULL || path == NULL || value_list == NULL)
441         {
442                 LOGE("The input param is invalid.");
443                 return DATACONTROL_ERROR_INVALID_PARAMETER;
444         }
445
446         int page_number = atoi(bundle_get_val(b, RESULT_PAGE_NUMBER));
447         int count_per_page = atoi(bundle_get_val(b, MAX_COUNT_PER_PAGE));
448         int value_count = atoi(bundle_get_val(b, RESULT_VALUE_COUNT));
449         int current_offset = (page_number - 1) * count_per_page;
450         int remain_count = value_count - current_offset;
451         remain_count = (remain_count > 0) ? remain_count : 0;   // round off to zero if the negative num is found
452         int add_value_count = (count_per_page > remain_count) ? remain_count : count_per_page;
453
454         if (add_value_count < value_count)
455         {
456                 bundle_del(b, RESULT_VALUE_COUNT);
457                 char value_count_str[32] = {0,};
458                 snprintf(value_count_str, 32, "%d", add_value_count);
459                 bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
460         }
461
462         if (add_value_count <= 0)
463         {
464                 LOGI("There is no value list.");
465                 return DATACONTROL_ERROR_NONE;
466         }
467
468         client_pkgid = __get_client_pkgid(b);
469         ret = security_server_shared_file_open(path, client_pkgid, &fd);
470         if (ret == SECURITY_SERVER_API_ERROR_FILE_EXIST) {
471                 SECURE_LOGE("The file(%s) already exist, delete and retry to open", path);
472                 int ret_temp = security_server_shared_file_delete(path);
473                 if (ret_temp != SECURITY_SERVER_API_SUCCESS) {
474                         SECURE_LOGE("Delete the file(%s) is failed : %d", path, ret_temp);
475                 } else {
476                         ret = security_server_shared_file_open(path, client_pkgid, &fd);
477                 }
478         }
479
480         if (ret != SECURITY_SERVER_API_SUCCESS)
481         {
482                 SECURE_LOGE("Opening the file(%s) is failed : %d", path, ret);
483                 free(client_pkgid);
484                 return DATACONTROL_ERROR_IO_ERROR;
485         }
486         free(client_pkgid);
487
488         for (i = 0; i < add_value_count; ++i)
489         {
490                 int length = strlen(value_list[current_offset + i]);
491                 if (write(fd, &length, sizeof(int)) == -1)
492                 {
493                         LOGE("Writing a length to a file descriptor is failed. errno = %d", errno);
494                 }
495                 if (write(fd, value_list[current_offset + i], length) == -1)
496                 {
497                         LOGE("Writing a value_list to a file descriptor is failed. errno = %d", errno);
498                 }
499         }
500
501         fsync(fd);
502         close(fd);
503         return DATACONTROL_ERROR_NONE;
504 }
505
506 static char*
507 __get_result_file_path(bundle *b)
508 {
509         LOGI("__get_result_file_path");
510         const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID);
511         if (!caller)
512         {
513                 LOGE("caller appid is NULL.");
514                 return NULL;
515         }
516
517         const char *caller_req_id = bundle_get_val(b, OSP_K_REQUEST_ID);
518
519         char *result_path = calloc(RESULT_PATH_MAX, sizeof(char));
520
521         if (!result_path)
522         {
523                 LOGE("result path is NULL.");
524                 return NULL;
525         }
526         snprintf(result_path, RESULT_PATH_MAX, "%s%s%s", DATACONTROL_RESULT_FILE_PREFIX, caller, caller_req_id);
527
528         SECURE_LOGI("result file path: %s", result_path);
529
530         return result_path;
531 }
532
533 static bundle*
534 __set_result(bundle* b, datacontrol_request_type type, void* data)
535 {
536         bundle* res;
537         aul_create_result_bundle(b, &res);
538
539         // Set the type
540         char type_str[MAX_LEN_DATACONTROL_REQ_TYPE + 1] = {0,};
541         if (type == DATACONTROL_TYPE_UNDEFINED || type == DATACONTROL_TYPE_ERROR)
542         {
543                 char *request_type = (char*)bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
544                 strncpy(type_str, request_type, MAX_LEN_DATACONTROL_REQ_TYPE);
545                 LOGI("type is %s", type_str);
546         }
547         else
548         {
549                 snprintf(type_str, MAX_LEN_DATACONTROL_REQ_TYPE, "%d", (int)type);
550         }
551         bundle_add_str(res, OSP_K_DATACONTROL_REQUEST_TYPE, type_str);
552
553         // Set the provider id
554         char *provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
555         bundle_add_str(res, OSP_K_DATACONTROL_PROVIDER, provider_id);
556
557         // Set the data id
558         char *data_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_DATA);
559         bundle_add_str(res, OSP_K_DATACONTROL_DATA, data_id);
560
561         // Set the caller request id
562         char *request_id = (char*)bundle_get_val(b, OSP_K_REQUEST_ID);
563         bundle_add_str(res, OSP_K_REQUEST_ID, request_id);
564
565         switch(type)
566         {
567                 case DATACONTROL_TYPE_SQL_SELECT:
568                 {
569                         const char* list[3];
570
571                         list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
572                         list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
573
574                         char *path = __get_result_file_path(b);
575                         if (path != NULL)
576                         {
577                                 int ret = __set_select_result(b, path, data);
578                                 if (ret < 0)
579                                 {
580                                         memset(path, 0, RESULT_PATH_MAX);
581                                         strcpy(path, "NoResultSet");
582                                         LOGI("Empty ResultSet");
583                                 }
584                                 list[PACKET_INDEX_SELECT_RESULT_FILE] = path;
585                         }
586                         else
587                         {
588                                 list[PACKET_INDEX_SELECT_RESULT_FILE] = DATACONTROL_EMPTY;
589                         }
590
591                         bundle_add_str_array(res, OSP_K_ARG, list, 3);
592
593                         if (path != NULL)
594                         {
595                                 free(path);
596                         }
597
598                         break;
599                 }
600
601                 case DATACONTROL_TYPE_SQL_INSERT:
602                 {
603                         long long row_id = *(long long*)data;
604
605                         const char* list[3];
606                         list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
607                         list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
608
609                         // Set the row value
610                         char row_str[ROW_ID_SIZE] = {0,};
611                         snprintf(row_str, ROW_ID_SIZE, "%lld", row_id);
612
613                         list[PACKET_INDEX_ROW_ID] = row_str;
614
615                         bundle_add_str_array(res, OSP_K_ARG, list, 3);
616                         break;
617                 }
618                 case DATACONTROL_TYPE_SQL_UPDATE:
619                 case DATACONTROL_TYPE_SQL_DELETE:
620                 {
621                         const char* list[2];
622                         list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
623                         list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
624
625                         bundle_add_str_array(res, OSP_K_ARG, list, 2);
626                         break;
627                 }
628                 case DATACONTROL_TYPE_MAP_GET:
629                 {
630                         const char* list[4];
631
632                         list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
633                         list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
634
635                         char *path = __get_result_file_path(b);
636                         if (path != NULL)
637                         {
638                                 char **value_list = (char **)data;
639                                 __set_get_value_result(b, path, value_list);
640                                 list[PACKET_INDEX_VALUE_COUNT] = bundle_get_val(b, RESULT_VALUE_COUNT); // value count
641                                 list[PACKET_INDEX_GET_RESULT_FILE] = path;
642                         }
643                         else
644                         {
645                                 list[PACKET_INDEX_VALUE_COUNT] = 0;     // value count
646                                 list[PACKET_INDEX_GET_RESULT_FILE] = DATACONTROL_EMPTY;
647                         }
648
649                         bundle_add_str_array(res, OSP_K_ARG, list, 4);
650
651                         if (path != NULL)
652                         {
653                                 free(path);
654                         }
655
656                         break;
657                 }
658                 case DATACONTROL_TYPE_UNDEFINED:        // DATACONTROL_TYPE_MAP_SET || ADD || REMOVE
659                 {
660                         const char* list[2];
661                         list[PACKET_INDEX_REQUEST_RESULT] = "1";                // request result
662                         list[PACKET_INDEX_ERROR_MSG] = DATACONTROL_EMPTY;
663
664                         bundle_add_str_array(res, OSP_K_ARG, list, 2);
665                         break;
666                 }
667                 default:  // Error
668                 {
669                         const char* list[2];
670                         list[PACKET_INDEX_REQUEST_RESULT] = "0";                // request result
671                         list[PACKET_INDEX_ERROR_MSG] = (char*)data;  // error string
672
673                         bundle_add_str_array(res, OSP_K_ARG, list, 2);
674                         break;
675                 }
676         }
677
678         return res;
679 }
680
681 static int
682 __send_result(bundle* b, datacontrol_request_type type)
683 {
684         int ret = aul_send_service_result(b);
685
686         if (ret < 0)
687         {
688                 LOGE("Fail to send a result to caller");
689
690                 int index = 0;
691
692                 switch (type)
693                 {
694                         case DATACONTROL_TYPE_SQL_SELECT:
695                         {
696                                 index = PACKET_INDEX_SELECT_RESULT_FILE;
697                                 break;
698                         }
699                         case DATACONTROL_TYPE_MAP_GET:
700                         {
701                                 index = PACKET_INDEX_GET_RESULT_FILE;
702                                 break;
703                         }
704                         default:
705                         {
706                                 bundle_free(b);
707                                 return DATACONTROL_ERROR_IO_ERROR;
708                         }
709                 }
710
711                 int len = 0;
712                 const char **str_arr = bundle_get_str_array(b, OSP_K_ARG, &len);
713                 SECURE_LOGI("result file: %s (%d)", str_arr[index], index);
714                 ret = security_server_shared_file_delete(str_arr[index]);
715                 if (ret != SECURITY_SERVER_API_SUCCESS)
716                 {
717                         SECURE_LOGE("unable to remove the result file: %d", ret);
718                 }
719
720                 bundle_free(b);
721                 return DATACONTROL_ERROR_IO_ERROR;
722         }
723
724         bundle_free(b);
725         return DATACONTROL_ERROR_NONE;
726 }
727
728 int
729 __datacontrol_handler_cb(bundle *b, int request_id, void* data)
730 {
731         LOGI("datacontrol_handler_cb");
732
733         const char *request_type = bundle_get_val(b, OSP_K_DATACONTROL_REQUEST_TYPE);
734         if (request_type == NULL)
735         {
736                 LOGE("Invalid data control request");
737                 return DATACONTROL_ERROR_INVALID_PARAMETER;
738         }
739
740         // Get the request type
741         datacontrol_request_type type = atoi(request_type);
742         if (type >= DATACONTROL_TYPE_SQL_SELECT && type <= DATACONTROL_TYPE_SQL_DELETE)
743         {
744                 if (provider_sql_cb == NULL)
745                 {
746                         LOGE("SQL callback is not registered.");
747                         return DATACONTROL_ERROR_INVALID_PARAMETER;
748                 }
749         }
750         else if (type >= DATACONTROL_TYPE_MAP_GET && type <= DATACONTROL_TYPE_MAP_REMOVE)
751         {
752                 if (provider_map_cb == NULL)
753                 {
754                         LOGE("Map callback is not registered.");
755                         return DATACONTROL_ERROR_INVALID_PARAMETER;
756                 }
757         }
758         else
759         {
760                 LOGE("Invalid requeste type");
761                 return DATACONTROL_ERROR_INVALID_PARAMETER;
762         }
763
764         int len = 0;
765         const char **arg_list = bundle_get_str_array(b, OSP_K_ARG, &len);
766
767         datacontrol_h provider = malloc(sizeof(struct datacontrol_s));
768         if (provider == NULL) {
769                 LOGE("Fail to alloc provider");
770                 return DATACONTROL_ERROR_OUT_OF_MEMORY;
771         }
772
773         // Set the provider ID
774         provider->provider_id = (char*)bundle_get_val(b, OSP_K_DATACONTROL_PROVIDER);
775
776         // Set the data ID
777         provider->data_id = (char*)arg_list[PACKET_INDEX_DATAID];
778
779         // Set the request ID
780         int provider_req_id = __provider_new_request_id();
781
782         SECURE_LOGI("Provider ID: %s, data ID: %s, request type: %s", provider->provider_id, provider->data_id, request_type);
783
784         // Add the data to the table
785         int *key = malloc(sizeof(int));
786         if (key == NULL) {
787                 free(provider);
788                 LOGE("Fail to alloc key");
789                 return DATACONTROL_ERROR_OUT_OF_MEMORY;
790         }
791         *key = provider_req_id;
792
793         bundle *value = bundle_dup(b);
794         g_hash_table_insert(request_table, key, value);
795
796         switch (type)
797         {
798                 case DATACONTROL_TYPE_SQL_SELECT:
799                         {
800                                 int i = 1;
801                                 int current = 0;
802                                 int column_count = atoi(arg_list[i++]); // Column count
803
804                                 LOGI("SELECT column count: %d", column_count);
805
806                                 const char** column_list = (const char**)malloc(column_count * (sizeof(char *)));
807                                 if (column_list == NULL) {
808                                         free(provider);
809                                         LOGE("Fail to alloc column_list");
810                                         return DATACONTROL_ERROR_OUT_OF_MEMORY;
811                                 }
812
813                                 while (current < column_count)
814                                 {
815                                         column_list[current++] = arg_list[i++];  // Column data
816
817                                         LOGI("Column %d: %s", current, column_list[current-1]);
818                                 }
819
820                                 const char *where = arg_list[i++];  // where
821                                 const char *order = arg_list[i++];  // order
822
823                                 LOGI("where: %s, order: %s", where, order);
824
825                                 if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
826                                 {
827                                         where = NULL;
828                                 }
829
830                                 if (strncmp(order, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
831                                 {
832                                         order = NULL;
833                                 }
834
835                                 const char *page_number = arg_list[i++];
836                                 const char *per_page =  arg_list[i];
837
838                                 bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
839                                 bundle_add_str(value, MAX_COUNT_PER_PAGE, per_page);
840
841                                 provider_sql_cb->select(provider_req_id, provider, column_list, column_count, where, order, provider_sql_user_data);
842
843                                 free(column_list);
844
845                                 break;
846                         }
847                 case DATACONTROL_TYPE_SQL_INSERT:
848                 case DATACONTROL_TYPE_SQL_UPDATE:
849                         {
850                                 int column_count = atoi(arg_list[PACKET_INDEX_COLUMNCOUNT]);
851                                 const char *map_path = arg_list[PACKET_INDEX_MAP];
852
853                                 LOGI("INSERT / UPDATE handler");
854                                 SECURE_LOGI("Data path: %s, Column count: %d", map_path, column_count);
855
856                                 bundle* map = __get_data_map(map_path, column_count);
857
858                                 if (type == DATACONTROL_TYPE_SQL_INSERT)
859                                 {
860                                         SECURE_LOGI("INSERT column count: %d, map_path: %s", column_count, map_path);
861                                         provider_sql_cb->insert(provider_req_id, provider, map, provider_sql_user_data);
862                                 }
863                                 else
864                                 {
865                                         const char *where = arg_list[PACKET_INDEX_UPDATEWHERE];
866                                         LOGI("UPDATE from where: %s", where);
867
868                                         if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
869                                         {
870                                                 where = NULL;
871                                         }
872                                         provider_sql_cb->update(provider_req_id, provider, map, where, provider_sql_user_data);
873                                 }
874
875                                 bundle_free(map);
876                                 break;
877                         }
878                 case DATACONTROL_TYPE_SQL_DELETE:
879                         {
880                                 const char *where = arg_list[PACKET_INDEX_DELETEWHERE];
881
882                                 LOGI("DELETE from where: %s", where);
883                                 if (strncmp(where, DATACONTROL_EMPTY, strlen(DATACONTROL_EMPTY)) == 0)
884                                 {
885                                         where = NULL;
886                                 }
887                                 provider_sql_cb->delete(provider_req_id, provider, where, provider_sql_user_data);
888                                 break;
889                         }
890                 case DATACONTROL_TYPE_MAP_GET:
891                         {
892                                 const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
893                                 const char *page_number= arg_list[PACKET_INDEX_MAP_PAGE_NO];
894                                 const char *count_per_page =  arg_list[PACKET_INDEX_MAP_COUNT_PER_PAGE];
895                                 bundle_add_str(value, RESULT_PAGE_NUMBER, page_number);
896                                 bundle_add_str(value, MAX_COUNT_PER_PAGE, count_per_page);
897
898                                 LOGI("Gets the value list related with the key(%s) from Map datacontrol. ", map_key);
899
900                                 provider_map_cb->get(provider_req_id, provider, map_key, provider_map_user_data);
901                                 break;
902                         }
903                 case DATACONTROL_TYPE_MAP_SET:
904                         {
905                                 const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
906                                 const char *old_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
907                                 const char *new_value = arg_list[PACKET_INDEX_MAP_VALUE_2ND];
908
909                                 LOGI("Sets the old value(%s) of the key(%s) to the new value(%s) in Map datacontrol.", old_value, map_key, new_value);
910
911                                 provider_map_cb->set(provider_req_id, provider, map_key, old_value, new_value, provider_map_user_data);
912                                 break;
913                         }
914                 case DATACONTROL_TYPE_MAP_ADD:
915                         {
916                                 const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
917                                 const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
918
919                                 LOGI("Adds the %s-%s in Map datacontrol.", map_key, map_value);
920
921                                 provider_map_cb->add(provider_req_id, provider, map_key, map_value, provider_map_user_data);
922                                 break;
923                         }
924                 case DATACONTROL_TYPE_MAP_REMOVE:
925                         {
926                                 const char *map_key = arg_list[PACKET_INDEX_MAP_KEY];
927                                 const char *map_value = arg_list[PACKET_INDEX_MAP_VALUE_1ST];
928
929                                 LOGI("Removes the %s-%s in Map datacontrol.", map_key, map_value);
930
931                                 provider_map_cb->remove(provider_req_id, provider, map_key, map_value, provider_map_user_data);
932                                 break;
933                         }
934                 default:
935                                 break;
936         }
937
938         free(provider);
939
940         return DATACONTROL_ERROR_NONE;
941 }
942
943 int
944 datacontrol_provider_sql_register_cb(datacontrol_provider_sql_cb *callback, void *user_data)
945 {
946         int ret = DATACONTROL_ERROR_NONE;
947
948         if (callback == NULL)
949         {
950                 return DATACONTROL_ERROR_INVALID_PARAMETER;
951         }
952
953         if (request_table == NULL)
954         {
955                 __initialize_provider();
956         }
957
958         LOGI("datacontrol_provider_sql_register_cb");
959
960         provider_sql_cb = callback;
961         provider_sql_user_data = user_data;
962
963         if (provider_map_cb == NULL)    // If the provider_map_cb was registered(not NULL), __datacontrol_handler_cb is set already.
964         {
965                 ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
966         }
967
968         return ret;
969 }
970
971 int
972 datacontrol_provider_sql_unregister_cb(void)
973 {
974         if (provider_map_cb == NULL)    // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible.
975         {
976                 aul_unset_data_control_provider_cb();
977         }
978         provider_sql_cb = NULL;
979         provider_sql_user_data = NULL;
980
981         return DATACONTROL_ERROR_NONE;
982 }
983
984 int datacontrol_provider_map_register_cb(datacontrol_provider_map_cb *callback, void *user_data)
985 {
986         int ret = DATACONTROL_ERROR_NONE;
987
988         if (callback == NULL)
989         {
990                 return DATACONTROL_ERROR_INVALID_PARAMETER;
991         }
992
993         if (request_table == NULL)
994         {
995                 __initialize_provider();
996         }
997
998         LOGI("datacontrol_provider_map_register_cb");
999
1000         provider_map_cb = callback;
1001         provider_map_user_data = user_data;
1002
1003         if (provider_sql_cb == NULL)    // If the provider_sql_cb was registered(not NULL), __datacontrol_handler_cb is set already.
1004         {
1005                 ret = aul_set_data_control_provider_cb(__datacontrol_handler_cb);
1006         }
1007
1008         return ret;
1009 }
1010
1011 int datacontrol_provider_map_unregister_cb(void)
1012 {
1013         if (provider_sql_cb == NULL)    // When both SQL_cb and Map_cb are unregisted, unsetting the provider cb is possible.
1014         {
1015                 aul_unset_data_control_provider_cb();
1016         }
1017         provider_map_cb = NULL;
1018         provider_map_user_data = NULL;
1019
1020         return DATACONTROL_ERROR_NONE;
1021 }
1022
1023 int
1024 datacontrol_provider_get_client_appid(int request_id, char **appid)
1025 {
1026         if (request_table == NULL)
1027         {
1028                 __initialize_provider();
1029         }
1030
1031         bundle* b = g_hash_table_lookup(request_table, &request_id);
1032         if (!b)
1033         {
1034                 SECURE_LOGE("No data for the request id: %d", request_id);
1035                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1036         }
1037
1038         const char *caller = bundle_get_val(b, AUL_K_CALLER_APPID);
1039         if (!caller)
1040         {
1041                 SECURE_LOGE("No appid for the request id: %d", request_id);
1042                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1043         }
1044
1045         SECURE_LOGI("Request ID: %d, caller appid: %s", request_id, caller);
1046
1047         *appid = strdup(caller);
1048
1049         return DATACONTROL_ERROR_NONE;
1050 }
1051
1052 int
1053 datacontrol_provider_send_select_result(int request_id, void *db_handle)
1054 {
1055         SECURE_LOGI("Send a select result for request id: %d", request_id);
1056
1057         if (request_table == NULL)
1058         {
1059                 __initialize_provider();
1060         }
1061
1062         bundle* b = g_hash_table_lookup(request_table, &request_id);
1063         if (!b)
1064         {
1065                 SECURE_LOGE("No data for the request id: %d", request_id);
1066                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1067         }
1068
1069         bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_SELECT, db_handle);
1070
1071         return __send_result(res, DATACONTROL_TYPE_SQL_SELECT);
1072 }
1073
1074 int
1075 datacontrol_provider_send_insert_result(int request_id, long long row_id)
1076 {
1077         SECURE_LOGI("Send an insert result for request id: %d", request_id);
1078
1079         if (request_table == NULL)
1080         {
1081                 __initialize_provider();
1082         }
1083
1084         bundle* b = g_hash_table_lookup(request_table, &request_id);
1085         if (!b)
1086         {
1087                 SECURE_LOGE("No data for the request id: %d", request_id);
1088                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1089         }
1090
1091         bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_INSERT, (void*)&row_id);
1092
1093         return __send_result(res, DATACONTROL_TYPE_SQL_INSERT);
1094 }
1095
1096 int
1097 datacontrol_provider_send_update_result(int request_id)
1098 {
1099         SECURE_LOGI("Send an update result for request id: %d", request_id);
1100
1101         if (request_table == NULL)
1102         {
1103                 __initialize_provider();
1104         }
1105
1106         bundle* b = g_hash_table_lookup(request_table, &request_id);
1107         if (!b)
1108         {
1109                 SECURE_LOGE("No data for the request id: %d", request_id);
1110                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1111         }
1112
1113         bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_UPDATE, NULL);
1114
1115         return __send_result(res, DATACONTROL_TYPE_SQL_UPDATE);
1116 }
1117
1118 int
1119 datacontrol_provider_send_delete_result(int request_id)
1120 {
1121         SECURE_LOGI("Send a delete result for request id: %d", request_id);
1122
1123         if (request_table == NULL)
1124         {
1125                 __initialize_provider();
1126         }
1127
1128         bundle* b = g_hash_table_lookup(request_table, &request_id);
1129         if (!b)
1130         {
1131                 SECURE_LOGE("No data for the request id: %d", request_id);
1132                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1133         }
1134
1135         bundle* res = __set_result(b, DATACONTROL_TYPE_SQL_DELETE, NULL);
1136
1137         return __send_result(res, DATACONTROL_TYPE_SQL_DELETE);
1138 }
1139
1140 int
1141 datacontrol_provider_send_error(int request_id, const char *error)
1142 {
1143         SECURE_LOGI("Send an error for request id: %d", request_id);
1144
1145         if (request_table == NULL)
1146         {
1147                 __initialize_provider();
1148         }
1149
1150         bundle* b = g_hash_table_lookup(request_table, &request_id);
1151         if (!b)
1152         {
1153                 SECURE_LOGE("No data for the request id: %d", request_id);
1154                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1155         }
1156
1157         bundle* res = __set_result(b, DATACONTROL_TYPE_ERROR, (void*)error);
1158
1159         return __send_result(res, DATACONTROL_TYPE_ERROR);
1160 }
1161
1162 int
1163 datacontrol_provider_send_map_result(int request_id)
1164 {
1165         SECURE_LOGI("Send a set/add/remove result for request id: %d", request_id);
1166
1167         if (request_table == NULL)
1168         {
1169                 __initialize_provider();
1170         }
1171
1172         bundle* b = g_hash_table_lookup(request_table, &request_id);
1173         if (!b)
1174         {
1175                 SECURE_LOGE("No data for the request id: %d", request_id);
1176                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1177         }
1178
1179         bundle* res = __set_result(b, DATACONTROL_TYPE_UNDEFINED, NULL);
1180
1181         return __send_result(res, DATACONTROL_TYPE_UNDEFINED);
1182 }
1183
1184 int
1185 datacontrol_provider_send_map_get_value_result(int request_id, char **value_list, int value_count)
1186 {
1187         SECURE_LOGI("Send a get result for request id: %d", request_id);
1188
1189         if (request_table == NULL)
1190         {
1191                 __initialize_provider();
1192         }
1193
1194         bundle* b = g_hash_table_lookup(request_table, &request_id);
1195         if (!b)
1196         {
1197                 SECURE_LOGE("No data for the request id: %d", request_id);
1198                 return DATACONTROL_ERROR_INVALID_PARAMETER;
1199         }
1200
1201         char value_count_str[32] = {0,};
1202         snprintf(value_count_str, 32, "%d", value_count);
1203         bundle_add_str(b, RESULT_VALUE_COUNT, value_count_str);
1204
1205         bundle* res = __set_result(b, DATACONTROL_TYPE_MAP_GET, value_list);
1206
1207         return __send_result(res, DATACONTROL_TYPE_MAP_GET);
1208 }