Remove a logic to check TIDL privileges
[platform/core/uifw/voice-control.git] / common / vc_command.c
1 /*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18
19 #include <cynara-client.h>
20 #include <cynara-error.h>
21 #include <cynara-session.h>
22 #include <libintl.h>
23 #include <stdlib.h>
24 #include <system_info.h>
25
26 #include "vc_command.h"
27 #include "vc_info_parser.h"
28 #include "vc_main.h"
29 #include "vc_regex_rule.h"
30 #include "vc_config_mgr.h"
31 #include "voice_control_command.h"
32 #include "voice_control_command_expand.h"
33 #include "voice_control_common.h"
34 #include "voice_control_key_defines.h"
35
36 static pthread_mutex_t g_cmd_mutex = PTHREAD_MUTEX_INITIALIZER;
37 static pthread_mutex_t g_cmd_list_mutex = PTHREAD_MUTEX_INITIALIZER;
38 #define CMD_MUTEX_LOCK()        pthread_mutex_lock(&g_cmd_mutex)
39 #define CMD_MUTEX_UNLOCK()      pthread_mutex_unlock(&g_cmd_mutex)
40 #define CMD_LIST_MUTEX_LOCK()   pthread_mutex_lock(&g_cmd_list_mutex)
41 #define CMD_LIST_MUTEX_UNLOCK() pthread_mutex_unlock(&g_cmd_list_mutex)
42
43 static int g_feature_enabled = -1;
44 static bool g_privilege_allowed = false;
45
46 static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
47 static cynara *p_cynara = NULL;
48 static GList *g_cmd_list = NULL;
49 static GList *g_cmdlist_list = NULL;
50
51
52 // For getting timestamp using regular expression
53 static regex_t reg[MAX_NUM_REGEX];
54 static time_t t_now;            //time_t is based on UTC
55 static struct tm td_now;        //if use localtime function, the value follows the local time zone, otherwise it follows the UTC.
56
57 static int g_time_flag;
58 static int g_date_flag;
59
60 static int g_data_sidx;
61 static int g_data_eidx;
62
63 static int __vc_cmd_get_feature_enabled()
64 {
65         if (0 == g_feature_enabled) {
66                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Voice control feature NOT supported");
67                 return VC_ERROR_NOT_SUPPORTED;
68         } else if (-1 == g_feature_enabled) {
69                 bool vc_supported = false;
70                 bool mic_supported = false;
71                 if (0 == system_info_get_platform_bool(VC_FEATURE_PATH, &vc_supported)) {
72                         if (0 == system_info_get_platform_bool(VC_MIC_FEATURE_PATH, &mic_supported)) {
73                                 if (false == vc_supported || false == mic_supported) {
74                                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Voice control feature NOT supported");
75                                         g_feature_enabled = 0;
76                                         return VC_ERROR_NOT_SUPPORTED;
77                                 }
78
79                                 g_feature_enabled = 1;
80                         } else {
81                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get feature value");
82                                 return VC_ERROR_NOT_SUPPORTED;
83                         }
84                 } else {
85                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get feature value");
86                         return VC_ERROR_NOT_SUPPORTED;
87                 }
88         }
89
90         return VC_ERROR_NONE;
91 }
92
93 static int __check_privilege_initialize()
94 {
95         int ret = cynara_initialize(&p_cynara, NULL);
96         if (CYNARA_API_SUCCESS != ret)
97                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to initialize");
98
99         return ret == CYNARA_API_SUCCESS;
100 }
101
102 static int __check_privilege(const char* uid, const char * privilege)
103 {
104         FILE *fp = NULL;
105         char label_path[1024] = "/proc/self/attr/current";
106         char smack_label[1024] = {'\0',};
107
108         if (!p_cynara) {
109                 return false;
110         }
111
112         fp = fopen(label_path, "r");
113         if (fp != NULL) {
114                 if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
115                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread");
116
117                 fclose(fp);
118         }
119
120         pid_t pid = getpid();
121         char *session = cynara_session_from_pid(pid);
122         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
123         SLOG(LOG_DEBUG, TAG_VCCMD, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
124         if (session)
125                 free(session);
126
127         if (ret != CYNARA_API_ACCESS_ALLOWED)
128                 return false;
129         return true;
130 }
131
132 static void __check_privilege_deinitialize()
133 {
134         if (p_cynara)
135         {
136                 int ret = cynara_finish(p_cynara);
137                 if (ret != CYNARA_API_SUCCESS)
138                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] cynara finish %d", ret);
139         }
140         p_cynara = NULL;
141 }
142
143 static int __vc_cmd_check_privilege()
144 {
145         if (true == g_privilege_allowed)
146                 return VC_ERROR_NONE;
147
148         pthread_mutex_lock(&g_cynara_mutex);
149
150         if (false == g_privilege_allowed) {
151                 bool ret = true;
152                 ret = __check_privilege_initialize();
153                 if (false == ret) {
154                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] privilege initialize is failed");
155                         g_privilege_allowed = false;
156                         pthread_mutex_unlock(&g_cynara_mutex);
157                         return VC_ERROR_PERMISSION_DENIED;
158                 }
159
160                 char uid[32];
161                 snprintf(uid, 32, "%d", getuid());
162                 ret = true;
163                 ret = __check_privilege(uid, VC_PRIVILEGE_RECORDER);
164                 if (false == ret) {
165                         //LCOV_EXCL_START
166                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_RECORDER, uid);
167                         __check_privilege_deinitialize();
168                         g_privilege_allowed = false;
169                         pthread_mutex_unlock(&g_cynara_mutex);
170                         return VC_ERROR_PERMISSION_DENIED;
171                         //LCOV_EXCL_STOP
172                 }
173
174                 __check_privilege_deinitialize();
175         }
176
177         g_privilege_allowed = true;
178         pthread_mutex_unlock(&g_cynara_mutex);
179         return VC_ERROR_NONE;
180 }
181
182 int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list)
183 {
184         if (0 != __vc_cmd_get_feature_enabled()) {
185                 return VC_ERROR_NOT_SUPPORTED;
186         }
187         if (0 != __vc_cmd_check_privilege()) {
188                 return VC_ERROR_PERMISSION_DENIED;
189         }
190
191         CMD_LIST_MUTEX_LOCK();
192
193         if (NULL == vc_cmd_list) {
194                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
195                 CMD_LIST_MUTEX_UNLOCK();
196                 return VC_ERROR_INVALID_PARAMETER;
197         }
198
199         vc_cmd_list_s* list = (vc_cmd_list_s*)calloc(1, sizeof(vc_cmd_list_s));
200
201         if (NULL == list) {
202                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
203                 CMD_LIST_MUTEX_UNLOCK();
204                 return VC_ERROR_OUT_OF_MEMORY;
205         }
206
207         list->index = -1;
208         list->list = NULL;
209
210         *vc_cmd_list = (vc_cmd_list_h)list;
211
212         g_cmdlist_list = g_list_append(g_cmdlist_list, list);
213
214         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p)", *vc_cmd_list);
215
216         CMD_LIST_MUTEX_UNLOCK();
217         return VC_ERROR_NONE;
218 }
219
220 int vc_cmd_list_destroy(vc_cmd_list_h vc_cmd_list, bool release_command)
221 {
222         if (0 != __vc_cmd_get_feature_enabled()) {
223                 return VC_ERROR_NOT_SUPPORTED;
224         }
225         if (0 != __vc_cmd_check_privilege()) {
226                 return VC_ERROR_PERMISSION_DENIED;
227         }
228
229         CMD_LIST_MUTEX_LOCK();
230
231         if (NULL == vc_cmd_list) {
232                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
233                 CMD_LIST_MUTEX_UNLOCK();
234                 return VC_ERROR_INVALID_PARAMETER;
235         }
236
237
238         vc_cmd_list_s* list = NULL;
239         list = (vc_cmd_list_s*)vc_cmd_list;
240
241         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p)", list);
242
243         GList *iter = NULL;
244         iter = g_list_find(g_cmdlist_list, list);
245         if (NULL == iter) {
246                 SLOG(LOG_ERROR, TAG_VCCMD, "Fail to destroy client : handle is not valid");
247                 CMD_LIST_MUTEX_UNLOCK();
248                 return VC_ERROR_INVALID_PARAMETER;
249         }
250
251         g_cmdlist_list = g_list_delete_link(g_cmdlist_list, iter);
252
253         vc_cmd_list_remove_all((vc_cmd_list_h)list, release_command);
254         free(list);
255         list = NULL;
256
257         SLOG(LOG_DEBUG, TAG_VCCMD, "Client destroy");
258
259         CMD_LIST_MUTEX_UNLOCK();
260         return VC_ERROR_NONE;
261 }
262
263 int vc_cmd_list_get_count(vc_cmd_list_h vc_cmd_list, int* count)
264 {
265         if (0 != __vc_cmd_get_feature_enabled()) {
266                 return VC_ERROR_NOT_SUPPORTED;
267         }
268         if (0 != __vc_cmd_check_privilege()) {
269                 return VC_ERROR_PERMISSION_DENIED;
270         }
271
272         if (NULL == vc_cmd_list || NULL == count) {
273                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Get command count : Input parameter is NULL");
274                 return VC_ERROR_INVALID_PARAMETER;
275         }
276
277         vc_cmd_list_s* list = NULL;
278         list = (vc_cmd_list_s*)vc_cmd_list;
279
280         *count = g_slist_length(list->list);
281
282         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), count(%d)", list, *count);
283
284         return VC_ERROR_NONE;
285 }
286
287 int vc_cmd_list_add(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
288 {
289         if (0 != __vc_cmd_get_feature_enabled()) {
290                 return VC_ERROR_NOT_SUPPORTED;
291         }
292         if (0 != __vc_cmd_check_privilege()) {
293                 return VC_ERROR_PERMISSION_DENIED;
294         }
295
296         if (NULL == vc_cmd_list || NULL == vc_command) {
297                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
298                 return VC_ERROR_INVALID_PARAMETER;
299         }
300
301         vc_cmd_list_s* list = NULL;
302         list = (vc_cmd_list_s*)vc_cmd_list;
303
304         vc_cmd_s* cmd = NULL;
305         cmd = (vc_cmd_s*)vc_command;
306
307         list->list = g_slist_append(list->list, cmd);
308
309         if (1 == g_slist_length(list->list)) {
310                 list->index = 0;
311         }
312
313         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), command(%p)", list, cmd);
314
315         return VC_ERROR_NONE;
316 }
317
318 int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
319 {
320         if (0 != __vc_cmd_get_feature_enabled()) {
321                 return VC_ERROR_NOT_SUPPORTED;
322         }
323         if (0 != __vc_cmd_check_privilege()) {
324                 return VC_ERROR_PERMISSION_DENIED;
325         }
326
327         if (NULL == vc_cmd_list || NULL == vc_command) {
328                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
329                 return VC_ERROR_INVALID_PARAMETER;
330         }
331
332         vc_cmd_list_s* list = NULL;
333         list = (vc_cmd_list_s*)vc_cmd_list;
334
335         vc_cmd_s* cmd = NULL;
336         cmd = (vc_cmd_s*)vc_command;
337
338         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), command(%p)", list, cmd);
339
340         GSList *iter = NULL;
341         iter = g_slist_find(list->list, cmd);
342         if (NULL == iter) {
343                 SLOG(LOG_ERROR, TAG_VCCMD, "Fail to destroy command : handle is not valid");
344                 return VC_ERROR_INVALID_PARAMETER;
345         }
346
347         list->list = g_slist_remove_link(list->list, iter);
348         SLOG(LOG_DEBUG, TAG_VCCMD, "destroy command");
349
350         int len = g_slist_length(list->list);
351         if (0 == len)
352                 list->index = -1;
353         else if (list->index == len)
354                 list->index = len - 1;
355
356         return VC_ERROR_NONE;
357 }
358
359 static void __vc_cmd_list_remove_all_foreach(gpointer data, gpointer user_data)
360 {
361         vc_cmd_s *temp = NULL;
362         temp = data;
363         if (temp) {
364                 SLOG(LOG_DEBUG, TAG_VCCMD, "Free command(%p)", temp);
365                 vc_cmd_destroy((vc_cmd_h)temp);
366                 temp = NULL;
367         }
368         return;
369 }
370
371 int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool release_command)
372 {
373         if (0 != __vc_cmd_get_feature_enabled()) {
374                 return VC_ERROR_NOT_SUPPORTED;
375         }
376         if (0 != __vc_cmd_check_privilege()) {
377                 return VC_ERROR_PERMISSION_DENIED;
378         }
379
380         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Destroy all command");
381
382         if (NULL == vc_cmd_list) {
383                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
384                 return VC_ERROR_INVALID_PARAMETER;
385         }
386
387         vc_cmd_list_s* list = NULL;
388         list = (vc_cmd_list_s*)vc_cmd_list;
389
390         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), release command (%s)"
391                  , list, release_command ? "true" : "false");
392
393         if (true == release_command) {
394                 if (list->list) {
395                         g_slist_foreach(list->list, __vc_cmd_list_remove_all_foreach, NULL);
396                         g_slist_free(list->list);
397                         list->list = NULL;
398                 }
399                 list->index = -1;
400         }
401
402         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
403
404         return VC_ERROR_NONE;
405 }
406
407 int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data)
408 {
409         if (0 != __vc_cmd_get_feature_enabled()) {
410                 return VC_ERROR_NOT_SUPPORTED;
411         }
412         if (0 != __vc_cmd_check_privilege()) {
413                 return VC_ERROR_PERMISSION_DENIED;
414         }
415
416         if (NULL == vc_cmd_list) {
417                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
418                 return VC_ERROR_INVALID_PARAMETER;
419         }
420
421         vc_cmd_list_s* list = NULL;
422         list = (vc_cmd_list_s*)vc_cmd_list;
423
424         GSList *iter = NULL;
425         iter = g_slist_nth(list->list, 0);
426         while (NULL != iter) {
427                 vc_cmd_s *temp_cmd = NULL;
428                 temp_cmd = iter->data;
429                 if (NULL == temp_cmd) {
430                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
431                         return VC_ERROR_OPERATION_FAILED;
432                 }
433                 if (false == callback((vc_cmd_h)temp_cmd, user_data))
434                         break;
435
436                 iter = g_slist_next(iter);
437         }
438
439         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Foreach commands Done");
440
441         return VC_ERROR_NONE;
442 }
443
444 int vc_cmd_list_filter_by_type(vc_cmd_list_h original, int type, vc_cmd_list_h* filtered)
445 {
446         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Filter by type");
447
448         if (0 != __vc_cmd_get_feature_enabled()) {
449                 return VC_ERROR_NOT_SUPPORTED;
450         }
451         if (0 != __vc_cmd_check_privilege()) {
452                 return VC_ERROR_PERMISSION_DENIED;
453         }
454
455         if (NULL == original) {
456                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
457                 return VC_ERROR_INVALID_PARAMETER;
458         }
459
460         if (VC_COMMAND_TYPE_NONE >= type || VC_COMMAND_TYPE_EXCLUSIVE < type) {
461                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid type");
462                 return VC_ERROR_INVALID_PARAMETER;
463         }
464
465         vc_cmd_list_s* list = NULL;
466         list = (vc_cmd_list_s*)original;
467
468         vc_cmd_list_h temp_list;
469         if (0 != vc_cmd_list_create(&temp_list)) {
470                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to list create");
471                 return VC_ERROR_OPERATION_FAILED;
472         }
473
474         GSList *iter = NULL;
475         iter = g_slist_nth(list->list, 0);
476         while (NULL != iter) {
477                 vc_cmd_s *iter_cmd = NULL;
478                 iter_cmd = iter->data;
479                 if (NULL == iter_cmd) {
480                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
481                         return VC_ERROR_OPERATION_FAILED;
482                 }
483
484                 int iter_type = 0;
485                 if (0 != vc_cmd_get_type((vc_cmd_h)iter_cmd, &iter_type)) {
486                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command type");
487                         continue;
488                 }
489
490                 if (iter_type == type) {
491                         vc_cmd_h temp_cmd;
492                         if (0 != vc_cmd_create(&temp_cmd)) {
493                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to create cmd");
494                                 continue;
495                         }
496
497                         memcpy(temp_cmd, iter_cmd, sizeof(vc_cmd_s));
498                         if (NULL != iter_cmd->command)
499                                 ((vc_cmd_s *)temp_cmd)->command = strdup(iter_cmd->command);
500                         if (NULL != iter_cmd->parameter)
501                                 ((vc_cmd_s *)temp_cmd)->parameter = strdup(iter_cmd->parameter);
502
503                         if (0 != vc_cmd_list_add(temp_list, temp_cmd)) {
504                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to cmd list add");
505                                 vc_cmd_destroy(temp_cmd);
506                                 continue;
507                         }
508                 }
509                 iter = g_slist_next(iter);
510         }
511
512         int count = 0;
513         if (0 != vc_cmd_list_get_count(temp_list, &count)) {
514                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get count");
515         } else {
516                 SLOG(LOG_DEBUG, TAG_VCCMD, "Filtering result : (%d) command", count);
517         }
518
519         *filtered = temp_list;
520
521         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
522
523         return VC_ERROR_NONE;
524 }
525
526 int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list)
527 {
528         if (0 != __vc_cmd_get_feature_enabled()) {
529                 return VC_ERROR_NOT_SUPPORTED;
530         }
531         if (0 != __vc_cmd_check_privilege()) {
532                 return VC_ERROR_PERMISSION_DENIED;
533         }
534
535         if (NULL == vc_cmd_list) {
536                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
537                 return VC_ERROR_INVALID_PARAMETER;
538         }
539
540         vc_cmd_list_s* list = NULL;
541         list = (vc_cmd_list_s*)vc_cmd_list;
542
543         if (0 == g_slist_length(list->list)) {
544                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
545                 return VC_ERROR_EMPTY;
546         }
547
548         list->index = 0;
549
550         return VC_ERROR_NONE;
551 }
552
553 int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list)
554 {
555         if (0 != __vc_cmd_get_feature_enabled()) {
556                 return VC_ERROR_NOT_SUPPORTED;
557         }
558         if (0 != __vc_cmd_check_privilege()) {
559                 return VC_ERROR_PERMISSION_DENIED;
560         }
561
562         if (NULL == vc_cmd_list) {
563                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
564                 return VC_ERROR_INVALID_PARAMETER;
565         }
566
567         vc_cmd_list_s* list = NULL;
568         list = (vc_cmd_list_s*)vc_cmd_list;
569
570         int count = g_slist_length(list->list);
571
572         if (0 == count) {
573                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
574                 return VC_ERROR_EMPTY;
575         } else {
576                 list->index = count - 1;
577                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
578         }
579
580         return VC_ERROR_NONE;
581 }
582
583 int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
584 {
585         if (0 != __vc_cmd_get_feature_enabled()) {
586                 return VC_ERROR_NOT_SUPPORTED;
587         }
588         if (0 != __vc_cmd_check_privilege()) {
589                 return VC_ERROR_PERMISSION_DENIED;
590         }
591
592         if (NULL == vc_cmd_list) {
593                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
594                 return VC_ERROR_INVALID_PARAMETER;
595         }
596
597         vc_cmd_list_s* list = NULL;
598         list = (vc_cmd_list_s*)vc_cmd_list;
599
600         int count = g_slist_length(list->list);
601
602         if (list->index < count - 1) {
603                 list->index = list->index + 1;
604                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
605         } else {
606                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
607                 return VC_ERROR_ITERATION_END;
608         }
609
610         return VC_ERROR_NONE;
611 }
612
613 int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
614 {
615         if (0 != __vc_cmd_get_feature_enabled()) {
616                 return VC_ERROR_NOT_SUPPORTED;
617         }
618         if (0 != __vc_cmd_check_privilege()) {
619                 return VC_ERROR_PERMISSION_DENIED;
620         }
621
622         if (NULL == vc_cmd_list) {
623                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
624                 return VC_ERROR_INVALID_PARAMETER;
625         }
626
627         vc_cmd_list_s* list = NULL;
628         list = (vc_cmd_list_s*)vc_cmd_list;
629
630         if (list->index > 0) {
631                 list->index = list->index - 1;
632                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
633         } else {
634                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
635                 return VC_ERROR_ITERATION_END;
636         }
637
638         return VC_ERROR_NONE;
639 }
640
641 int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command)
642 {
643         if (0 != __vc_cmd_get_feature_enabled()) {
644                 return VC_ERROR_NOT_SUPPORTED;
645         }
646         if (0 != __vc_cmd_check_privilege()) {
647                 return VC_ERROR_PERMISSION_DENIED;
648         }
649
650         if (NULL == vc_cmd_list || NULL == vc_command) {
651                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
652                 return VC_ERROR_INVALID_PARAMETER;
653         }
654
655         vc_cmd_list_s* list = NULL;
656         list = (vc_cmd_list_s*)vc_cmd_list;
657
658         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), index (%d)", list, list->index);
659
660         if (0 == g_slist_length(list->list)) {
661                 SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list is empty");
662                 *vc_command = NULL;
663                 return VC_ERROR_EMPTY;
664         }
665
666         vc_cmd_s *temp_cmd = NULL;
667         temp_cmd = g_slist_nth_data(list->list, list->index);
668
669         *vc_command = (vc_cmd_h)temp_cmd;
670
671         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] Get current command (%p)", *vc_command);
672
673         return VC_ERROR_NONE;
674 }
675
676
677 int vc_cmd_create(vc_cmd_h* vc_command)
678 {
679         if (0 != __vc_cmd_get_feature_enabled()) {
680                 return VC_ERROR_NOT_SUPPORTED;
681         }
682         if (0 != __vc_cmd_check_privilege()) {
683                 return VC_ERROR_PERMISSION_DENIED;
684         }
685
686         CMD_MUTEX_LOCK();
687
688         if (NULL == vc_command) {
689                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
690                 CMD_MUTEX_UNLOCK();
691                 return VC_ERROR_INVALID_PARAMETER;
692         }
693
694         vc_cmd_s* command = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s));
695
696         if (NULL == command) {
697                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
698                 CMD_MUTEX_UNLOCK();
699                 return VC_ERROR_OUT_OF_MEMORY;
700         }
701
702         command->pid = 0;
703         command->id = 0;
704         command->index = 0;
705         command->type = VC_COMMAND_TYPE_NONE;
706         command->format = VC_CMD_FORMAT_FIXED;
707         command->command = NULL;
708         command->parameter = NULL;
709         command->domain = 0;
710         command->priority = 0;
711         command->key = VC_KEY_NONE;
712         command->modifier = VC_MODIFIER_NONE;
713         command->invocation_name = NULL;
714         command->appid = NULL;
715         command->fixed = NULL;
716         command->coordinates = NULL;
717
718         *vc_command = (vc_cmd_h)command;
719
720         g_cmd_list = g_list_append(g_cmd_list, command);
721
722         SLOG(LOG_DEBUG, TAG_VCCMD, "[Create command][%p]", *vc_command);
723
724         CMD_MUTEX_UNLOCK();
725         return VC_ERROR_NONE;
726 }
727
728 int vc_cmd_destroy(vc_cmd_h vc_command)
729 {
730         if (0 != __vc_cmd_get_feature_enabled()) {
731                 return VC_ERROR_NOT_SUPPORTED;
732         }
733         if (0 != __vc_cmd_check_privilege()) {
734                 return VC_ERROR_PERMISSION_DENIED;
735         }
736
737         CMD_MUTEX_LOCK();
738
739         if (NULL == vc_command) {
740                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
741                 CMD_MUTEX_UNLOCK();
742                 return VC_ERROR_INVALID_PARAMETER;
743         }
744
745         vc_cmd_s* command = NULL;
746         command = (vc_cmd_s*)vc_command;
747
748         SLOG(LOG_DEBUG, TAG_VCCMD, "[Destroy command][%p]", command);
749
750         GList *iter = NULL;
751         iter = g_list_find(g_cmd_list, command);
752         if (NULL == iter) {
753                 SLOG(LOG_ERROR, TAG_VCCMD, "Fail to command destroy : handle is not valid");
754                 CMD_MUTEX_UNLOCK();
755                 return VC_ERROR_INVALID_PARAMETER;
756         }
757
758         g_cmd_list = g_list_delete_link(g_cmd_list, iter);
759
760         if (command->command)
761                 free(command->command);
762         command->command = NULL;
763         if (command->parameter)
764                 free(command->parameter);
765         command->parameter = NULL;
766         if (command->invocation_name)
767                 free(command->invocation_name);
768         command->invocation_name = NULL;
769         if (command->appid)
770                 free(command->appid);
771         command->appid = NULL;
772         if (command->fixed)
773                 free(command->fixed);
774         command->fixed = NULL;
775         if (command->coordinates)
776                 free(command->coordinates);
777         command->coordinates = NULL;
778         free(command);
779         command = NULL;
780
781         CMD_MUTEX_UNLOCK();
782         return VC_ERROR_NONE;
783 }
784
785 int vc_cmd_set_id(vc_cmd_h vc_command, int id)
786 {
787         if (0 != __vc_cmd_get_feature_enabled()) {
788                 return VC_ERROR_NOT_SUPPORTED;
789         }
790         if (0 != __vc_cmd_check_privilege()) {
791                 return VC_ERROR_PERMISSION_DENIED;
792         }
793
794         if (NULL == vc_command) {
795                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
796                 return VC_ERROR_INVALID_PARAMETER;
797         }
798
799         vc_cmd_s* cmd = NULL;
800         cmd = (vc_cmd_s*)vc_command;
801
802         cmd->id = id;
803         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
804
805         return VC_ERROR_NONE;
806 }
807
808 int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
809 {
810         if (0 != __vc_cmd_get_feature_enabled()) {
811                 return VC_ERROR_NOT_SUPPORTED;
812         }
813         if (0 != __vc_cmd_check_privilege()) {
814                 return VC_ERROR_PERMISSION_DENIED;
815         }
816
817         if (NULL == vc_command || NULL == id) {
818                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
819                 return VC_ERROR_INVALID_PARAMETER;
820         }
821
822         vc_cmd_s* cmd = NULL;
823         cmd = (vc_cmd_s*)vc_command;
824
825         *id = cmd->id;
826         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
827
828         return VC_ERROR_NONE;
829 }
830
831 int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid)
832 {
833         if (0 != __vc_cmd_get_feature_enabled()) {
834                 return VC_ERROR_NOT_SUPPORTED;
835         }
836
837         if (NULL == vc_command) {
838                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
839                 return VC_ERROR_INVALID_PARAMETER;
840         }
841
842         if (NULL == appid) {
843                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, appid is NULL");
844                 return VC_ERROR_INVALID_PARAMETER;
845         }
846
847         vc_cmd_s* cmd = NULL;
848         cmd = (vc_cmd_s*)vc_command;
849
850         if (cmd->appid)
851                 free(cmd->appid);
852         cmd->appid = NULL;
853         cmd->appid = strdup(appid);
854
855         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set appid][%p] appid(%s)", vc_command, cmd->appid);
856         return VC_ERROR_NONE;
857 }
858
859 int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid)
860 {
861         if (0 != __vc_cmd_get_feature_enabled()) {
862                 return VC_ERROR_NOT_SUPPORTED;
863         }
864
865         if (NULL == vc_command || NULL == appid) {
866                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
867                 return VC_ERROR_INVALID_PARAMETER;
868         }
869
870         vc_cmd_s* cmd = NULL;
871         cmd = (vc_cmd_s*)vc_command;
872
873         if (cmd->appid)
874                 *appid = strdup(gettext(cmd->appid));
875         else
876                 *appid = NULL;
877
878         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get appid][%p] appid(%s)", vc_command, *appid);
879
880         return VC_ERROR_NONE;
881 }
882
883 int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
884 {
885         if (0 != __vc_cmd_get_feature_enabled()) {
886                 return VC_ERROR_NOT_SUPPORTED;
887         }
888         if (0 != __vc_cmd_check_privilege()) {
889                 return VC_ERROR_PERMISSION_DENIED;
890         }
891
892         if (NULL == vc_command || NULL == command) {
893                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
894                 return VC_ERROR_INVALID_PARAMETER;
895         }
896
897         vc_cmd_s* cmd = NULL;
898         cmd = (vc_cmd_s*)vc_command;
899
900         if (cmd->command)
901                 free(cmd->command);
902         cmd->command = NULL;
903         cmd->command = strdup(command);
904
905         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set command][%p] Command(%s)", vc_command, cmd->command);
906
907         return VC_ERROR_NONE;
908 }
909
910 int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
911 {
912         if (0 != __vc_cmd_get_feature_enabled()) {
913                 return VC_ERROR_NOT_SUPPORTED;
914         }
915         if (0 != __vc_cmd_check_privilege()) {
916                 return VC_ERROR_PERMISSION_DENIED;
917         }
918
919         if (NULL == vc_command || NULL == command) {
920                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
921                 return VC_ERROR_INVALID_PARAMETER;
922         }
923
924         vc_cmd_s* cmd = NULL;
925         cmd = (vc_cmd_s*)vc_command;
926
927         if (cmd->command)
928                 *command = strdup(gettext(cmd->command));
929         else
930                 *command = NULL;
931
932         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get command][%p] Command(%s)", vc_command, *command);
933
934         return VC_ERROR_NONE;
935 }
936
937 int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
938 {
939         if (0 != __vc_cmd_get_feature_enabled()) {
940                 return VC_ERROR_NOT_SUPPORTED;
941         }
942         if (0 != __vc_cmd_check_privilege()) {
943                 return VC_ERROR_PERMISSION_DENIED;
944         }
945
946         if (NULL == vc_command || NULL == command) {
947                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
948                 return VC_ERROR_INVALID_PARAMETER;
949         }
950
951         vc_cmd_s* cmd = NULL;
952         cmd = (vc_cmd_s*)vc_command;
953
954         if (cmd->parameter)
955                 free(cmd->parameter);
956         cmd->parameter = NULL;
957         cmd->parameter = strdup(command);
958         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set unfixed command][%p] unfixed command(%s)", vc_command, cmd->parameter);
959
960         return VC_ERROR_NONE;
961 }
962
963 int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
964 {
965         if (0 != __vc_cmd_get_feature_enabled()) {
966                 return VC_ERROR_NOT_SUPPORTED;
967         }
968
969         if (NULL == vc_command || NULL == command) {
970                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
971                 return VC_ERROR_INVALID_PARAMETER;
972         }
973
974         vc_cmd_s* cmd = NULL;
975         cmd = (vc_cmd_s*)vc_command;
976
977         if (cmd->parameter)
978                 *command = strdup(gettext(cmd->parameter));
979         else
980                 *command = NULL;
981
982         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get unfixed command][%p] unfixed command(%s)", vc_command, *command);
983
984         return VC_ERROR_NONE;
985 }
986
987 int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed)
988 {
989         if (0 != __vc_cmd_get_feature_enabled()) {
990                 return VC_ERROR_NOT_SUPPORTED;
991         }
992
993         if (NULL == vc_command) {
994                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
995                 return VC_ERROR_INVALID_PARAMETER;
996         }
997
998         if (NULL == fixed) {
999                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, fixed is NULL");
1000                 return VC_ERROR_INVALID_PARAMETER;
1001         }
1002
1003         vc_cmd_s* cmd = NULL;
1004         cmd = (vc_cmd_s*)vc_command;
1005
1006         if (cmd->fixed)
1007                 free(cmd->fixed);
1008         cmd->fixed = NULL;
1009         cmd->fixed = strdup(fixed);
1010
1011         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] fixed command(%s)", vc_command, cmd->fixed);
1012         return VC_ERROR_NONE;
1013 }
1014
1015 int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed)
1016 {
1017         if (0 != __vc_cmd_get_feature_enabled()) {
1018                 return VC_ERROR_NOT_SUPPORTED;
1019         }
1020
1021         if (NULL == vc_command || NULL == fixed) {
1022                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1023                 return VC_ERROR_INVALID_PARAMETER;
1024         }
1025
1026         vc_cmd_s* cmd = NULL;
1027         cmd = (vc_cmd_s*)vc_command;
1028
1029         if (cmd->fixed)
1030                 *fixed = strdup(gettext(cmd->fixed));
1031         else
1032                 *fixed = NULL;
1033
1034         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get fixed command][%p] fixed command(%s)", vc_command, *fixed);
1035
1036         return VC_ERROR_NONE;
1037 }
1038
1039 int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation_name)
1040 {
1041         if (0 != __vc_cmd_get_feature_enabled()) {
1042                 return VC_ERROR_NOT_SUPPORTED;
1043         }
1044
1045         if (NULL == vc_command) {
1046                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
1047                 return VC_ERROR_INVALID_PARAMETER;
1048         }
1049
1050         if (NULL == invocation_name) {
1051                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, invocation_name is NULL");
1052                 return VC_ERROR_INVALID_PARAMETER;
1053         }
1054
1055         vc_cmd_s* cmd = NULL;
1056         cmd = (vc_cmd_s*)vc_command;
1057
1058         if (cmd->invocation_name)
1059                 free(cmd->invocation_name);
1060         cmd->invocation_name = NULL;
1061         cmd->invocation_name = strdup(invocation_name);
1062
1063         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set invocation name][%p] invocation_name(%s)", vc_command, cmd->invocation_name);
1064         return VC_ERROR_NONE;
1065 }
1066
1067 int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation_name)
1068 {
1069         if (0 != __vc_cmd_get_feature_enabled()) {
1070                 return VC_ERROR_NOT_SUPPORTED;
1071         }
1072
1073         if (NULL == vc_command || NULL == invocation_name) {
1074                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1075                 return VC_ERROR_INVALID_PARAMETER;
1076         }
1077
1078         vc_cmd_s* cmd = NULL;
1079         cmd = (vc_cmd_s*)vc_command;
1080
1081         if (cmd->invocation_name)
1082                 *invocation_name = strdup(gettext(cmd->invocation_name));
1083         else
1084                 *invocation_name = NULL;
1085
1086         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get invocation name][%p] invocation_name(%s)", vc_command, *invocation_name);
1087         return VC_ERROR_NONE;
1088 }
1089
1090 int vc_cmd_set_type(vc_cmd_h vc_command, int type)
1091 {
1092         if (0 != __vc_cmd_get_feature_enabled()) {
1093                 return VC_ERROR_NOT_SUPPORTED;
1094         }
1095         if (0 != __vc_cmd_check_privilege()) {
1096                 return VC_ERROR_PERMISSION_DENIED;
1097         }
1098
1099         if (NULL == vc_command) {
1100                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1101                 return VC_ERROR_INVALID_PARAMETER;
1102         }
1103
1104         vc_cmd_s* cmd = NULL;
1105         cmd = (vc_cmd_s*)vc_command;
1106
1107         cmd->type = type;
1108
1109         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
1110
1111         return VC_ERROR_NONE;
1112 }
1113
1114 int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
1115 {
1116         if (0 != __vc_cmd_get_feature_enabled()) {
1117                 return VC_ERROR_NOT_SUPPORTED;
1118         }
1119         if (0 != __vc_cmd_check_privilege()) {
1120                 return VC_ERROR_PERMISSION_DENIED;
1121         }
1122
1123         if (NULL == vc_command || NULL == type) {
1124                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1125                 return VC_ERROR_INVALID_PARAMETER;
1126         }
1127
1128         vc_cmd_s* cmd = NULL;
1129         cmd = (vc_cmd_s*)vc_command;
1130
1131         *type = cmd->type;
1132
1133         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get type][%p] type(%d)", vc_command, *type);
1134
1135         return VC_ERROR_NONE;
1136 }
1137
1138 int vc_cmd_set_format(vc_cmd_h vc_command, int format)
1139 {
1140         if (0 != __vc_cmd_get_feature_enabled()) {
1141                 return VC_ERROR_NOT_SUPPORTED;
1142         }
1143
1144         if (NULL == vc_command) {
1145                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1146                 return VC_ERROR_INVALID_PARAMETER;
1147         }
1148
1149         vc_cmd_s* cmd = NULL;
1150         cmd = (vc_cmd_s*)vc_command;
1151
1152         cmd->format = format;
1153
1154         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set format][%p] format(%d)", vc_command, format);
1155
1156         return VC_ERROR_NONE;
1157 }
1158
1159 int vc_cmd_get_format(vc_cmd_h vc_command, int* format)
1160 {
1161         if (0 != __vc_cmd_get_feature_enabled()) {
1162                 return VC_ERROR_NOT_SUPPORTED;
1163         }
1164
1165         if (NULL == vc_command || NULL == format) {
1166                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1167                 return VC_ERROR_INVALID_PARAMETER;
1168         }
1169
1170         vc_cmd_s* cmd = NULL;
1171         cmd = (vc_cmd_s*)vc_command;
1172
1173         *format = cmd->format;
1174
1175         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get format][%p] format(%d)", vc_command, *format);
1176
1177         return VC_ERROR_NONE;
1178 }
1179
1180 int vc_cmd_set_pid(vc_cmd_h vc_command, int pid)
1181 {
1182         if (0 != __vc_cmd_get_feature_enabled()) {
1183                 return VC_ERROR_NOT_SUPPORTED;
1184         }
1185         if (0 != __vc_cmd_check_privilege()) {
1186                 return VC_ERROR_PERMISSION_DENIED;
1187         }
1188
1189         if (NULL == vc_command) {
1190                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1191                 return VC_ERROR_INVALID_PARAMETER;
1192         }
1193
1194         vc_cmd_s* cmd = NULL;
1195         cmd = (vc_cmd_s*)vc_command;
1196
1197         cmd->pid = pid;
1198
1199         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set pid][%p] pid(%d)", vc_command, cmd->pid);
1200
1201         return VC_ERROR_NONE;
1202 }
1203
1204 int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
1205 {
1206         if (0 != __vc_cmd_get_feature_enabled()) {
1207                 return VC_ERROR_NOT_SUPPORTED;
1208         }
1209         if (0 != __vc_cmd_check_privilege()) {
1210                 return VC_ERROR_PERMISSION_DENIED;
1211         }
1212
1213         if (NULL == vc_command || NULL == pid) {
1214                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1215                 return VC_ERROR_INVALID_PARAMETER;
1216         }
1217
1218         vc_cmd_s* cmd = NULL;
1219         cmd = (vc_cmd_s*)vc_command;
1220
1221         *pid = cmd->pid;
1222
1223         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get pid][%p] pid(%d)", vc_command, *pid);
1224
1225         return VC_ERROR_NONE;
1226 }
1227
1228 int vc_cmd_set_domain(vc_cmd_h vc_command, int domain)
1229 {
1230         if (0 != __vc_cmd_get_feature_enabled()) {
1231                 return VC_ERROR_NOT_SUPPORTED;
1232         }
1233         if (0 != __vc_cmd_check_privilege()) {
1234                 return VC_ERROR_PERMISSION_DENIED;
1235         }
1236
1237         if (NULL == vc_command) {
1238                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1239                 return VC_ERROR_INVALID_PARAMETER;
1240         }
1241
1242         vc_cmd_s* cmd = NULL;
1243         cmd = (vc_cmd_s*)vc_command;
1244
1245         cmd->domain = domain;
1246
1247         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set domain] domain : %d", domain);
1248
1249         return VC_ERROR_NONE;
1250 }
1251
1252 int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
1253 {
1254         if (0 != __vc_cmd_get_feature_enabled()) {
1255                 return VC_ERROR_NOT_SUPPORTED;
1256         }
1257         if (0 != __vc_cmd_check_privilege()) {
1258                 return VC_ERROR_PERMISSION_DENIED;
1259         }
1260
1261         if (NULL == vc_command || NULL == domain) {
1262                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1263                 return VC_ERROR_INVALID_PARAMETER;
1264         }
1265
1266         vc_cmd_s* cmd = NULL;
1267         cmd = (vc_cmd_s*)vc_command;
1268
1269         *domain = cmd->domain;
1270
1271         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get domain] domain : %d", *domain);
1272
1273         return VC_ERROR_NONE;
1274 }
1275
1276 /**
1277 * @brief Sets key value of command.
1278 *
1279 * @param[in] vc_command Command handle
1280 * @param[in] key key value
1281 * @param[in] modifier modifier value
1282 *
1283 * @return 0 on success, otherwise a negative error value
1284 * @retval #VC_ERROR_NONE Successful
1285 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1286 *
1287 * @see vc_cmd_get_result_key()
1288 */
1289 int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
1290 {
1291         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Set result key");
1292
1293         if (NULL == vc_command) {
1294                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1295                 return VC_ERROR_INVALID_PARAMETER;
1296         }
1297
1298         vc_cmd_s* cmd = NULL;
1299         cmd = (vc_cmd_s*)vc_command;
1300
1301         SLOG(LOG_DEBUG, TAG_VCCMD, "key : %d, modifier : %d", key, modifier);
1302
1303         cmd->key = key;
1304         cmd->modifier = modifier;
1305
1306         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
1307
1308         return VC_ERROR_NONE;
1309 }
1310
1311 /**
1312 * @brief Gets key value of command.
1313 *
1314 * @param[in] vc_command Command handle
1315 * @param[out] key key value
1316 * @param[out] modifier modifier value
1317 *
1318 * @return 0 on success, otherwise a negative error value
1319 * @retval #VC_ERROR_NONE Successful
1320 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1321 *
1322 * @see vc_cmd_add_result_key()
1323 */
1324 int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
1325 {
1326         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Get result key");
1327
1328         if (NULL == vc_command || NULL == key || NULL == modifier) {
1329                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1330                 return VC_ERROR_INVALID_PARAMETER;
1331         }
1332
1333         vc_cmd_s* cmd = NULL;
1334         cmd = (vc_cmd_s*)vc_command;
1335
1336         *key = cmd->key;
1337         *modifier = cmd->modifier;
1338
1339         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
1340
1341         return VC_ERROR_NONE;
1342 }
1343
1344 int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
1345 {
1346         if (NULL == vc_cmd_list) {
1347                 return -1;
1348         }
1349
1350         vc_cmd_list_s* list = NULL;
1351         list = (vc_cmd_list_s*)vc_cmd_list;
1352
1353         SLOG(LOG_DEBUG, TAG_VCCMD, "@ Command List @");
1354         SLOG(LOG_DEBUG, TAG_VCCMD, "[List][%p]", list);
1355
1356         int i = 0;
1357         GSList *iter = NULL;
1358         iter = g_slist_nth(list->list, 0);
1359         while (NULL != iter) {
1360                 vc_cmd_s *cmd = NULL;
1361                 cmd = iter->data;
1362                 if (NULL == cmd) {
1363                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
1364                         return VC_ERROR_OPERATION_FAILED;
1365                 }
1366                 SLOG(LOG_DEBUG, TAG_VCCMD, "  [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Command(%s) Param(%s) Appid(%s) Invocation(%s) Fixed(%s)",
1367                          i++, cmd, cmd->pid, cmd->index, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
1368
1369                 iter = g_slist_next(iter);
1370         }
1371
1372         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
1373
1374         return VC_ERROR_NONE;
1375 }
1376
1377 int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json)
1378 {
1379         if (0 != __vc_cmd_get_feature_enabled()) {
1380                 return VC_ERROR_NOT_SUPPORTED;
1381         }
1382
1383         if (NULL == vc_cmd || NULL == json) {
1384                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] NULL parameter");
1385                 return VC_ERROR_INVALID_PARAMETER;
1386         }
1387
1388         vc_cmd_s* cmd = NULL;
1389         cmd = (vc_cmd_s*)vc_cmd;
1390
1391         if (VC_CMD_FORMAT_ACTION != cmd->format) {
1392                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not Action format");
1393                 return VC_ERROR_INVALID_PARAMETER;
1394         }
1395
1396         if (0 != vc_info_parser_get_nlu_result(json)) {
1397                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get nlu result");
1398                 return VC_ERROR_OPERATION_FAILED;
1399         }
1400
1401         return VC_ERROR_NONE;
1402 }
1403
1404 static void __vc_cmd_regex_deinit(int num_regex)
1405 {
1406         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Start Deinitialize regex @@@");
1407         int i;
1408
1409         for (i = 0; num_regex > i; i++) {
1410                 regfree(&reg[i]);
1411         }
1412
1413         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
1414 }
1415
1416 static int __vc_cmd_regex_init()
1417 {
1418         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Initialize regular expression @@@");
1419
1420         int cflags = REG_EXTENDED | REG_ICASE;
1421         int ret;
1422         char errStr[128];
1423         char *lang = NULL;
1424         int lang_type = 1;
1425
1426         vc_config_mgr_get_default_language(&lang);
1427         if (NULL == lang) {
1428                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1429                 return VC_ERROR_OPERATION_FAILED;
1430         }
1431
1432         if (!strcmp("en_US", lang)) {
1433                 lang_type = 1;
1434         } else if (!strcmp("ko_KR", lang)) {
1435                 lang_type = 0;
1436         } else {
1437                 free(lang);
1438                 lang = NULL;
1439
1440                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not supported language type");
1441                 return VC_ERROR_INVALID_LANGUAGE;
1442         }
1443
1444         free(lang);
1445         lang = NULL;
1446
1447         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ lang type > %d @@@", lang_type);
1448
1449         re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
1450
1451         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s" , TIME_ABS1_REGEX[lang_type]);
1452         ret = regcomp(&reg[0], TIME_ABS1_REGEX[lang_type], cflags);
1453         if (0 != ret) {
1454                 regerror(ret, &reg[0], errStr, sizeof(errStr));
1455
1456                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1457                 return VC_ERROR_OPERATION_FAILED;
1458         }
1459
1460         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS2_REGEX[lang_type]);
1461         ret = regcomp(&reg[1], TIME_ABS2_REGEX[lang_type], cflags);
1462         if (0 != ret) {
1463                 regerror(ret, &reg[1], errStr, sizeof(errStr));
1464                 __vc_cmd_regex_deinit(1);
1465
1466                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1467                 return VC_ERROR_OPERATION_FAILED;
1468         }
1469
1470         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS3_REGEX[lang_type]);
1471         ret = regcomp(&reg[2], TIME_ABS3_REGEX[lang_type], cflags);
1472         if (0 != ret) {
1473                 regerror(ret, &reg[2], errStr, sizeof(errStr));
1474                 __vc_cmd_regex_deinit(2);
1475
1476                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1477                 return VC_ERROR_OPERATION_FAILED;
1478         }
1479
1480         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL1_REGEX[lang_type]);
1481         ret = regcomp(&reg[3], TIME_REL1_REGEX[lang_type], cflags);
1482         if (0 != ret) {
1483                 regerror(ret, &reg[3], errStr, sizeof(errStr));
1484                 __vc_cmd_regex_deinit(3);
1485
1486                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1487                 return VC_ERROR_OPERATION_FAILED;
1488         }
1489
1490         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL2_REGEX[lang_type]);
1491         ret = regcomp(&reg[4], TIME_REL2_REGEX[lang_type], cflags);
1492         if (0 != ret) {
1493                 regerror(ret, &reg[4], errStr, sizeof(errStr));
1494                 __vc_cmd_regex_deinit(4);
1495
1496                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1497                 return VC_ERROR_OPERATION_FAILED;
1498         }
1499
1500         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL3_REGEX[lang_type]);
1501         ret = regcomp(&reg[5], TIME_REL3_REGEX[lang_type], cflags);
1502         if (0 != ret) {
1503                 regerror(ret, &reg[5], errStr, sizeof(errStr));
1504                 __vc_cmd_regex_deinit(5);
1505
1506                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1507                 return VC_ERROR_OPERATION_FAILED;
1508         }
1509
1510         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_PHR_REGEX[lang_type]);
1511         ret = regcomp(&reg[6], TIME_PHR_REGEX[lang_type], cflags);
1512         if (0 != ret) {
1513                 regerror(ret, &reg[6], errStr, sizeof(errStr));
1514                 __vc_cmd_regex_deinit(6);
1515
1516                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1517                 return VC_ERROR_OPERATION_FAILED;
1518         }
1519
1520         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS1_REGEX[lang_type]);
1521         ret = regcomp(&reg[7], DATE_ABS1_REGEX[lang_type], cflags);
1522         if (0 != ret) {
1523                 regerror(ret, &reg[7], errStr, sizeof(errStr));
1524                 __vc_cmd_regex_deinit(7);
1525
1526                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1527                 return VC_ERROR_OPERATION_FAILED;
1528         }
1529
1530         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS2_REGEX[lang_type]);
1531         ret = regcomp(&reg[8], DATE_ABS2_REGEX[lang_type], cflags);
1532         if (0 != ret) {
1533                 regerror(ret, &reg[8], errStr, sizeof(errStr));
1534                 __vc_cmd_regex_deinit(8);
1535
1536                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1537                 return VC_ERROR_OPERATION_FAILED;
1538         }
1539
1540         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS3_REGEX[lang_type]);
1541         ret = regcomp(&reg[9], DATE_ABS3_REGEX[lang_type], cflags);
1542         if (0 != ret) {
1543                 regerror(ret, &reg[9], errStr, sizeof(errStr));
1544                 __vc_cmd_regex_deinit(9);
1545
1546                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1547                 return VC_ERROR_OPERATION_FAILED;
1548         }
1549
1550         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR1_REGEX[lang_type]);
1551         ret = regcomp(&reg[10], DATE_PHR1_REGEX[lang_type], cflags);
1552         if (0 != ret) {
1553                 regerror(ret, &reg[10], errStr, sizeof(errStr));
1554                 __vc_cmd_regex_deinit(10);
1555
1556                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1557                 return VC_ERROR_OPERATION_FAILED;
1558         }
1559
1560         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR2_REGEX[lang_type]);
1561         ret = regcomp(&reg[11], DATE_PHR2_REGEX[lang_type], cflags);
1562         if (0 != ret) {
1563                 regerror(ret, &reg[11], errStr, sizeof(errStr));
1564                 __vc_cmd_regex_deinit(11);
1565
1566                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1567                 return VC_ERROR_OPERATION_FAILED;
1568         }
1569
1570         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
1571
1572         return VC_ERROR_NONE;
1573 }
1574
1575 static void __vc_cmd_add_year(struct tm *td, int year)
1576 {
1577         td->tm_year += year;
1578 }
1579
1580 static void __vc_cmd_add_mon(struct tm *td, int mon)
1581 {
1582         int year = 0;
1583
1584         mon = td->tm_mon + mon;
1585         year = mon / 12;
1586
1587         if (0 < year) {
1588                 __vc_cmd_add_year(td, year);
1589         }
1590
1591         td->tm_mon = mon % 12;
1592 }
1593
1594 static void __vc_cmd_add_mday(struct tm *td, int mday)
1595 {
1596         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
1597         int year = td->tm_year + 1900;
1598
1599         int mon = 0;
1600
1601         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) max_day[1] = 29;
1602
1603         mday = td->tm_mday + mday;
1604
1605         for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) {
1606                 mday -= max_day[mon % 12];
1607
1608                 if (11 == mon % 12) {
1609                         year++;
1610
1611                         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) {
1612                                 max_day[1] = 29;
1613                         } else {
1614                                 max_day[1] = 28;
1615                         }
1616                 }
1617         }
1618
1619         mon = mon - td->tm_mon;
1620
1621         if (0 < mon) {
1622                 __vc_cmd_add_mon(td, mon);
1623         }
1624
1625         td->tm_mday = mday;
1626 }
1627
1628 static void __vc_cmd_add_hour(struct tm *td, int hour)
1629 {
1630         int day = 0;
1631
1632         hour = td->tm_hour + hour;
1633         day = hour / 24;
1634
1635         if (0 < day) {
1636                 __vc_cmd_add_mday(td, day);
1637         }
1638
1639         td->tm_hour = hour % 24;
1640 }
1641
1642 static void __vc_cmd_add_min(struct tm *td, int min)
1643 {
1644         int hour = 0;
1645
1646         min = td->tm_min + min;
1647         hour = min / 60;
1648
1649         if (0 < hour) {
1650                 __vc_cmd_add_hour(td, hour);
1651         }
1652
1653         td->tm_min = min % 60;
1654 }
1655
1656 static void __copy_struct_tm(struct tm *des, struct tm *src)
1657 {
1658         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Start to copy struct tm @@@");
1659
1660         des->tm_sec     = src->tm_sec;
1661         des->tm_min     = src->tm_min;
1662         des->tm_hour    = src->tm_hour;
1663         des->tm_mday    = src->tm_mday;
1664         des->tm_mon     = src->tm_mon;
1665         des->tm_year    = src->tm_year;
1666         des->tm_wday    = src->tm_wday;
1667         des->tm_yday    = src->tm_yday;
1668         des->tm_isdst   = src->tm_isdst;
1669
1670         des->tm_gmtoff  = src->tm_gmtoff;
1671         des->tm_zone    = src->tm_zone;
1672 }
1673
1674 static void __update_data_sidx(int idx)
1675 {
1676         if (0 > g_data_sidx || idx < g_data_sidx) g_data_sidx = idx;
1677 }
1678
1679 static void __update_data_eidx(int idx)
1680 {
1681         if (0 > g_data_eidx || idx > g_data_eidx) g_data_eidx = idx;
1682 }
1683
1684 static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist)
1685 {
1686         regmatch_t pmatch[3];
1687         int ret;
1688         int len;
1689         int idx;
1690
1691         *exist = 0;
1692         ret = regexec(&reg[6], str, 3, pmatch, 0);
1693         if (0 == ret) {
1694                 idx = 1;
1695                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1696                 if (0 < len) {
1697                         if (12 < td->tm_hour) {
1698                                 __vc_cmd_add_mday(td, 1);
1699                         }
1700
1701                         td->tm_hour = 12;
1702                 } else {
1703                         idx = 2;
1704                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1705
1706                         __vc_cmd_add_mday(td, 1);
1707                 }
1708
1709                 td->tm_min = 0;
1710                 td->tm_sec = 0;
1711                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1712
1713                 __update_data_sidx(pmatch[0].rm_so);
1714                 __update_data_eidx(pmatch[0].rm_eo);
1715
1716                 *exist = 1;
1717                 return VC_ERROR_NONE;
1718         }
1719
1720         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1721         return VC_ERROR_NONE;
1722 }
1723
1724 static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist)
1725 {
1726         regmatch_t pmatch[2];
1727         int ret;
1728         int len;
1729         int sidx = -1;
1730         int eidx = -1;
1731         int hour = -1;
1732         int min = -1;
1733
1734         char *tempstr = NULL;
1735
1736         *exist = 0;
1737         ret = regexec(&reg[3], str, 1, pmatch, 0);
1738         if (0 == ret) {
1739                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so);
1740                 hour = min = -1;
1741
1742                 sidx = pmatch[0].rm_so;
1743                 eidx = pmatch[0].rm_eo;
1744
1745                 ret = regexec(&reg[4], str, 2, pmatch, 0);
1746                 if (0 == ret) {
1747                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1748
1749                         if (0 > len) {
1750                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1751                                 return VC_ERROR_OPERATION_FAILED;
1752                         }
1753                         tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1754
1755                         if (NULL == tempstr) {
1756                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1757                                 return VC_ERROR_OUT_OF_MEMORY;
1758                         }
1759
1760                         hour = atoi(tempstr);
1761
1762                         free(tempstr);
1763                         tempstr = NULL;
1764
1765                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1766
1767                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1768                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1769                 }
1770
1771                 ret = regexec(&reg[5], str, 2, pmatch, 0);
1772                 if (0 == ret) {
1773                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1774
1775                         if (0 > len) {
1776                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1777                                 return VC_ERROR_OPERATION_FAILED;
1778                         }
1779                         tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1780
1781                         if (NULL == tempstr) {
1782                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1783                                 return VC_ERROR_OUT_OF_MEMORY;
1784                         }
1785
1786                         min = atoi(tempstr);
1787
1788                         free(tempstr);
1789                         tempstr = NULL;
1790
1791                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1792
1793                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1794                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1795                 }
1796
1797                 if (hour < 0 && min < 0) {
1798                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1799                         return VC_ERROR_NONE;
1800                 }
1801
1802                 hour = 0 > hour ? 0 : hour;
1803                 min = 0 > min ? 0 : min;
1804
1805                 min = min + (hour * 60);
1806
1807                 __vc_cmd_add_min(td, min);
1808                 td->tm_sec = 0;
1809
1810                 __update_data_sidx(sidx);
1811                 __update_data_eidx(eidx);
1812
1813                 *exist = 1;
1814                 return VC_ERROR_NONE;
1815         }
1816
1817         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1818         return VC_ERROR_NONE;
1819 }
1820
1821 static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist)
1822 {
1823         regmatch_t pmatch[5];
1824         int ret;
1825         int len;
1826         int idx;
1827         int flag = -1;
1828         int hour = -1;
1829         int min = -1;
1830         int sidx = -1;
1831         int eidx = -1;
1832         char *tempstr = NULL;
1833
1834         *exist = 0;
1835         ret = regexec(&reg[0], str, 5, pmatch, 0);
1836         if (0 == ret) {
1837                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1838
1839                 flag = idx & 1;
1840
1841                 sidx = pmatch[0].rm_so;
1842                 eidx = pmatch[0].rm_eo;
1843         }
1844
1845         ret = regexec(&reg[1], str, 2, pmatch, 0);
1846         if (0 == ret) {
1847                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
1848
1849                 if (0 > len) {
1850                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1851                         return VC_ERROR_OPERATION_FAILED;
1852                 }
1853                 tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1854
1855                 if (NULL == tempstr) {
1856                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1857                         return VC_ERROR_OUT_OF_MEMORY;
1858                 }
1859
1860                 hour = atoi(tempstr);
1861
1862                 if (0 <= flag) {
1863                         hour = hour + 12 * flag;
1864
1865                         if (12 == hour) hour = 0;
1866                         else if (24 == hour) hour = 12;
1867                 }
1868
1869                 if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) {
1870                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1871                         free(tempstr);
1872                         tempstr = NULL;
1873                         return VC_ERROR_NONE;
1874                 }
1875
1876                 free(tempstr);
1877                 tempstr = NULL;
1878
1879                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1880
1881                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1882                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1883         } else if (0 < flag) {
1884                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1885                 return VC_ERROR_NONE;
1886         }
1887
1888         ret = regexec(&reg[2], str, 2, pmatch, 0);
1889         if (0 == ret) {
1890                 idx = 1;
1891                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1892                 if (0 < len) {
1893                         tempstr = strndup(str + pmatch[idx].rm_so, (size_t)len);
1894
1895                         if (NULL == tempstr) {
1896                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1897                                 return VC_ERROR_OUT_OF_MEMORY;
1898                         }
1899
1900                         min = atoi(tempstr);
1901
1902                         if (0 > min || 60 <= min) {
1903                                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1904                                 free(tempstr);
1905                                 tempstr = NULL;
1906                                 return VC_ERROR_NONE;
1907                         }
1908
1909                         td->tm_sec = 0;
1910
1911                         free(tempstr);
1912                         tempstr = NULL;
1913                 } else {
1914                         idx = 0;
1915                         min = 30;
1916                 }
1917
1918                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so);
1919                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1920                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1921         }
1922
1923         if (0 > hour && 0 > min) {
1924                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1925                 return VC_ERROR_NONE;
1926         }
1927
1928         if (0 <= min && 0 <= hour) {
1929                 if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1);
1930
1931                 td->tm_hour = hour;
1932                 td->tm_min = min;
1933         } else if (0 <= min) {
1934                 char *lang = NULL;
1935                 vc_config_mgr_get_default_language(&lang);
1936                 if (NULL == lang) {
1937                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1938                         return VC_ERROR_OPERATION_FAILED;
1939                 }
1940
1941                 if (!strcmp("en_US", lang)) {
1942                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1943                         free(lang);
1944                         lang = NULL;
1945                         return VC_ERROR_NONE;
1946                 }
1947                 if (min <= td->tm_min) __vc_cmd_add_hour(td, 1);
1948
1949                 td->tm_min = min;
1950
1951                 free(lang);
1952                 lang = NULL;
1953         } else {
1954                 if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1);
1955
1956                 td->tm_hour = hour;
1957                 td->tm_min = 0;
1958         }
1959
1960         td->tm_sec = 0;
1961
1962         __update_data_sidx(sidx);
1963         __update_data_eidx(eidx);
1964
1965         *exist = 1;
1966         return VC_ERROR_NONE;
1967 }
1968
1969 static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist)
1970 {
1971         regmatch_t pmatch[10];
1972         int ret;
1973         int len;
1974         int idx;
1975
1976         *exist = 0;
1977         ret = regexec(&reg[10], str, 5, pmatch, 0);
1978         if (0 == ret) {
1979                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1980
1981                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1982
1983                 td->tm_year = td_now.tm_year;
1984                 td->tm_mon = td_now.tm_mon;
1985                 td->tm_mday = td_now.tm_mday;
1986
1987                 __vc_cmd_add_mday(td, idx - 1);
1988
1989                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1990
1991                 __update_data_sidx(pmatch[0].rm_so);
1992                 __update_data_eidx(pmatch[0].rm_eo);
1993
1994                 *exist = 1;
1995                 return VC_ERROR_NONE;
1996         }
1997
1998         ret = regexec(&reg[11], str, 10, pmatch, 0);
1999         if (0 == ret) {
2000                 for (idx = 1; 10 > idx; idx++) {
2001                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2002
2003                         if (0 < len) break;
2004                 }
2005
2006                 td->tm_year = td_now.tm_year;
2007                 td->tm_mon = td_now.tm_mon;
2008                 td->tm_mday = td_now.tm_mday;
2009
2010                 __vc_cmd_add_mday(td, idx + 1);
2011
2012                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2013
2014                 __update_data_sidx(pmatch[0].rm_so);
2015                 __update_data_eidx(pmatch[0].rm_eo);
2016
2017                 *exist = 1;
2018                 return VC_ERROR_NONE;
2019         }
2020
2021         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
2022         return VC_ERROR_NONE;
2023 }
2024
2025 static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist)
2026 {
2027         regmatch_t pmatch[13];
2028         int ret;
2029         int len;
2030         int idx;
2031         int sidx = -1;
2032         int eidx = -1;
2033         int y_flag = 0;
2034         int m_flag = 0;
2035         int year = 0;
2036         int mon = 0;
2037         int day = 0;
2038         char *tempstr = NULL;
2039
2040         *exist = 0;
2041         ret = regexec(&reg[9], str, 2, pmatch, 0);
2042         if (0 == ret) {
2043                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
2044
2045                 if (0 > len) {
2046                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2047                         return VC_ERROR_OPERATION_FAILED;
2048                 }
2049                 tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
2050
2051                 if (NULL == tempstr) {
2052                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2053                         return VC_ERROR_OUT_OF_MEMORY;
2054                 }
2055
2056                 day = atoi(tempstr);
2057
2058                 free(tempstr);
2059                 tempstr = NULL;
2060
2061                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2062
2063                 sidx = pmatch[0].rm_so;
2064                 eidx = pmatch[0].rm_eo;
2065         } else {
2066                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2067                 return VC_ERROR_NONE;
2068         }
2069
2070         ret = regexec(&reg[8], str, 13, pmatch, 0);
2071         if (0 == ret) {
2072                 for (idx = 1; 13 > idx; idx++) {
2073                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2074
2075                         if (0 < len) {
2076                                 mon = idx - 1;
2077                                 break;
2078                         }
2079                 }
2080
2081                 m_flag = 1;
2082
2083                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2084
2085                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2086                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2087         } else {
2088                 char *lang = NULL;
2089                 vc_config_mgr_get_default_language(&lang);
2090                 if (NULL == lang) {
2091                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
2092                         return VC_ERROR_OPERATION_FAILED;
2093                 }
2094
2095                 if (!strcmp("en_US", lang)) {
2096                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2097                         free(lang);
2098                         lang = NULL;
2099                         return VC_ERROR_NONE;
2100                 }
2101
2102                 free(lang);
2103                 lang = NULL;
2104
2105                 mon = td->tm_mon;
2106         }
2107
2108         ret = regexec(&reg[7], str, 3, pmatch, 0);
2109         if (0 == ret) {
2110                 if (!m_flag) return -1;
2111
2112                 len = pmatch[2].rm_eo - pmatch[2].rm_so;
2113
2114                 if (0 > len) {
2115                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2116                         return VC_ERROR_OPERATION_FAILED;
2117                 }
2118                 tempstr = strndup(str + pmatch[2].rm_so, (size_t)len);
2119
2120                 if (NULL == tempstr) {
2121                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2122                         return VC_ERROR_OUT_OF_MEMORY;
2123                 }
2124
2125                 year = atoi(tempstr);
2126                 year = 1900 < year ? year - 1900 : year + 100;
2127
2128                 free(tempstr);
2129                 tempstr = NULL;
2130
2131                 y_flag = 1;
2132                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2133
2134                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2135                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2136         } else {
2137                 year = td->tm_year;
2138         }
2139
2140         if (0 > g_time_flag) {
2141                 td->tm_hour = 0;
2142                 td->tm_min = 0;
2143                 td->tm_sec = 0;
2144         } else if (2 == g_time_flag) {
2145                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2146                 return VC_ERROR_NONE;
2147         }
2148
2149         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
2150         if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29;
2151
2152         if (max_day[mon] < day || 1 > day) {
2153                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2154                 return VC_ERROR_NONE;
2155         }
2156
2157         td->tm_year = year;
2158         td->tm_mon = mon;
2159         td->tm_mday = day;
2160
2161         if (!y_flag) {
2162                 if (!m_flag) {
2163                         if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1);
2164                 } else {
2165                         if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1);
2166                         else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1);
2167                 }
2168         }
2169
2170         __update_data_sidx(sidx);
2171         __update_data_eidx(eidx);
2172
2173         *exist = 1;
2174         return VC_ERROR_NONE;
2175 }
2176
2177 static int __vc_cmd_time_check(const char *str, struct tm *td)
2178 {
2179         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check time value in string \"%s\"", str);
2180
2181         vc_error_e ret;
2182         int exist = 0;
2183
2184         ret = __vc_cmd_tphrase_check(str, td, &exist);
2185         if (1 == exist) {
2186                 g_time_flag = 1;
2187
2188                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
2189                 return ret;
2190         } else if (VC_ERROR_NONE != ret) {
2191                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2192                 return ret;
2193         }
2194
2195         ret = __vc_cmd_trelative_check(str, td, &exist);
2196         if (1 == exist) {
2197                 g_time_flag = 2;
2198
2199                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
2200                 return ret;
2201         } else if (VC_ERROR_NONE != ret) {
2202                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2203                 return ret;
2204         }
2205
2206         ret = __vc_cmd_tabsolute_check(str, td, &exist);
2207         if (1 == exist) {
2208                 g_time_flag = 3;
2209
2210                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
2211                 return ret;
2212         } else if (VC_ERROR_NONE != ret) {
2213                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2214                 return ret;
2215         }
2216
2217         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no time value");
2218         return VC_ERROR_NONE;
2219 }
2220
2221 static int __vc_cmd_date_check(const char *str, struct tm *td)
2222 {
2223         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check date value in string \"%s\"", str);
2224
2225         vc_error_e ret;
2226         int exist = 0;
2227
2228         ret = __vc_cmd_dphrase_check(str, td, &exist);
2229         if (1 == exist) {
2230                 g_date_flag = 1;
2231
2232                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
2233                 return ret;
2234         } else if (VC_ERROR_NONE != ret) {
2235                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2236                 return ret;
2237         }
2238
2239         ret = __vc_cmd_dabsolute_check(str, td, &exist);
2240         if (1 == exist) {
2241                 g_date_flag = 1;
2242
2243                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
2244                 return ret;
2245         } else if (VC_ERROR_NONE != ret) {
2246                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2247                 return ret;
2248         }
2249
2250         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no date value");
2251         return VC_ERROR_NONE;
2252 }
2253
2254 int vc_cmd_get_datetime(const char *text, time_t *result, char **remain)
2255 {
2256         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Get timestamp data");
2257
2258         struct tm td;
2259         const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
2260         vc_error_e ret;
2261
2262         if (NULL == text || NULL == result || NULL == remain) {
2263                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter");
2264                 return VC_ERROR_INVALID_PARAMETER;
2265         }
2266
2267         *result = -1;
2268         ret = __vc_cmd_regex_init();
2269         if (VC_ERROR_NONE != ret) {
2270                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed");
2271                 return ret;
2272         }
2273
2274         g_data_sidx = g_data_eidx = -1;
2275
2276         t_now = time(NULL);
2277         localtime_r(&t_now, &td_now);
2278         SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now);
2279
2280         __copy_struct_tm(&td, &td_now);
2281         SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2282                 td.tm_year + 1900, td.tm_mon + 1, td.tm_mday, day_name[td.tm_wday], td.tm_hour, td.tm_min, td.tm_sec);
2283
2284         g_time_flag = g_date_flag = -1;
2285
2286         ret = __vc_cmd_time_check(text, &td);
2287         if (VC_ERROR_NONE != ret) {
2288                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
2289                 return ret;
2290         }
2291
2292         ret = __vc_cmd_date_check(text, &td);
2293         if (VC_ERROR_NONE != ret) {
2294                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
2295                 return ret;
2296         }
2297
2298         __vc_cmd_regex_deinit(12);
2299
2300         if (g_time_flag > 0 || g_date_flag > 0) {
2301                 *result = mktime(&td);
2302
2303                 SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %ld", *result);
2304                 SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2305                         td.tm_year + 1900, td.tm_mon + 1, td.tm_mday, day_name[td.tm_wday], td.tm_hour, td.tm_min, td.tm_sec);
2306
2307                 *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx));
2308
2309                 if (NULL == *remain) {
2310                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error");
2311                         return VC_ERROR_OUT_OF_MEMORY;
2312                 }
2313
2314                 strncpy(*remain, text, g_data_sidx);
2315                 strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx);
2316         } else {
2317                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text");
2318         }
2319
2320         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
2321
2322         return VC_ERROR_NONE;
2323 }