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