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