Add command list handle check logic
[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         list->list = NULL;
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) {
730                         free(command->command);
731                         command->command = NULL;
732                 }
733                 if (NULL != command->parameter) {
734                         free(command->parameter);
735                         command->parameter = NULL;
736                 }
737                 if (NULL != command->invocation_name) {
738                         free(command->invocation_name);
739                         command->invocation_name = NULL;
740                 }
741                 if (NULL != command->appid) {
742                         free(command->appid);
743                         command->appid = NULL;
744                 }
745                 if (NULL != command->fixed) {
746                         free(command->fixed);
747                         command->fixed = NULL;
748                 }
749                 free(command);
750                 command = NULL;
751         }
752
753         return VC_ERROR_NONE;
754 }
755
756 int vc_cmd_set_id(vc_cmd_h vc_command, int id)
757 {
758         if (0 != __vc_cmd_get_feature_enabled()) {
759                 return VC_ERROR_NOT_SUPPORTED;
760         }
761         if (0 != __vc_cmd_check_privilege()) {
762                 return VC_ERROR_PERMISSION_DENIED;
763         }
764
765         if (NULL == vc_command) {
766                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
767                 return VC_ERROR_INVALID_PARAMETER;
768         }
769
770         vc_cmd_s* cmd = NULL;
771         cmd = (vc_cmd_s*)vc_command;
772
773         if (NULL != cmd) {
774                 cmd->id = id;
775                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
776         }
777
778         return 0;
779 }
780
781 int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
782 {
783         if (0 != __vc_cmd_get_feature_enabled()) {
784                 return VC_ERROR_NOT_SUPPORTED;
785         }
786         if (0 != __vc_cmd_check_privilege()) {
787                 return VC_ERROR_PERMISSION_DENIED;
788         }
789
790         if (NULL == vc_command || NULL == id) {
791                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
792                 return VC_ERROR_INVALID_PARAMETER;
793         }
794
795         vc_cmd_s* cmd = NULL;
796         cmd = (vc_cmd_s*)vc_command;
797
798         if (NULL != cmd) {
799                 *id = cmd->id;
800                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
801         }
802
803         return 0;
804 }
805
806 int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid)
807 {
808         if (0 != __vc_cmd_get_feature_enabled()) {
809                 return VC_ERROR_NOT_SUPPORTED;
810         }
811
812         if (NULL == vc_command) {
813                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
814                 return VC_ERROR_INVALID_PARAMETER;
815         }
816
817         if (NULL == appid) {
818                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, appid is NULL");
819                 return VC_ERROR_INVALID_PARAMETER;
820         }
821
822         vc_cmd_s* cmd = NULL;
823         cmd = (vc_cmd_s*)vc_command;
824
825         if (NULL != cmd->appid) {
826                 free(cmd->appid);
827                 cmd->appid = NULL;
828         }
829
830         cmd->appid = strdup(appid);
831
832         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set appid][%p] appid(%s)", vc_command, cmd->appid);
833         return 0;
834 }
835
836 int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid)
837 {
838         if (0 != __vc_cmd_get_feature_enabled()) {
839                 return VC_ERROR_NOT_SUPPORTED;
840         }
841
842         if (NULL == vc_command || NULL == appid) {
843                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
844                 return VC_ERROR_INVALID_PARAMETER;
845         }
846
847         vc_cmd_s* cmd = NULL;
848         cmd = (vc_cmd_s*)vc_command;
849
850         if (NULL != cmd->appid) {
851                 *appid = strdup(gettext(cmd->appid));
852         }
853
854         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get appid][%p] appid(%s)", vc_command, *appid);
855         return 0;
856 }
857
858 int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
859 {
860         if (0 != __vc_cmd_get_feature_enabled()) {
861                 return VC_ERROR_NOT_SUPPORTED;
862         }
863         if (0 != __vc_cmd_check_privilege()) {
864                 return VC_ERROR_PERMISSION_DENIED;
865         }
866
867         if (NULL == vc_command) {
868                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
869                 return VC_ERROR_INVALID_PARAMETER;
870         }
871
872         vc_cmd_s* cmd = NULL;
873         cmd = (vc_cmd_s*)vc_command;
874
875         if (NULL != cmd->command) {
876                 free(cmd->command);
877         }
878
879         cmd->command = NULL;
880
881         if (NULL != command) {
882                 cmd->command = strdup(command);
883         }
884
885         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set command][%p] Command(%s)", vc_command, cmd->command);
886
887         return 0;
888 }
889
890 int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
891 {
892         if (0 != __vc_cmd_get_feature_enabled()) {
893                 return VC_ERROR_NOT_SUPPORTED;
894         }
895         if (0 != __vc_cmd_check_privilege()) {
896                 return VC_ERROR_PERMISSION_DENIED;
897         }
898
899         if (NULL == vc_command || NULL == command) {
900                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
901                 return VC_ERROR_INVALID_PARAMETER;
902         }
903
904         vc_cmd_s* cmd = NULL;
905         cmd = (vc_cmd_s*)vc_command;
906
907         if (NULL != cmd->command) {
908                 *command = strdup(gettext(cmd->command));
909         }
910
911         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get command][%p] Command(%s)", vc_command, *command);
912
913         return 0;
914 }
915
916 int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
917 {
918         if (0 != __vc_cmd_get_feature_enabled()) {
919                 return VC_ERROR_NOT_SUPPORTED;
920         }
921         if (0 != __vc_cmd_check_privilege()) {
922                 return VC_ERROR_PERMISSION_DENIED;
923         }
924
925         if (NULL == vc_command) {
926                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
927                 return VC_ERROR_INVALID_PARAMETER;
928         }
929
930         vc_cmd_s* cmd = NULL;
931         cmd = (vc_cmd_s*)vc_command;
932
933         if (NULL != cmd->parameter) {
934                 free(cmd->parameter);
935         }
936
937         cmd->parameter = NULL;
938
939         if (NULL != command) {
940                 cmd->parameter = strdup(command);
941                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Set unfixed command][%p] unfixed command(%s)", vc_command, cmd->parameter);
942         }
943
944         return 0;
945 }
946
947 int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
948 {
949         if (0 != __vc_cmd_get_feature_enabled()) {
950                 return VC_ERROR_NOT_SUPPORTED;
951         }
952
953         if (NULL == vc_command || NULL == command) {
954                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
955                 return VC_ERROR_INVALID_PARAMETER;
956         }
957
958         vc_cmd_s* cmd = NULL;
959         cmd = (vc_cmd_s*)vc_command;
960
961         if (NULL != cmd->parameter) {
962                 *command = strdup(gettext(cmd->parameter));
963                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get unfixed command][%p] unfixed command(%s)", vc_command, *command);
964         }
965
966         return 0;
967 }
968
969 int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed)
970 {
971         if (0 != __vc_cmd_get_feature_enabled()) {
972                 return VC_ERROR_NOT_SUPPORTED;
973         }
974
975         if (NULL == vc_command) {
976                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
977                 return VC_ERROR_INVALID_PARAMETER;
978         }
979
980         if (NULL == fixed) {
981                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, fixed is NULL");
982                 return VC_ERROR_INVALID_PARAMETER;
983         }
984
985         vc_cmd_s* cmd = NULL;
986         cmd = (vc_cmd_s*)vc_command;
987
988         if (NULL != cmd->fixed) {
989                 free(cmd->fixed);
990                 cmd->fixed = NULL;
991         }
992
993         cmd->fixed = strdup(fixed);
994
995         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] fixed command(%s)", vc_command, cmd->fixed);
996         return 0;
997 }
998
999 int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed)
1000 {
1001         if (0 != __vc_cmd_get_feature_enabled()) {
1002                 return VC_ERROR_NOT_SUPPORTED;
1003         }
1004
1005         if (NULL == vc_command || NULL == fixed) {
1006                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1007                 return VC_ERROR_INVALID_PARAMETER;
1008         }
1009
1010         vc_cmd_s* cmd = NULL;
1011         cmd = (vc_cmd_s*)vc_command;
1012
1013         if (NULL != cmd->fixed) {
1014                 *fixed = strdup(gettext(cmd->fixed));
1015                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get fixed command][%p] fixed command(%s)", vc_command, *fixed);
1016         }
1017
1018         return 0;
1019 }
1020
1021 int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation_name)
1022 {
1023         if (0 != __vc_cmd_get_feature_enabled()) {
1024                 return VC_ERROR_NOT_SUPPORTED;
1025         }
1026
1027         if (NULL == vc_command) {
1028                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
1029                 return VC_ERROR_INVALID_PARAMETER;
1030         }
1031
1032         if (NULL == invocation_name) {
1033                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, invocation_name is NULL");
1034                 return VC_ERROR_INVALID_PARAMETER;
1035         }
1036
1037         vc_cmd_s* cmd = NULL;
1038         cmd = (vc_cmd_s*)vc_command;
1039
1040         if (NULL != cmd->invocation_name) {
1041                 free(cmd->invocation_name);
1042                 cmd->invocation_name = NULL;
1043         }
1044
1045         cmd->invocation_name = strdup(invocation_name);
1046
1047         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set invocation name][%p] invocation_name(%s)", vc_command, cmd->invocation_name);
1048         return 0;
1049 }
1050
1051 int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation_name)
1052 {
1053         if (0 != __vc_cmd_get_feature_enabled()) {
1054                 return VC_ERROR_NOT_SUPPORTED;
1055         }
1056
1057         if (NULL == vc_command || NULL == invocation_name) {
1058                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1059                 return VC_ERROR_INVALID_PARAMETER;
1060         }
1061
1062         vc_cmd_s* cmd = NULL;
1063         cmd = (vc_cmd_s*)vc_command;
1064
1065         if (NULL != cmd->invocation_name) {
1066                 *invocation_name = strdup(gettext(cmd->invocation_name));
1067         }
1068
1069         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get invocation name][%p] invocation_name(%s)", vc_command, *invocation_name);
1070         return 0;
1071 }
1072
1073 int vc_cmd_set_type(vc_cmd_h vc_command, int type)
1074 {
1075         if (0 != __vc_cmd_get_feature_enabled()) {
1076                 return VC_ERROR_NOT_SUPPORTED;
1077         }
1078         if (0 != __vc_cmd_check_privilege()) {
1079                 return VC_ERROR_PERMISSION_DENIED;
1080         }
1081
1082         if (NULL == vc_command) {
1083                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1084                 return VC_ERROR_INVALID_PARAMETER;
1085         }
1086
1087         vc_cmd_s* cmd = NULL;
1088         cmd = (vc_cmd_s*)vc_command;
1089
1090         cmd->type = type;
1091
1092         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
1093
1094         return 0;
1095 }
1096
1097 int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
1098 {
1099         if (0 != __vc_cmd_get_feature_enabled()) {
1100                 return VC_ERROR_NOT_SUPPORTED;
1101         }
1102         if (0 != __vc_cmd_check_privilege()) {
1103                 return VC_ERROR_PERMISSION_DENIED;
1104         }
1105
1106         if (NULL == vc_command || NULL == type) {
1107                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1108                 return VC_ERROR_INVALID_PARAMETER;
1109         }
1110
1111         vc_cmd_s* cmd = NULL;
1112         cmd = (vc_cmd_s*)vc_command;
1113
1114         *type = cmd->type;
1115
1116         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get type][%p] type(%d)", vc_command, *type);
1117
1118         return 0;
1119 }
1120
1121 int vc_cmd_set_format(vc_cmd_h vc_command, int format)
1122 {
1123         if (0 != __vc_cmd_get_feature_enabled()) {
1124                 return VC_ERROR_NOT_SUPPORTED;
1125         }
1126
1127         if (NULL == vc_command) {
1128                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1129                 return VC_ERROR_INVALID_PARAMETER;
1130         }
1131
1132         vc_cmd_s* cmd = NULL;
1133         cmd = (vc_cmd_s*)vc_command;
1134
1135         cmd->format = format;
1136
1137         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set format][%p] format(%d)", vc_command, format);
1138
1139         return 0;
1140 }
1141
1142 int vc_cmd_get_format(vc_cmd_h vc_command, int* format)
1143 {
1144         if (0 != __vc_cmd_get_feature_enabled()) {
1145                 return VC_ERROR_NOT_SUPPORTED;
1146         }
1147
1148         if (NULL == vc_command || NULL == format) {
1149                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1150                 return VC_ERROR_INVALID_PARAMETER;
1151         }
1152
1153         vc_cmd_s* cmd = NULL;
1154         cmd = (vc_cmd_s*)vc_command;
1155
1156         *format = cmd->format;
1157
1158         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get format][%p] format(%d)", vc_command, *format);
1159
1160         return 0;
1161 }
1162
1163 int vc_cmd_set_pid(vc_cmd_h vc_command, int pid)
1164 {
1165         if (0 != __vc_cmd_get_feature_enabled()) {
1166                 return VC_ERROR_NOT_SUPPORTED;
1167         }
1168         if (0 != __vc_cmd_check_privilege()) {
1169                 return VC_ERROR_PERMISSION_DENIED;
1170         }
1171
1172         if (NULL == vc_command) {
1173                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1174                 return VC_ERROR_INVALID_PARAMETER;
1175         }
1176
1177         vc_cmd_s* cmd = NULL;
1178         cmd = (vc_cmd_s*)vc_command;
1179
1180         cmd->pid = pid;
1181
1182         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set pid][%p] pid(%d)", vc_command, cmd->pid);
1183
1184         return 0;
1185 }
1186
1187 int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
1188 {
1189         if (0 != __vc_cmd_get_feature_enabled()) {
1190                 return VC_ERROR_NOT_SUPPORTED;
1191         }
1192         if (0 != __vc_cmd_check_privilege()) {
1193                 return VC_ERROR_PERMISSION_DENIED;
1194         }
1195
1196         if (NULL == vc_command || NULL == pid) {
1197                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1198                 return VC_ERROR_INVALID_PARAMETER;
1199         }
1200
1201         vc_cmd_s* cmd = NULL;
1202         cmd = (vc_cmd_s*)vc_command;
1203
1204         *pid = cmd->pid;
1205
1206         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get pid][%p] pid(%d)", vc_command, *pid);
1207
1208         return 0;
1209 }
1210
1211 int vc_cmd_set_domain(vc_cmd_h vc_command, int domain)
1212 {
1213         if (0 != __vc_cmd_get_feature_enabled()) {
1214                 return VC_ERROR_NOT_SUPPORTED;
1215         }
1216         if (0 != __vc_cmd_check_privilege()) {
1217                 return VC_ERROR_PERMISSION_DENIED;
1218         }
1219
1220         if (NULL == vc_command) {
1221                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1222                 return VC_ERROR_INVALID_PARAMETER;
1223         }
1224
1225         vc_cmd_s* cmd = NULL;
1226         cmd = (vc_cmd_s*)vc_command;
1227
1228         cmd->domain = domain;
1229
1230         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set domain] domain : %d", domain);
1231
1232         return 0;
1233 }
1234
1235 int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
1236 {
1237         if (0 != __vc_cmd_get_feature_enabled()) {
1238                 return VC_ERROR_NOT_SUPPORTED;
1239         }
1240         if (0 != __vc_cmd_check_privilege()) {
1241                 return VC_ERROR_PERMISSION_DENIED;
1242         }
1243
1244         if (NULL == vc_command || NULL == domain) {
1245                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1246                 return VC_ERROR_INVALID_PARAMETER;
1247         }
1248
1249         vc_cmd_s* cmd = NULL;
1250         cmd = (vc_cmd_s*)vc_command;
1251
1252         *domain = cmd->domain;
1253
1254         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get domain] domain : %d", *domain);
1255
1256         return 0;
1257 }
1258
1259 /**
1260 * @brief Sets key value of command.
1261 *
1262 * @param[in] vc_command Command handle
1263 * @param[in] key key value
1264 * @param[in] modifier modifier value
1265 *
1266 * @return 0 on success, otherwise a negative error value
1267 * @retval #VC_ERROR_NONE Successful
1268 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1269 *
1270 * @see vc_cmd_get_result_key()
1271 */
1272 int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
1273 {
1274         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Set result key");
1275
1276         if (NULL == vc_command) {
1277                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1278                 return VC_ERROR_INVALID_PARAMETER;
1279         }
1280
1281         vc_cmd_s* cmd = NULL;
1282         cmd = (vc_cmd_s*)vc_command;
1283
1284         SLOG(LOG_DEBUG, TAG_VCCMD, "key : %d, modifier : %d", key, modifier);
1285
1286         cmd->key = key;
1287         cmd->modifier = modifier;
1288
1289         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
1290         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1291
1292         return 0;
1293 }
1294
1295 /**
1296 * @brief Gets key value of command.
1297 *
1298 * @param[in] vc_command Command handle
1299 * @param[out] key key value
1300 * @param[out] modifier modifier value
1301 *
1302 * @return 0 on success, otherwise a negative error value
1303 * @retval #VC_ERROR_NONE Successful
1304 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1305 *
1306 * @see vc_cmd_add_result_key()
1307 */
1308 int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
1309 {
1310         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Get result key");
1311
1312         if (NULL == vc_command || NULL == key || NULL == modifier) {
1313                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1314                 return VC_ERROR_INVALID_PARAMETER;
1315         }
1316
1317         vc_cmd_s* cmd = NULL;
1318         cmd = (vc_cmd_s*)vc_command;
1319
1320         *key = cmd->key;
1321         *modifier = cmd->modifier;
1322
1323         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
1324         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1325
1326         return 0;
1327 }
1328
1329 int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
1330 {
1331         if (NULL == vc_cmd_list) {
1332                 return -1;
1333         }
1334
1335         vc_cmd_list_s* list = NULL;
1336         list = (vc_cmd_list_s*)vc_cmd_list;
1337
1338         SLOG(LOG_DEBUG, TAG_VCCMD, "=== Command List ===");
1339         SLOG(LOG_DEBUG, TAG_VCCMD, "[List][%p]", list);
1340
1341         int count = g_slist_length(list->list);
1342
1343         int i;
1344         vc_cmd_s *cmd = NULL;
1345
1346         for (i = 0; i < count ; i++) {
1347                 cmd = g_slist_nth_data(list->list, i);
1348
1349                 if (NULL != cmd) {
1350                         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)",
1351                          i, cmd, cmd->pid, cmd->index, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
1352                 }
1353         }
1354
1355         SLOG(LOG_DEBUG, TAG_VCCMD, "==================");
1356         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1357
1358         return 0;
1359 }
1360
1361 int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json)
1362 {
1363         if (0 != __vc_cmd_get_feature_enabled()) {
1364                 return VC_ERROR_NOT_SUPPORTED;
1365         }
1366
1367         if (NULL == vc_cmd || NULL == json) {
1368                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] NULL parameter");
1369                 return VC_ERROR_INVALID_PARAMETER;
1370         }
1371
1372         vc_cmd_s* cmd = NULL;
1373         cmd = (vc_cmd_s*)vc_cmd;
1374
1375         if (VC_CMD_FORMAT_ACTION != cmd->format) {
1376                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not Action format");
1377                 return VC_ERROR_INVALID_PARAMETER;
1378         }
1379
1380         if (0 != vc_info_parser_get_nlu_result(json)) {
1381                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get nlu result");
1382                 return VC_ERROR_OPERATION_FAILED;
1383         }
1384
1385         return 0;
1386 }
1387
1388 static void __vc_cmd_regex_deinit(int num_regex)
1389 {
1390         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start Deinitialize regex ====");
1391         int i;
1392
1393         for (i = 0; num_regex > i; i++) {
1394                 regfree(&reg[i]);
1395         }
1396
1397         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
1398         SLOG(LOG_DEBUG, TAG_VCCMD, "");
1399 }
1400
1401 static int __vc_cmd_regex_init()
1402 {
1403         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Initialize regular expression ====");
1404
1405         int cflags = REG_EXTENDED | REG_ICASE;
1406         int ret;
1407         char errStr[128];
1408         char *lang = NULL;
1409         int lang_type = 1;
1410
1411         vc_config_mgr_get_default_language(&lang);
1412         if (NULL == lang) {
1413                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1414                 return VC_ERROR_OPERATION_FAILED;
1415         }
1416
1417         if (!strcmp("en_US", lang)) {
1418                 lang_type = 1;
1419         } else if (!strcmp("ko_KR", lang)) {
1420                 lang_type = 0;
1421         } else {
1422                 free(lang);
1423                 lang = NULL;
1424
1425                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not supported language type");
1426                 return VC_ERROR_INVALID_LANGUAGE;
1427         }
1428
1429         free(lang);
1430         lang = NULL;
1431
1432         SLOG(LOG_DEBUG, TAG_VCCMD, "==== lang type > %d ====", lang_type);
1433
1434         re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
1435
1436         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s" , TIME_ABS1_REGEX[lang_type]);
1437         ret = regcomp(&reg[0], TIME_ABS1_REGEX[lang_type], cflags);
1438         if (0 != ret) {
1439                 regerror(ret, &reg[0], errStr, sizeof(errStr));
1440
1441                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1442                 return VC_ERROR_OPERATION_FAILED;
1443         }
1444
1445         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS2_REGEX[lang_type]);
1446         ret = regcomp(&reg[1], TIME_ABS2_REGEX[lang_type], cflags);
1447         if (0 != ret) {
1448                 regerror(ret, &reg[1], errStr, sizeof(errStr));
1449                 __vc_cmd_regex_deinit(1);
1450
1451                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1452                 return VC_ERROR_OPERATION_FAILED;
1453         }
1454
1455         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS3_REGEX[lang_type]);
1456         ret = regcomp(&reg[2], TIME_ABS3_REGEX[lang_type], cflags);
1457         if (0 != ret) {
1458                 regerror(ret, &reg[2], errStr, sizeof(errStr));
1459                 __vc_cmd_regex_deinit(2);
1460
1461                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1462                 return VC_ERROR_OPERATION_FAILED;
1463         }
1464
1465         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL1_REGEX[lang_type]);
1466         ret = regcomp(&reg[3], TIME_REL1_REGEX[lang_type], cflags);
1467         if (0 != ret) {
1468                 regerror(ret, &reg[3], errStr, sizeof(errStr));
1469                 __vc_cmd_regex_deinit(3);
1470
1471                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1472                 return VC_ERROR_OPERATION_FAILED;
1473         }
1474
1475         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL2_REGEX[lang_type]);
1476         ret = regcomp(&reg[4], TIME_REL2_REGEX[lang_type], cflags);
1477         if (0 != ret) {
1478                 regerror(ret, &reg[4], errStr, sizeof(errStr));
1479                 __vc_cmd_regex_deinit(4);
1480
1481                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1482                 return VC_ERROR_OPERATION_FAILED;
1483         }
1484
1485         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL3_REGEX[lang_type]);
1486         ret = regcomp(&reg[5], TIME_REL3_REGEX[lang_type], cflags);
1487         if (0 != ret) {
1488                 regerror(ret, &reg[5], errStr, sizeof(errStr));
1489                 __vc_cmd_regex_deinit(5);
1490
1491                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1492                 return VC_ERROR_OPERATION_FAILED;
1493         }
1494
1495         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_PHR_REGEX[lang_type]);
1496         ret = regcomp(&reg[6], TIME_PHR_REGEX[lang_type], cflags);
1497         if (0 != ret) {
1498                 regerror(ret, &reg[6], errStr, sizeof(errStr));
1499                 __vc_cmd_regex_deinit(6);
1500
1501                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1502                 return VC_ERROR_OPERATION_FAILED;
1503         }
1504
1505         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS1_REGEX[lang_type]);
1506         ret = regcomp(&reg[7], DATE_ABS1_REGEX[lang_type], cflags);
1507         if (0 != ret) {
1508                 regerror(ret, &reg[7], errStr, sizeof(errStr));
1509                 __vc_cmd_regex_deinit(7);
1510
1511                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1512                 return VC_ERROR_OPERATION_FAILED;
1513         }
1514
1515         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS2_REGEX[lang_type]);
1516         ret = regcomp(&reg[8], DATE_ABS2_REGEX[lang_type], cflags);
1517         if (0 != ret) {
1518                 regerror(ret, &reg[8], errStr, sizeof(errStr));
1519                 __vc_cmd_regex_deinit(8);
1520
1521                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1522                 return VC_ERROR_OPERATION_FAILED;
1523         }
1524
1525         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS3_REGEX[lang_type]);
1526         ret = regcomp(&reg[9], DATE_ABS3_REGEX[lang_type], cflags);
1527         if (0 != ret) {
1528                 regerror(ret, &reg[9], errStr, sizeof(errStr));
1529                 __vc_cmd_regex_deinit(9);
1530
1531                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1532                 return VC_ERROR_OPERATION_FAILED;
1533         }
1534
1535         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR1_REGEX[lang_type]);
1536         ret = regcomp(&reg[10], DATE_PHR1_REGEX[lang_type], cflags);
1537         if (0 != ret) {
1538                 regerror(ret, &reg[10], errStr, sizeof(errStr));
1539                 __vc_cmd_regex_deinit(10);
1540
1541                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1542                 return VC_ERROR_OPERATION_FAILED;
1543         }
1544
1545         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR2_REGEX[lang_type]);
1546         ret = regcomp(&reg[11], DATE_PHR2_REGEX[lang_type], cflags);
1547         if (0 != ret) {
1548                 regerror(ret, &reg[11], errStr, sizeof(errStr));
1549                 __vc_cmd_regex_deinit(11);
1550
1551                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1552                 return VC_ERROR_OPERATION_FAILED;
1553         }
1554
1555         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
1556         SLOG(LOG_DEBUG, TAG_VCCMD, "");
1557
1558         return VC_ERROR_NONE;
1559 }
1560
1561 static void __vc_cmd_add_year(struct tm *td, int year)
1562 {
1563         td->tm_year += year;
1564 }
1565
1566 static void __vc_cmd_add_mon(struct tm *td, int mon)
1567 {
1568         int year = 0;
1569
1570         mon = td->tm_mon + mon;
1571         year = mon / 12;
1572
1573         if (0 < year) {
1574                 __vc_cmd_add_year(td, year);
1575         }
1576
1577         td->tm_mon = mon % 12;
1578 }
1579
1580 static void __vc_cmd_add_mday(struct tm *td, int mday)
1581 {
1582         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
1583         int year = td->tm_year + 1900;
1584
1585         int mon = 0;
1586
1587         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) max_day[1] = 29;
1588
1589         mday = td->tm_mday + mday;
1590
1591         for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) {
1592                 mday -= max_day[mon % 12];
1593
1594                 if (11 == mon % 12) {
1595                         year++;
1596
1597                         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) {
1598                                 max_day[1] = 29;
1599                         } else {
1600                                 max_day[1] = 28;
1601                         }
1602                 }
1603         }
1604
1605         mon = mon - td->tm_mon;
1606
1607         if (0 < mon) {
1608                 __vc_cmd_add_mon(td, mon);
1609         }
1610
1611         td->tm_mday = mday;
1612 }
1613
1614 static void __vc_cmd_add_hour(struct tm *td, int hour)
1615 {
1616         int day = 0;
1617
1618         hour = td->tm_hour + hour;
1619         day = hour / 24;
1620
1621         if (0 < day) {
1622                 __vc_cmd_add_mday(td, day);
1623         }
1624
1625         td->tm_hour = hour % 24;
1626 }
1627
1628 static void __vc_cmd_add_min(struct tm *td, int min)
1629 {
1630         int hour = 0;
1631
1632         min = td->tm_min + min;
1633         hour = min / 60;
1634
1635         if (0 < hour) {
1636                 __vc_cmd_add_hour(td, hour);
1637         }
1638
1639         td->tm_min = min % 60;
1640 }
1641
1642 static void __copy_struct_tm(struct tm *des, struct tm *src)
1643 {
1644         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start to copy struct tm ====");
1645
1646         des->tm_sec     = src->tm_sec;
1647         des->tm_min     = src->tm_min;
1648         des->tm_hour    = src->tm_hour;
1649         des->tm_mday    = src->tm_mday;
1650         des->tm_mon     = src->tm_mon;
1651         des->tm_year    = src->tm_year;
1652         des->tm_wday    = src->tm_wday;
1653         des->tm_yday    = src->tm_yday;
1654         des->tm_isdst   = src->tm_isdst;
1655
1656         des->tm_gmtoff  = src->tm_gmtoff;
1657         des->tm_zone    = src->tm_zone;
1658 }
1659
1660 static void __update_data_sidx(int idx)
1661 {
1662         if (0 > g_data_sidx || idx < g_data_sidx) g_data_sidx = idx;
1663 }
1664
1665 static void __update_data_eidx(int idx)
1666 {
1667         if (0 > g_data_eidx || idx > g_data_eidx) g_data_eidx = idx;
1668 }
1669
1670 static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist)
1671 {
1672         regmatch_t pmatch[3];
1673         int ret;
1674         int len;
1675         int idx;
1676
1677         *exist = 0;
1678         ret = regexec(&reg[6], str, 3, pmatch, 0);
1679         if (0 == ret) {
1680                 idx = 1;
1681                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1682                 if (0 < len) {
1683                         if (12 < td->tm_hour) {
1684                                 __vc_cmd_add_mday(td, 1);
1685                         }
1686
1687                         td->tm_hour = 12;
1688                 } else {
1689                         idx = 2;
1690                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1691
1692                         __vc_cmd_add_mday(td, 1);
1693                 }
1694
1695                 td->tm_min = 0;
1696                 td->tm_sec = 0;
1697                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1698
1699                 __update_data_sidx(pmatch[0].rm_so);
1700                 __update_data_eidx(pmatch[0].rm_eo);
1701
1702                 *exist = 1;
1703                 return VC_ERROR_NONE;
1704         }
1705
1706         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1707         return VC_ERROR_NONE;
1708 }
1709
1710 static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist)
1711 {
1712         regmatch_t pmatch[2];
1713         int ret;
1714         int len;
1715         int sidx = -1;
1716         int eidx = -1;
1717         int hour = -1;
1718         int min = -1;
1719
1720         char *tempstr = NULL;
1721
1722         *exist = 0;
1723         ret = regexec(&reg[3], str, 1, pmatch, 0);
1724         if (0 == ret) {
1725                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so);
1726                 hour = min = -1;
1727
1728                 sidx = pmatch[0].rm_so;
1729                 eidx = pmatch[0].rm_eo;
1730
1731                 ret = regexec(&reg[4], str, 2, pmatch, 0);
1732                 if (0 == ret) {
1733                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1734                         tempstr = strndup(str + pmatch[1].rm_so, len);
1735
1736                         if (NULL == tempstr) {
1737                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1738                                 return VC_ERROR_OUT_OF_MEMORY;
1739                         }
1740
1741                         hour = atoi(tempstr);
1742
1743                         free(tempstr);
1744                         tempstr = NULL;
1745
1746                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1747
1748                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1749                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1750                 }
1751
1752                 ret = regexec(&reg[5], str, 2, pmatch, 0);
1753                 if (0 == ret) {
1754                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1755                         tempstr = strndup(str + pmatch[1].rm_so, len);
1756
1757                         if (NULL == tempstr) {
1758                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1759                                 return VC_ERROR_OUT_OF_MEMORY;
1760                         }
1761
1762                         min = atoi(tempstr);
1763
1764                         free(tempstr);
1765                         tempstr = NULL;
1766
1767                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1768
1769                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1770                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1771                 }
1772
1773                 if (hour < 0 && min < 0) {
1774                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1775                         return VC_ERROR_NONE;
1776                 }
1777
1778                 hour = 0 > hour ? 0 : hour;
1779                 min = 0 > min ? 0 : min;
1780
1781                 min = min + (hour * 60);
1782
1783                 __vc_cmd_add_min(td, min);
1784                 td->tm_sec = 0;
1785
1786                 __update_data_sidx(sidx);
1787                 __update_data_eidx(eidx);
1788
1789                 *exist = 1;
1790                 return VC_ERROR_NONE;
1791         }
1792
1793         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1794         return VC_ERROR_NONE;
1795 }
1796
1797 static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist)
1798 {
1799         regmatch_t pmatch[5];
1800         int ret;
1801         int len;
1802         int idx;
1803         int flag = -1;
1804         int hour = -1;
1805         int min = -1;
1806         int sidx = -1;
1807         int eidx = -1;
1808         char *tempstr = NULL;
1809
1810         *exist = 0;
1811         ret = regexec(&reg[0], str, 5, pmatch, 0);
1812         if (0 == ret) {
1813                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1814
1815                 flag = idx & 1;
1816
1817                 sidx = pmatch[0].rm_so;
1818                 eidx = pmatch[0].rm_eo;
1819         }
1820
1821         ret = regexec(&reg[1], str, 2, pmatch, 0);
1822         if (0 == ret) {
1823                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
1824                 tempstr = strndup(str + pmatch[1].rm_so, len);
1825
1826                 if (NULL == tempstr) {
1827                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1828                         return VC_ERROR_OUT_OF_MEMORY;
1829                 }
1830
1831                 hour = atoi(tempstr);
1832
1833                 if (0 <= flag) {
1834                         hour = hour + 12 * flag;
1835
1836                         if (12 == hour) hour = 0;
1837                         else if (24 == hour) hour = 12;
1838                 }
1839
1840                 if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) {
1841                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1842                         return VC_ERROR_NONE;
1843                 }
1844
1845                 free(tempstr);
1846                 tempstr = NULL;
1847
1848                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1849
1850                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1851                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1852         } else if (0 < flag) {
1853                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1854                 return VC_ERROR_NONE;
1855         }
1856
1857         ret = regexec(&reg[2], str, 2, pmatch, 0);
1858         if (0 == ret) {
1859                 idx = 1;
1860                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1861                 if (0 < len) {
1862                         tempstr = strndup(str + pmatch[idx].rm_so, len);
1863
1864                         if (NULL == tempstr) {
1865                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1866                                 return VC_ERROR_OUT_OF_MEMORY;
1867                         }
1868
1869                         min = atoi(tempstr);
1870
1871                         if (0 > min || 60 <= min) {
1872                                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1873                                 return VC_ERROR_NONE;
1874                         }
1875
1876                         td->tm_sec = 0;
1877
1878                         free(tempstr);
1879                         tempstr = NULL;
1880                 } else {
1881                         idx = 0;
1882                         min = 30;
1883                 }
1884
1885                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so);
1886                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1887                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1888         }
1889
1890         if (0 > hour && 0 > min) {
1891                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1892                 return VC_ERROR_NONE;
1893         }
1894
1895         if (0 <= min && 0 <= hour) {
1896                 if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1);
1897
1898                 td->tm_hour = hour;
1899                 td->tm_min = min;
1900         } else if (0 <= min) {
1901                 char *lang = NULL;
1902                 vc_config_mgr_get_default_language(&lang);
1903                 if (NULL == lang) {
1904                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1905                         return VC_ERROR_OPERATION_FAILED;
1906                 }
1907
1908                 if (!strcmp("en_US", lang)) {
1909                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1910                         free(lang);
1911                         lang = NULL;
1912                         return VC_ERROR_NONE;
1913                 }
1914                 if (min <= td->tm_min) __vc_cmd_add_hour(td, 1);
1915
1916                 td->tm_min = min;
1917
1918                 free(lang);
1919                 lang = NULL;
1920         } else {
1921                 if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1);
1922
1923                 td->tm_hour = hour;
1924                 td->tm_min = 0;
1925         }
1926
1927         td->tm_sec = 0;
1928
1929         __update_data_sidx(sidx);
1930         __update_data_eidx(eidx);
1931
1932         *exist = 1;
1933         return VC_ERROR_NONE;
1934 }
1935
1936 static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist)
1937 {
1938         regmatch_t pmatch[10];
1939         int ret;
1940         int len;
1941         int idx;
1942
1943         *exist = 0;
1944         ret = regexec(&reg[10], str, 5, pmatch, 0);
1945         if (0 == ret) {
1946                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1947
1948                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1949
1950                 td->tm_year = td_now.tm_year;
1951                 td->tm_mon = td_now.tm_mon;
1952                 td->tm_mday = td_now.tm_mday;
1953
1954                 __vc_cmd_add_mday(td, idx - 1);
1955
1956                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1957
1958                 __update_data_sidx(pmatch[0].rm_so);
1959                 __update_data_eidx(pmatch[0].rm_eo);
1960
1961                 *exist = 1;
1962                 return VC_ERROR_NONE;
1963         }
1964
1965         ret = regexec(&reg[11], str, 10, pmatch, 0);
1966         if (0 == ret) {
1967                 for (idx = 1; 10 > idx; idx++) {
1968                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1969
1970                         if (0 < len) break;
1971                 }
1972
1973                 td->tm_year = td_now.tm_year;
1974                 td->tm_mon = td_now.tm_mon;
1975                 td->tm_mday = td_now.tm_mday;
1976
1977                 __vc_cmd_add_mday(td, idx + 1);
1978
1979                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1980
1981                 __update_data_sidx(pmatch[0].rm_so);
1982                 __update_data_eidx(pmatch[0].rm_eo);
1983
1984                 *exist = 1;
1985                 return VC_ERROR_NONE;
1986         }
1987
1988         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1989         return VC_ERROR_NONE;
1990 }
1991
1992 static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist)
1993 {
1994         regmatch_t pmatch[13];
1995         int ret;
1996         int len;
1997         int idx;
1998         int sidx = -1;
1999         int eidx = -1;
2000         int y_flag = 0;
2001         int m_flag = 0;
2002         int year = 0;
2003         int mon = 0;
2004         int day = 0;
2005         char *tempstr = NULL;
2006
2007         *exist = 0;
2008         ret = regexec(&reg[9], str, 2, pmatch, 0);
2009         if (0 == ret) {
2010                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
2011                 tempstr = strndup(str + pmatch[1].rm_so, len);
2012
2013                 if (NULL == tempstr) {
2014                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2015                         return VC_ERROR_OUT_OF_MEMORY;
2016                 }
2017
2018                 day = atoi(tempstr);
2019
2020                 free(tempstr);
2021                 tempstr = NULL;
2022
2023                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2024
2025                 sidx = pmatch[0].rm_so;
2026                 eidx = pmatch[0].rm_eo;
2027         } else {
2028                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2029                 return VC_ERROR_NONE;
2030         }
2031
2032         ret = regexec(&reg[8], str, 13, pmatch, 0);
2033         if (0 == ret) {
2034                 for (idx = 1; 13 > idx; idx++) {
2035                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2036
2037                         if (0 < len) {
2038                                 mon = idx - 1;
2039                                 break;
2040                         }
2041                 }
2042
2043                 m_flag = 1;
2044
2045                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2046
2047                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2048                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2049         } else {
2050                 char *lang = NULL;
2051                 vc_config_mgr_get_default_language(&lang);
2052                 if (NULL == lang) {
2053                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
2054                         return VC_ERROR_OPERATION_FAILED;
2055                 }
2056
2057                 if (!strcmp("en_US", lang)) {
2058                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2059                         free(lang);
2060                         lang = NULL;
2061                         return VC_ERROR_NONE;
2062                 }
2063
2064                 free(lang);
2065                 lang = NULL;
2066
2067                 mon = td->tm_mon;
2068         }
2069
2070         ret = regexec(&reg[7], str, 3, pmatch, 0);
2071         if (0 == ret) {
2072                 if (!m_flag) return -1;
2073
2074                 len = pmatch[2].rm_eo - pmatch[2].rm_so;
2075                 tempstr = strndup(str + pmatch[2].rm_so, len);
2076
2077                 if (NULL == tempstr) {
2078                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2079                         return VC_ERROR_OUT_OF_MEMORY;
2080                 }
2081
2082                 year = atoi(tempstr);
2083                 year = 1900 < year ? year - 1900 : year + 100;
2084
2085                 free(tempstr);
2086                 tempstr = NULL;
2087
2088                 y_flag = 1;
2089                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2090
2091                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2092                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2093         } else {
2094                 year = td->tm_year;
2095         }
2096
2097         if (0 > g_time_flag) {
2098                 td->tm_hour = 0;
2099                 td->tm_min = 0;
2100                 td->tm_sec = 0;
2101         } else if (2 == g_time_flag) {
2102                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2103                 return VC_ERROR_NONE;
2104         }
2105
2106         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
2107         if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29;
2108
2109         if (max_day[mon] < day || 1 > day) {
2110                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2111                 return VC_ERROR_NONE;
2112         }
2113
2114         td->tm_year = year;
2115         td->tm_mon = mon;
2116         td->tm_mday = day;
2117
2118         if (!y_flag) {
2119                 if (!m_flag) {
2120                         if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1);
2121                 } else {
2122                         if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1);
2123                         else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1);
2124                 }
2125         }
2126
2127         __update_data_sidx(sidx);
2128         __update_data_eidx(eidx);
2129
2130         *exist = 1;
2131         return VC_ERROR_NONE;
2132 }
2133
2134 static int __vc_cmd_time_check(const char *str, struct tm *td)
2135 {
2136         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check time value in string \"%s\"", str);
2137
2138         vc_error_e ret;
2139         int exist = 0;
2140
2141         ret = __vc_cmd_tphrase_check(str, td, &exist);
2142         if (1 == exist) {
2143                 g_time_flag = 1;
2144
2145                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2146                 return ret;
2147         } else if (VC_ERROR_NONE != ret) {
2148                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2149                 return ret;
2150         }
2151
2152         ret = __vc_cmd_trelative_check(str, td, &exist);
2153         if (1 == exist) {
2154                 g_time_flag = 2;
2155
2156                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2157                 return ret;
2158         } else if (VC_ERROR_NONE != ret) {
2159                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2160                 return ret;
2161         }
2162
2163         ret = __vc_cmd_tabsolute_check(str, td, &exist);
2164         if (1 == exist) {
2165                 g_time_flag = 3;
2166
2167                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2168                 return ret;
2169         } else if (VC_ERROR_NONE != ret) {
2170                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2171                 return ret;
2172         }
2173
2174         SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no time value");
2175         return VC_ERROR_NONE;
2176 }
2177
2178 static int __vc_cmd_date_check(const char *str, struct tm *td)
2179 {
2180         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check date value in string \"%s\"", str);
2181
2182         vc_error_e ret;
2183         int exist = 0;
2184
2185         ret = __vc_cmd_dphrase_check(str, td, &exist);
2186         if (1 == exist) {
2187                 g_date_flag = 1;
2188
2189                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist");
2190                 return ret;
2191         } else if (VC_ERROR_NONE != ret) {
2192                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2193                 return ret;
2194         }
2195
2196         ret = __vc_cmd_dabsolute_check(str, td, &exist);
2197         if (1 == exist) {
2198                 g_date_flag = 1;
2199
2200                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist");
2201                 return ret;
2202         } else if (VC_ERROR_NONE != ret) {
2203                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2204                 return ret;
2205         }
2206
2207         SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no date value");
2208         return VC_ERROR_NONE;
2209 }
2210
2211 int vc_cmd_get_datetime(const char *text, time_t *result, char **remain)
2212 {
2213         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Get timestamp data");
2214
2215         struct tm td;
2216         const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
2217         vc_error_e ret;
2218
2219         if (NULL == text || NULL == result || NULL == remain) {
2220                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter");
2221                 return VC_ERROR_INVALID_PARAMETER;
2222         }
2223
2224         *result = -1;
2225         ret = __vc_cmd_regex_init();
2226         if (VC_ERROR_NONE != ret) {
2227                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed");
2228                 return ret;
2229         }
2230
2231         g_data_sidx = g_data_eidx = -1;
2232
2233         t_now = time(NULL);
2234         localtime_r(&t_now, &td_now);
2235         SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now);
2236
2237         __copy_struct_tm(&td, &td_now);
2238         SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2239                 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);
2240
2241         g_time_flag = g_date_flag = -1;
2242
2243         ret = __vc_cmd_time_check(text, &td);
2244         if (VC_ERROR_NONE != ret) {
2245                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret);
2246                 return ret;
2247         }
2248
2249         ret = __vc_cmd_date_check(text, &td);
2250         if (VC_ERROR_NONE != ret) {
2251                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret);
2252                 return ret;
2253         }
2254
2255         __vc_cmd_regex_deinit(12);
2256
2257         if (g_time_flag > 0 || g_date_flag > 0) {
2258                 *result = mktime(&td);
2259
2260                 SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %d", *result);
2261                 SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2262                         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);
2263
2264                 *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx));
2265
2266                 if (NULL == *remain) {
2267                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error");
2268                         return VC_ERROR_OUT_OF_MEMORY;
2269                 }
2270
2271                 strncpy(*remain, text, g_data_sidx);
2272                 strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx);
2273         } else {
2274                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text");
2275         }
2276
2277         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
2278         SLOG(LOG_DEBUG, TAG_VCCMD, "");
2279
2280         return VC_ERROR_NONE;
2281 }