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