Fix memory leak
[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                                 if (NULL != temp_cmd->appid)            free(temp_cmd->appid);
365                                 if (NULL != temp_cmd->invocation_name)  free(temp_cmd->invocation_name);
366                                 if (NULL != temp_cmd->fixed)            free(temp_cmd->fixed);
367                                 free(temp_cmd);
368                                 temp_cmd = NULL;
369                         }
370                 }
371         }
372         list->list = NULL;
373         list->index = -1;
374
375         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
376         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
377
378         return VC_ERROR_NONE;
379 }
380
381 int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data)
382 {
383         if (0 != __vc_cmd_get_feature_enabled()) {
384                 return VC_ERROR_NOT_SUPPORTED;
385         }
386         if (0 != __vc_cmd_check_privilege()) {
387                 return VC_ERROR_PERMISSION_DENIED;
388         }
389
390         if (NULL == vc_cmd_list) {
391                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
392                 return VC_ERROR_INVALID_PARAMETER;
393         }
394
395         vc_cmd_list_s* list = NULL;
396         list = (vc_cmd_list_s*)vc_cmd_list;
397
398         int count = g_slist_length(list->list);
399         int i ;
400
401         GSList *iter = NULL;
402         vc_cmd_s *temp_cmd;
403
404         iter = g_slist_nth(list->list, 0);
405
406         for (i = 0; i < count; i++) {
407                 if (NULL == iter) {
408                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
409                         return VC_ERROR_OPERATION_FAILED;
410                 }
411
412                 temp_cmd = iter->data;
413
414                 if (NULL != temp_cmd) {
415                         if (false == callback((vc_cmd_h)temp_cmd, user_data)) {
416                                 break;
417                         }
418
419                 }
420                 iter = g_slist_next(iter);
421         }
422
423         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Foreach commands Done");
424
425         return VC_ERROR_NONE;
426 }
427
428 int vc_cmd_list_filter_by_type(vc_cmd_list_h original, int type, vc_cmd_list_h* filtered)
429 {
430         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Filter by type");
431
432         if (0 != __vc_cmd_get_feature_enabled()) {
433                 return VC_ERROR_NOT_SUPPORTED;
434         }
435         if (0 != __vc_cmd_check_privilege()) {
436                 return VC_ERROR_PERMISSION_DENIED;
437         }
438
439         if (NULL == original) {
440                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
441                 return VC_ERROR_INVALID_PARAMETER;
442         }
443
444         if (VC_COMMAND_TYPE_NONE >= type || VC_COMMAND_TYPE_EXCLUSIVE < type) {
445                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid type");
446                 return VC_ERROR_INVALID_PARAMETER;
447         }
448
449         vc_cmd_list_s* list = NULL;
450         list = (vc_cmd_list_s*)original;
451
452         vc_cmd_list_h temp_list;
453         if (0 != vc_cmd_list_create(&temp_list)) {
454                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to list create");
455                 return VC_ERROR_OPERATION_FAILED;
456         }
457
458         int count = g_slist_length(list->list);
459         int i;
460
461         GSList *iter = NULL;
462         vc_cmd_s *iter_cmd;
463
464         iter = g_slist_nth(list->list, 0);
465
466         for (i = 0; i < count; i++) {
467                 if (NULL == iter) {
468                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
469                         return VC_ERROR_OPERATION_FAILED;
470                 }
471                 if (NULL != iter->data) {
472                         iter_cmd = iter->data;
473
474                         if (NULL != iter_cmd) {
475                                 int iter_type;
476                                 if (0 != vc_cmd_get_type((vc_cmd_h)iter_cmd, &iter_type)) {
477                                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command type");
478                                         continue;
479                                 }
480
481                                 if (iter_type == type) {
482                                         vc_cmd_h temp_cmd;
483                                         if (0 != vc_cmd_create(&temp_cmd)) {
484                                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to create cmd");
485                                                 continue;
486                                         }
487
488                                         memcpy(temp_cmd, iter_cmd, sizeof(vc_cmd_s));
489                                         if (NULL != iter_cmd->command) {
490                                                 ((vc_cmd_s*)temp_cmd)->command = strdup(iter_cmd->command);
491                                         }
492                                         if (NULL != iter_cmd->parameter) {
493                                                 ((vc_cmd_s*)temp_cmd)->parameter = strdup(iter_cmd->parameter);
494                                         }
495
496                                         if (0 != vc_cmd_list_add(temp_list, temp_cmd)) {
497                                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to cmd list add");
498                                                 vc_cmd_destroy(temp_cmd);
499                                                 continue;
500                                         }
501                                 }
502                         }
503                 }
504                 iter = g_slist_next(iter);
505         }
506
507         count = 0;
508         if (0 != vc_cmd_list_get_count(temp_list, &count)) {
509                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get count");
510         } else {
511                 SLOG(LOG_DEBUG, TAG_VCCMD, "Filtering result : (%d) command", count);
512         }
513
514         *filtered = temp_list;
515
516         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
517
518         return VC_ERROR_NONE;
519 }
520
521 int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list)
522 {
523         if (0 != __vc_cmd_get_feature_enabled()) {
524                 return VC_ERROR_NOT_SUPPORTED;
525         }
526         if (0 != __vc_cmd_check_privilege()) {
527                 return VC_ERROR_PERMISSION_DENIED;
528         }
529
530         if (NULL == vc_cmd_list) {
531                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
532                 return VC_ERROR_INVALID_PARAMETER;
533         }
534
535         vc_cmd_list_s* list = NULL;
536         list = (vc_cmd_list_s*)vc_cmd_list;
537
538         if (0 == g_slist_length(list->list)) {
539                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
540                 return VC_ERROR_EMPTY;
541         }
542
543         list->index = 0;
544
545         return VC_ERROR_NONE;
546 }
547
548 int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list)
549 {
550         if (0 != __vc_cmd_get_feature_enabled()) {
551                 return VC_ERROR_NOT_SUPPORTED;
552         }
553         if (0 != __vc_cmd_check_privilege()) {
554                 return VC_ERROR_PERMISSION_DENIED;
555         }
556
557         if (NULL == vc_cmd_list) {
558                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
559                 return VC_ERROR_INVALID_PARAMETER;
560         }
561
562         vc_cmd_list_s* list = NULL;
563         list = (vc_cmd_list_s*)vc_cmd_list;
564
565         int count = g_slist_length(list->list);
566
567         if (0 == count) {
568                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
569                 return VC_ERROR_EMPTY;
570         } else {
571                 list->index = count - 1;
572                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
573         }
574
575         return VC_ERROR_NONE;
576 }
577
578 int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
579 {
580         if (0 != __vc_cmd_get_feature_enabled()) {
581                 return VC_ERROR_NOT_SUPPORTED;
582         }
583         if (0 != __vc_cmd_check_privilege()) {
584                 return VC_ERROR_PERMISSION_DENIED;
585         }
586
587         if (NULL == vc_cmd_list) {
588                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
589                 return VC_ERROR_INVALID_PARAMETER;
590         }
591
592         vc_cmd_list_s* list = NULL;
593         list = (vc_cmd_list_s*)vc_cmd_list;
594
595         int count = g_slist_length(list->list);
596
597         if (list->index < count - 1) {
598                 list->index = list->index + 1;
599                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
600         } else {
601                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
602                 return VC_ERROR_ITERATION_END;
603         }
604
605         return VC_ERROR_NONE;
606 }
607
608 int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
609 {
610         if (0 != __vc_cmd_get_feature_enabled()) {
611                 return VC_ERROR_NOT_SUPPORTED;
612         }
613         if (0 != __vc_cmd_check_privilege()) {
614                 return VC_ERROR_PERMISSION_DENIED;
615         }
616
617         if (NULL == vc_cmd_list) {
618                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
619                 return VC_ERROR_INVALID_PARAMETER;
620         }
621
622         vc_cmd_list_s* list = NULL;
623         list = (vc_cmd_list_s*)vc_cmd_list;
624
625         if (list->index > 0) {
626                 list->index = list->index - 1;
627                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
628         } else {
629                 SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
630                 return VC_ERROR_ITERATION_END;
631         }
632
633         return VC_ERROR_NONE;
634 }
635
636 int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command)
637 {
638         if (0 != __vc_cmd_get_feature_enabled()) {
639                 return VC_ERROR_NOT_SUPPORTED;
640         }
641         if (0 != __vc_cmd_check_privilege()) {
642                 return VC_ERROR_PERMISSION_DENIED;
643         }
644
645         if (NULL == vc_cmd_list || NULL == vc_command) {
646                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
647                 return VC_ERROR_INVALID_PARAMETER;
648         }
649
650         vc_cmd_list_s* list = NULL;
651         list = (vc_cmd_list_s*)vc_cmd_list;
652
653         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), index (%d)", list, list->index);
654
655         if (0 == g_slist_length(list->list)) {
656                 SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list is empty");
657                 *vc_command = NULL;
658                 return VC_ERROR_EMPTY;
659         }
660
661         vc_cmd_s *temp_cmd = NULL;
662         temp_cmd = g_slist_nth_data(list->list, list->index);
663
664         *vc_command = (vc_cmd_h)temp_cmd;
665
666         SLOG(LOG_DEBUG, TAG_VCCMD, "[List] Get current command (%p)", *vc_command);
667
668         return VC_ERROR_NONE;
669 }
670
671
672 int vc_cmd_create(vc_cmd_h* vc_command)
673 {
674         if (0 != __vc_cmd_get_feature_enabled()) {
675                 return VC_ERROR_NOT_SUPPORTED;
676         }
677         if (0 != __vc_cmd_check_privilege()) {
678                 return VC_ERROR_PERMISSION_DENIED;
679         }
680
681         if (NULL == vc_command) {
682                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
683                 return VC_ERROR_INVALID_PARAMETER;
684         }
685
686         vc_cmd_s* command = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s));
687
688         if (NULL == command) {
689                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
690                 return VC_ERROR_OUT_OF_MEMORY;
691         }
692
693         command->pid = 0;
694         command->id = 0;
695         command->index = 0;
696         command->type = VC_COMMAND_TYPE_NONE;
697         command->format = VC_CMD_FORMAT_FIXED;
698         command->command = NULL;
699         command->parameter = NULL;
700         command->domain = 0;
701         command->priority = 0;
702         command->key = VC_KEY_NONE;
703         command->modifier = VC_MODIFIER_NONE;
704         command->invocation_name = NULL;
705         command->appid = NULL;
706         command->fixed = NULL;
707
708         *vc_command = (vc_cmd_h)command;
709
710         SLOG(LOG_DEBUG, TAG_VCCMD, "[Create command][%p]", *vc_command);
711
712         return VC_ERROR_NONE;
713 }
714
715 int vc_cmd_destroy(vc_cmd_h vc_command)
716 {
717         if (0 != __vc_cmd_get_feature_enabled()) {
718                 return VC_ERROR_NOT_SUPPORTED;
719         }
720         if (0 != __vc_cmd_check_privilege()) {
721                 return VC_ERROR_PERMISSION_DENIED;
722         }
723
724         if (NULL == vc_command) {
725                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
726                 return VC_ERROR_INVALID_PARAMETER;
727         }
728
729         vc_cmd_s* command = NULL;
730         command = (vc_cmd_s*)vc_command;
731
732         SLOG(LOG_DEBUG, TAG_VCCMD, "[Destroy command][%p]", command);
733
734         if (NULL != command) {
735                 if (NULL != command->command) {
736                         free(command->command);
737                         command->command = NULL;
738                 }
739                 if (NULL != command->parameter) {
740                         free(command->parameter);
741                         command->parameter = NULL;
742                 }
743                 if (NULL != command->invocation_name) {
744                         free(command->invocation_name);
745                         command->invocation_name = NULL;
746                 }
747                 if (NULL != command->appid) {
748                         free(command->appid);
749                         command->appid = NULL;
750                 }
751                 if (NULL != command->fixed) {
752                         free(command->fixed);
753                         command->fixed = NULL;
754                 }
755                 free(command);
756                 command = NULL;
757         }
758
759         return VC_ERROR_NONE;
760 }
761
762 int vc_cmd_set_id(vc_cmd_h vc_command, int id)
763 {
764         if (0 != __vc_cmd_get_feature_enabled()) {
765                 return VC_ERROR_NOT_SUPPORTED;
766         }
767         if (0 != __vc_cmd_check_privilege()) {
768                 return VC_ERROR_PERMISSION_DENIED;
769         }
770
771         if (NULL == vc_command) {
772                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
773                 return VC_ERROR_INVALID_PARAMETER;
774         }
775
776         vc_cmd_s* cmd = NULL;
777         cmd = (vc_cmd_s*)vc_command;
778
779         if (NULL != cmd) {
780                 cmd->id = id;
781                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
782         }
783
784         return 0;
785 }
786
787 int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
788 {
789         if (0 != __vc_cmd_get_feature_enabled()) {
790                 return VC_ERROR_NOT_SUPPORTED;
791         }
792         if (0 != __vc_cmd_check_privilege()) {
793                 return VC_ERROR_PERMISSION_DENIED;
794         }
795
796         if (NULL == vc_command || NULL == id) {
797                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
798                 return VC_ERROR_INVALID_PARAMETER;
799         }
800
801         vc_cmd_s* cmd = NULL;
802         cmd = (vc_cmd_s*)vc_command;
803
804         if (NULL != cmd) {
805                 *id = cmd->id;
806                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
807         }
808
809         return 0;
810 }
811
812 int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid)
813 {
814         if (0 != __vc_cmd_get_feature_enabled()) {
815                 return VC_ERROR_NOT_SUPPORTED;
816         }
817
818         if (NULL == vc_command) {
819                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
820                 return VC_ERROR_INVALID_PARAMETER;
821         }
822
823         if (NULL == appid) {
824                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, appid is NULL");
825                 return VC_ERROR_INVALID_PARAMETER;
826         }
827
828         vc_cmd_s* cmd = NULL;
829         cmd = (vc_cmd_s*)vc_command;
830
831         if (NULL != cmd->appid) {
832                 free(cmd->appid);
833                 cmd->appid = NULL;
834         }
835
836         cmd->appid = strdup(appid);
837
838         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set appid][%p] appid(%s)", vc_command, cmd->appid);
839         return 0;
840 }
841
842 int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid)
843 {
844         if (0 != __vc_cmd_get_feature_enabled()) {
845                 return VC_ERROR_NOT_SUPPORTED;
846         }
847
848         if (NULL == vc_command || NULL == appid) {
849                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
850                 return VC_ERROR_INVALID_PARAMETER;
851         }
852
853         vc_cmd_s* cmd = NULL;
854         cmd = (vc_cmd_s*)vc_command;
855
856         if (NULL != cmd->appid) {
857                 *appid = strdup(gettext(cmd->appid));
858         }
859
860         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get appid][%p] appid(%s)", vc_command, *appid);
861         return 0;
862 }
863
864 int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
865 {
866         if (0 != __vc_cmd_get_feature_enabled()) {
867                 return VC_ERROR_NOT_SUPPORTED;
868         }
869         if (0 != __vc_cmd_check_privilege()) {
870                 return VC_ERROR_PERMISSION_DENIED;
871         }
872
873         if (NULL == vc_command) {
874                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
875                 return VC_ERROR_INVALID_PARAMETER;
876         }
877
878         vc_cmd_s* cmd = NULL;
879         cmd = (vc_cmd_s*)vc_command;
880
881         if (NULL != cmd->command) {
882                 free(cmd->command);
883         }
884
885         cmd->command = NULL;
886
887         if (NULL != command) {
888                 cmd->command = strdup(command);
889         }
890
891         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set command][%p] Command(%s)", vc_command, cmd->command);
892
893         return 0;
894 }
895
896 int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
897 {
898         if (0 != __vc_cmd_get_feature_enabled()) {
899                 return VC_ERROR_NOT_SUPPORTED;
900         }
901         if (0 != __vc_cmd_check_privilege()) {
902                 return VC_ERROR_PERMISSION_DENIED;
903         }
904
905         if (NULL == vc_command || NULL == command) {
906                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
907                 return VC_ERROR_INVALID_PARAMETER;
908         }
909
910         vc_cmd_s* cmd = NULL;
911         cmd = (vc_cmd_s*)vc_command;
912
913         if (NULL != cmd->command) {
914                 *command = strdup(gettext(cmd->command));
915         }
916
917         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get command][%p] Command(%s)", vc_command, *command);
918
919         return 0;
920 }
921
922 int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
923 {
924         if (0 != __vc_cmd_get_feature_enabled()) {
925                 return VC_ERROR_NOT_SUPPORTED;
926         }
927         if (0 != __vc_cmd_check_privilege()) {
928                 return VC_ERROR_PERMISSION_DENIED;
929         }
930
931         if (NULL == vc_command) {
932                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
933                 return VC_ERROR_INVALID_PARAMETER;
934         }
935
936         vc_cmd_s* cmd = NULL;
937         cmd = (vc_cmd_s*)vc_command;
938
939         if (NULL != cmd->parameter) {
940                 free(cmd->parameter);
941         }
942
943         cmd->parameter = NULL;
944
945         if (NULL != command) {
946                 cmd->parameter = strdup(command);
947                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Set unfixed command][%p] unfixed command(%s)", vc_command, cmd->parameter);
948         }
949
950         return 0;
951 }
952
953 int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
954 {
955         if (0 != __vc_cmd_get_feature_enabled()) {
956                 return VC_ERROR_NOT_SUPPORTED;
957         }
958
959         if (NULL == vc_command || NULL == command) {
960                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
961                 return VC_ERROR_INVALID_PARAMETER;
962         }
963
964         vc_cmd_s* cmd = NULL;
965         cmd = (vc_cmd_s*)vc_command;
966
967         if (NULL != cmd->parameter) {
968                 *command = strdup(gettext(cmd->parameter));
969                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get unfixed command][%p] unfixed command(%s)", vc_command, *command);
970         }
971
972         return 0;
973 }
974
975 int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed)
976 {
977         if (0 != __vc_cmd_get_feature_enabled()) {
978                 return VC_ERROR_NOT_SUPPORTED;
979         }
980
981         if (NULL == vc_command) {
982                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
983                 return VC_ERROR_INVALID_PARAMETER;
984         }
985
986         if (NULL == fixed) {
987                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, fixed is NULL");
988                 return VC_ERROR_INVALID_PARAMETER;
989         }
990
991         vc_cmd_s* cmd = NULL;
992         cmd = (vc_cmd_s*)vc_command;
993
994         if (NULL != cmd->fixed) {
995                 free(cmd->fixed);
996                 cmd->fixed = NULL;
997         }
998
999         cmd->fixed = strdup(fixed);
1000
1001         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] fixed command(%s)", vc_command, cmd->fixed);
1002         return 0;
1003 }
1004
1005 int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed)
1006 {
1007         if (0 != __vc_cmd_get_feature_enabled()) {
1008                 return VC_ERROR_NOT_SUPPORTED;
1009         }
1010
1011         if (NULL == vc_command || NULL == fixed) {
1012                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1013                 return VC_ERROR_INVALID_PARAMETER;
1014         }
1015
1016         vc_cmd_s* cmd = NULL;
1017         cmd = (vc_cmd_s*)vc_command;
1018
1019         if (NULL != cmd->fixed) {
1020                 *fixed = strdup(gettext(cmd->fixed));
1021                 SLOG(LOG_DEBUG, TAG_VCCMD, "[Get fixed command][%p] fixed command(%s)", vc_command, *fixed);
1022         }
1023
1024         return 0;
1025 }
1026
1027 int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation_name)
1028 {
1029         if (0 != __vc_cmd_get_feature_enabled()) {
1030                 return VC_ERROR_NOT_SUPPORTED;
1031         }
1032
1033         if (NULL == vc_command) {
1034                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
1035                 return VC_ERROR_INVALID_PARAMETER;
1036         }
1037
1038         if (NULL == invocation_name) {
1039                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, invocation_name is NULL");
1040                 return VC_ERROR_INVALID_PARAMETER;
1041         }
1042
1043         vc_cmd_s* cmd = NULL;
1044         cmd = (vc_cmd_s*)vc_command;
1045
1046         if (NULL != cmd->invocation_name) {
1047                 free(cmd->invocation_name);
1048                 cmd->invocation_name = NULL;
1049         }
1050
1051         cmd->invocation_name = strdup(invocation_name);
1052
1053         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set invocation name][%p] invocation_name(%s)", vc_command, cmd->invocation_name);
1054         return 0;
1055 }
1056
1057 int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation_name)
1058 {
1059         if (0 != __vc_cmd_get_feature_enabled()) {
1060                 return VC_ERROR_NOT_SUPPORTED;
1061         }
1062
1063         if (NULL == vc_command || NULL == invocation_name) {
1064                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
1065                 return VC_ERROR_INVALID_PARAMETER;
1066         }
1067
1068         vc_cmd_s* cmd = NULL;
1069         cmd = (vc_cmd_s*)vc_command;
1070
1071         if (NULL != cmd->invocation_name) {
1072                 *invocation_name = strdup(gettext(cmd->invocation_name));
1073         }
1074
1075         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get invocation name][%p] invocation_name(%s)", vc_command, *invocation_name);
1076         return 0;
1077 }
1078
1079 int vc_cmd_set_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) {
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         cmd->type = type;
1097
1098         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
1099
1100         return 0;
1101 }
1102
1103 int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
1104 {
1105         if (0 != __vc_cmd_get_feature_enabled()) {
1106                 return VC_ERROR_NOT_SUPPORTED;
1107         }
1108         if (0 != __vc_cmd_check_privilege()) {
1109                 return VC_ERROR_PERMISSION_DENIED;
1110         }
1111
1112         if (NULL == vc_command || NULL == type) {
1113                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1114                 return VC_ERROR_INVALID_PARAMETER;
1115         }
1116
1117         vc_cmd_s* cmd = NULL;
1118         cmd = (vc_cmd_s*)vc_command;
1119
1120         *type = cmd->type;
1121
1122         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get type][%p] type(%d)", vc_command, *type);
1123
1124         return 0;
1125 }
1126
1127 int vc_cmd_set_format(vc_cmd_h vc_command, int format)
1128 {
1129         if (0 != __vc_cmd_get_feature_enabled()) {
1130                 return VC_ERROR_NOT_SUPPORTED;
1131         }
1132
1133         if (NULL == vc_command) {
1134                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1135                 return VC_ERROR_INVALID_PARAMETER;
1136         }
1137
1138         vc_cmd_s* cmd = NULL;
1139         cmd = (vc_cmd_s*)vc_command;
1140
1141         cmd->format = format;
1142
1143         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set format][%p] format(%d)", vc_command, format);
1144
1145         return 0;
1146 }
1147
1148 int vc_cmd_get_format(vc_cmd_h vc_command, int* format)
1149 {
1150         if (0 != __vc_cmd_get_feature_enabled()) {
1151                 return VC_ERROR_NOT_SUPPORTED;
1152         }
1153
1154         if (NULL == vc_command || NULL == format) {
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         *format = cmd->format;
1163
1164         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get format][%p] format(%d)", vc_command, *format);
1165
1166         return 0;
1167 }
1168
1169 int vc_cmd_set_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) {
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         cmd->pid = pid;
1187
1188         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set pid][%p] pid(%d)", vc_command, cmd->pid);
1189
1190         return 0;
1191 }
1192
1193 int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
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 || NULL == pid) {
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         *pid = cmd->pid;
1211
1212         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get pid][%p] pid(%d)", vc_command, *pid);
1213
1214         return 0;
1215 }
1216
1217 int vc_cmd_set_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) {
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         cmd->domain = domain;
1235
1236         SLOG(LOG_DEBUG, TAG_VCCMD, "[Set domain] domain : %d", domain);
1237
1238         return 0;
1239 }
1240
1241 int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
1242 {
1243         if (0 != __vc_cmd_get_feature_enabled()) {
1244                 return VC_ERROR_NOT_SUPPORTED;
1245         }
1246         if (0 != __vc_cmd_check_privilege()) {
1247                 return VC_ERROR_PERMISSION_DENIED;
1248         }
1249
1250         if (NULL == vc_command || NULL == domain) {
1251                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1252                 return VC_ERROR_INVALID_PARAMETER;
1253         }
1254
1255         vc_cmd_s* cmd = NULL;
1256         cmd = (vc_cmd_s*)vc_command;
1257
1258         *domain = cmd->domain;
1259
1260         SLOG(LOG_DEBUG, TAG_VCCMD, "[Get domain] domain : %d", *domain);
1261
1262         return 0;
1263 }
1264
1265 /**
1266 * @brief Sets key value of command.
1267 *
1268 * @param[in] vc_command Command handle
1269 * @param[in] key key value
1270 * @param[in] modifier modifier value
1271 *
1272 * @return 0 on success, otherwise a negative error value
1273 * @retval #VC_ERROR_NONE Successful
1274 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1275 *
1276 * @see vc_cmd_get_result_key()
1277 */
1278 int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
1279 {
1280         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Set result key");
1281
1282         if (NULL == vc_command) {
1283                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1284                 return VC_ERROR_INVALID_PARAMETER;
1285         }
1286
1287         vc_cmd_s* cmd = NULL;
1288         cmd = (vc_cmd_s*)vc_command;
1289
1290         SLOG(LOG_DEBUG, TAG_VCCMD, "key : %d, modifier : %d", key, modifier);
1291
1292         cmd->key = key;
1293         cmd->modifier = modifier;
1294
1295         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
1296         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1297
1298         return 0;
1299 }
1300
1301 /**
1302 * @brief Gets key value of command.
1303 *
1304 * @param[in] vc_command Command handle
1305 * @param[out] key key value
1306 * @param[out] modifier modifier value
1307 *
1308 * @return 0 on success, otherwise a negative error value
1309 * @retval #VC_ERROR_NONE Successful
1310 * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
1311 *
1312 * @see vc_cmd_add_result_key()
1313 */
1314 int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
1315 {
1316         SLOG(LOG_DEBUG, TAG_VCCMD, "===== Get result key");
1317
1318         if (NULL == vc_command || NULL == key || NULL == modifier) {
1319                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
1320                 return VC_ERROR_INVALID_PARAMETER;
1321         }
1322
1323         vc_cmd_s* cmd = NULL;
1324         cmd = (vc_cmd_s*)vc_command;
1325
1326         *key = cmd->key;
1327         *modifier = cmd->modifier;
1328
1329         SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
1330         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1331
1332         return 0;
1333 }
1334
1335 int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
1336 {
1337         if (NULL == vc_cmd_list) {
1338                 return -1;
1339         }
1340
1341         vc_cmd_list_s* list = NULL;
1342         list = (vc_cmd_list_s*)vc_cmd_list;
1343
1344         SLOG(LOG_DEBUG, TAG_VCCMD, "=== Command List ===");
1345         SLOG(LOG_DEBUG, TAG_VCCMD, "[List][%p]", list);
1346
1347         int count = g_slist_length(list->list);
1348
1349         int i;
1350         vc_cmd_s *cmd = NULL;
1351
1352         for (i = 0; i < count ; i++) {
1353                 cmd = g_slist_nth_data(list->list, i);
1354
1355                 if (NULL != cmd) {
1356                         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)",
1357                          i, cmd, cmd->pid, cmd->index, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
1358                 }
1359         }
1360
1361         SLOG(LOG_DEBUG, TAG_VCCMD, "==================");
1362         SLOG(LOG_DEBUG, TAG_VCCMD, " ");
1363
1364         return 0;
1365 }
1366
1367 int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json)
1368 {
1369         if (0 != __vc_cmd_get_feature_enabled()) {
1370                 return VC_ERROR_NOT_SUPPORTED;
1371         }
1372
1373         if (NULL == vc_cmd || NULL == json) {
1374                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] NULL parameter");
1375                 return VC_ERROR_INVALID_PARAMETER;
1376         }
1377
1378         vc_cmd_s* cmd = NULL;
1379         cmd = (vc_cmd_s*)vc_cmd;
1380
1381         if (VC_CMD_FORMAT_ACTION != cmd->format) {
1382                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not Action format");
1383                 return VC_ERROR_INVALID_PARAMETER;
1384         }
1385
1386         if (0 != vc_info_parser_get_nlu_result(json)) {
1387                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get nlu result");
1388                 return VC_ERROR_OPERATION_FAILED;
1389         }
1390
1391         return 0;
1392 }
1393
1394 static void __vc_cmd_regex_deinit(int num_regex)
1395 {
1396         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start Deinitialize regex ====");
1397         int i;
1398
1399         for (i = 0; num_regex > i; i++) {
1400                 regfree(&reg[i]);
1401         }
1402
1403         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
1404         SLOG(LOG_DEBUG, TAG_VCCMD, "");
1405 }
1406
1407 static int __vc_cmd_regex_init()
1408 {
1409         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Initialize regular expression ====");
1410
1411         int cflags = REG_EXTENDED | REG_ICASE;
1412         int ret;
1413         char errStr[128];
1414         char *lang = NULL;
1415         int lang_type = 1;
1416
1417         vc_config_mgr_get_default_language(&lang);
1418         if (NULL == lang) {
1419                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1420                 return VC_ERROR_OPERATION_FAILED;
1421         }
1422
1423         if (!strcmp("en_US", lang)) {
1424                 lang_type = 1;
1425         } else if (!strcmp("ko_KR", lang)) {
1426                 lang_type = 0;
1427         } else {
1428                 free(lang);
1429                 lang = NULL;
1430
1431                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not supported language type");
1432                 return VC_ERROR_INVALID_LANGUAGE;
1433         }
1434
1435         free(lang);
1436         lang = NULL;
1437
1438         SLOG(LOG_DEBUG, TAG_VCCMD, "==== lang type > %d ====", lang_type);
1439
1440         re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
1441
1442         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s" , TIME_ABS1_REGEX[lang_type]);
1443         ret = regcomp(&reg[0], TIME_ABS1_REGEX[lang_type], cflags);
1444         if (0 != ret) {
1445                 regerror(ret, &reg[0], errStr, sizeof(errStr));
1446
1447                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1448                 return VC_ERROR_OPERATION_FAILED;
1449         }
1450
1451         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS2_REGEX[lang_type]);
1452         ret = regcomp(&reg[1], TIME_ABS2_REGEX[lang_type], cflags);
1453         if (0 != ret) {
1454                 regerror(ret, &reg[1], errStr, sizeof(errStr));
1455                 __vc_cmd_regex_deinit(1);
1456
1457                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1458                 return VC_ERROR_OPERATION_FAILED;
1459         }
1460
1461         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS3_REGEX[lang_type]);
1462         ret = regcomp(&reg[2], TIME_ABS3_REGEX[lang_type], cflags);
1463         if (0 != ret) {
1464                 regerror(ret, &reg[2], errStr, sizeof(errStr));
1465                 __vc_cmd_regex_deinit(2);
1466
1467                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1468                 return VC_ERROR_OPERATION_FAILED;
1469         }
1470
1471         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL1_REGEX[lang_type]);
1472         ret = regcomp(&reg[3], TIME_REL1_REGEX[lang_type], cflags);
1473         if (0 != ret) {
1474                 regerror(ret, &reg[3], errStr, sizeof(errStr));
1475                 __vc_cmd_regex_deinit(3);
1476
1477                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1478                 return VC_ERROR_OPERATION_FAILED;
1479         }
1480
1481         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL2_REGEX[lang_type]);
1482         ret = regcomp(&reg[4], TIME_REL2_REGEX[lang_type], cflags);
1483         if (0 != ret) {
1484                 regerror(ret, &reg[4], errStr, sizeof(errStr));
1485                 __vc_cmd_regex_deinit(4);
1486
1487                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1488                 return VC_ERROR_OPERATION_FAILED;
1489         }
1490
1491         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL3_REGEX[lang_type]);
1492         ret = regcomp(&reg[5], TIME_REL3_REGEX[lang_type], cflags);
1493         if (0 != ret) {
1494                 regerror(ret, &reg[5], errStr, sizeof(errStr));
1495                 __vc_cmd_regex_deinit(5);
1496
1497                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1498                 return VC_ERROR_OPERATION_FAILED;
1499         }
1500
1501         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_PHR_REGEX[lang_type]);
1502         ret = regcomp(&reg[6], TIME_PHR_REGEX[lang_type], cflags);
1503         if (0 != ret) {
1504                 regerror(ret, &reg[6], errStr, sizeof(errStr));
1505                 __vc_cmd_regex_deinit(6);
1506
1507                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1508                 return VC_ERROR_OPERATION_FAILED;
1509         }
1510
1511         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS1_REGEX[lang_type]);
1512         ret = regcomp(&reg[7], DATE_ABS1_REGEX[lang_type], cflags);
1513         if (0 != ret) {
1514                 regerror(ret, &reg[7], errStr, sizeof(errStr));
1515                 __vc_cmd_regex_deinit(7);
1516
1517                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1518                 return VC_ERROR_OPERATION_FAILED;
1519         }
1520
1521         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS2_REGEX[lang_type]);
1522         ret = regcomp(&reg[8], DATE_ABS2_REGEX[lang_type], cflags);
1523         if (0 != ret) {
1524                 regerror(ret, &reg[8], errStr, sizeof(errStr));
1525                 __vc_cmd_regex_deinit(8);
1526
1527                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1528                 return VC_ERROR_OPERATION_FAILED;
1529         }
1530
1531         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS3_REGEX[lang_type]);
1532         ret = regcomp(&reg[9], DATE_ABS3_REGEX[lang_type], cflags);
1533         if (0 != ret) {
1534                 regerror(ret, &reg[9], errStr, sizeof(errStr));
1535                 __vc_cmd_regex_deinit(9);
1536
1537                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1538                 return VC_ERROR_OPERATION_FAILED;
1539         }
1540
1541         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR1_REGEX[lang_type]);
1542         ret = regcomp(&reg[10], DATE_PHR1_REGEX[lang_type], cflags);
1543         if (0 != ret) {
1544                 regerror(ret, &reg[10], errStr, sizeof(errStr));
1545                 __vc_cmd_regex_deinit(10);
1546
1547                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1548                 return VC_ERROR_OPERATION_FAILED;
1549         }
1550
1551         SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR2_REGEX[lang_type]);
1552         ret = regcomp(&reg[11], DATE_PHR2_REGEX[lang_type], cflags);
1553         if (0 != ret) {
1554                 regerror(ret, &reg[11], errStr, sizeof(errStr));
1555                 __vc_cmd_regex_deinit(11);
1556
1557                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
1558                 return VC_ERROR_OPERATION_FAILED;
1559         }
1560
1561         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
1562         SLOG(LOG_DEBUG, TAG_VCCMD, "");
1563
1564         return VC_ERROR_NONE;
1565 }
1566
1567 static void __vc_cmd_add_year(struct tm *td, int year)
1568 {
1569         td->tm_year += year;
1570 }
1571
1572 static void __vc_cmd_add_mon(struct tm *td, int mon)
1573 {
1574         int year = 0;
1575
1576         mon = td->tm_mon + mon;
1577         year = mon / 12;
1578
1579         if (0 < year) {
1580                 __vc_cmd_add_year(td, year);
1581         }
1582
1583         td->tm_mon = mon % 12;
1584 }
1585
1586 static void __vc_cmd_add_mday(struct tm *td, int mday)
1587 {
1588         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
1589         int year = td->tm_year + 1900;
1590
1591         int mon = 0;
1592
1593         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) max_day[1] = 29;
1594
1595         mday = td->tm_mday + mday;
1596
1597         for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) {
1598                 mday -= max_day[mon % 12];
1599
1600                 if (11 == mon % 12) {
1601                         year++;
1602
1603                         if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) {
1604                                 max_day[1] = 29;
1605                         } else {
1606                                 max_day[1] = 28;
1607                         }
1608                 }
1609         }
1610
1611         mon = mon - td->tm_mon;
1612
1613         if (0 < mon) {
1614                 __vc_cmd_add_mon(td, mon);
1615         }
1616
1617         td->tm_mday = mday;
1618 }
1619
1620 static void __vc_cmd_add_hour(struct tm *td, int hour)
1621 {
1622         int day = 0;
1623
1624         hour = td->tm_hour + hour;
1625         day = hour / 24;
1626
1627         if (0 < day) {
1628                 __vc_cmd_add_mday(td, day);
1629         }
1630
1631         td->tm_hour = hour % 24;
1632 }
1633
1634 static void __vc_cmd_add_min(struct tm *td, int min)
1635 {
1636         int hour = 0;
1637
1638         min = td->tm_min + min;
1639         hour = min / 60;
1640
1641         if (0 < hour) {
1642                 __vc_cmd_add_hour(td, hour);
1643         }
1644
1645         td->tm_min = min % 60;
1646 }
1647
1648 static void __copy_struct_tm(struct tm *des, struct tm *src)
1649 {
1650         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start to copy struct tm ====");
1651
1652         des->tm_sec     = src->tm_sec;
1653         des->tm_min     = src->tm_min;
1654         des->tm_hour    = src->tm_hour;
1655         des->tm_mday    = src->tm_mday;
1656         des->tm_mon     = src->tm_mon;
1657         des->tm_year    = src->tm_year;
1658         des->tm_wday    = src->tm_wday;
1659         des->tm_yday    = src->tm_yday;
1660         des->tm_isdst   = src->tm_isdst;
1661
1662         des->tm_gmtoff  = src->tm_gmtoff;
1663         des->tm_zone    = src->tm_zone;
1664 }
1665
1666 static void __update_data_sidx(int idx)
1667 {
1668         if (0 > g_data_sidx || idx < g_data_sidx) g_data_sidx = idx;
1669 }
1670
1671 static void __update_data_eidx(int idx)
1672 {
1673         if (0 > g_data_eidx || idx > g_data_eidx) g_data_eidx = idx;
1674 }
1675
1676 static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist)
1677 {
1678         regmatch_t pmatch[3];
1679         int ret;
1680         int len;
1681         int idx;
1682
1683         *exist = 0;
1684         ret = regexec(&reg[6], str, 3, pmatch, 0);
1685         if (0 == ret) {
1686                 idx = 1;
1687                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1688                 if (0 < len) {
1689                         if (12 < td->tm_hour) {
1690                                 __vc_cmd_add_mday(td, 1);
1691                         }
1692
1693                         td->tm_hour = 12;
1694                 } else {
1695                         idx = 2;
1696                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1697
1698                         __vc_cmd_add_mday(td, 1);
1699                 }
1700
1701                 td->tm_min = 0;
1702                 td->tm_sec = 0;
1703                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1704
1705                 __update_data_sidx(pmatch[0].rm_so);
1706                 __update_data_eidx(pmatch[0].rm_eo);
1707
1708                 *exist = 1;
1709                 return VC_ERROR_NONE;
1710         }
1711
1712         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1713         return VC_ERROR_NONE;
1714 }
1715
1716 static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist)
1717 {
1718         regmatch_t pmatch[2];
1719         int ret;
1720         int len;
1721         int sidx = -1;
1722         int eidx = -1;
1723         int hour = -1;
1724         int min = -1;
1725
1726         char *tempstr = NULL;
1727
1728         *exist = 0;
1729         ret = regexec(&reg[3], str, 1, pmatch, 0);
1730         if (0 == ret) {
1731                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so);
1732                 hour = min = -1;
1733
1734                 sidx = pmatch[0].rm_so;
1735                 eidx = pmatch[0].rm_eo;
1736
1737                 ret = regexec(&reg[4], str, 2, pmatch, 0);
1738                 if (0 == ret) {
1739                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1740
1741                         if (0 > len) {
1742                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1743                                 return VC_ERROR_OPERATION_FAILED;
1744                         }
1745                         tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1746
1747                         if (NULL == tempstr) {
1748                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1749                                 return VC_ERROR_OUT_OF_MEMORY;
1750                         }
1751
1752                         hour = atoi(tempstr);
1753
1754                         free(tempstr);
1755                         tempstr = NULL;
1756
1757                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1758
1759                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1760                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1761                 }
1762
1763                 ret = regexec(&reg[5], str, 2, pmatch, 0);
1764                 if (0 == ret) {
1765                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1766
1767                         if (0 > len) {
1768                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1769                                 return VC_ERROR_OPERATION_FAILED;
1770                         }
1771                         tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1772
1773                         if (NULL == tempstr) {
1774                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1775                                 return VC_ERROR_OUT_OF_MEMORY;
1776                         }
1777
1778                         min = atoi(tempstr);
1779
1780                         free(tempstr);
1781                         tempstr = NULL;
1782
1783                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1784
1785                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1786                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1787                 }
1788
1789                 if (hour < 0 && min < 0) {
1790                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1791                         return VC_ERROR_NONE;
1792                 }
1793
1794                 hour = 0 > hour ? 0 : hour;
1795                 min = 0 > min ? 0 : min;
1796
1797                 min = min + (hour * 60);
1798
1799                 __vc_cmd_add_min(td, min);
1800                 td->tm_sec = 0;
1801
1802                 __update_data_sidx(sidx);
1803                 __update_data_eidx(eidx);
1804
1805                 *exist = 1;
1806                 return VC_ERROR_NONE;
1807         }
1808
1809         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1810         return VC_ERROR_NONE;
1811 }
1812
1813 static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist)
1814 {
1815         regmatch_t pmatch[5];
1816         int ret;
1817         int len;
1818         int idx;
1819         int flag = -1;
1820         int hour = -1;
1821         int min = -1;
1822         int sidx = -1;
1823         int eidx = -1;
1824         char *tempstr = NULL;
1825
1826         *exist = 0;
1827         ret = regexec(&reg[0], str, 5, pmatch, 0);
1828         if (0 == ret) {
1829                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1830
1831                 flag = idx & 1;
1832
1833                 sidx = pmatch[0].rm_so;
1834                 eidx = pmatch[0].rm_eo;
1835         }
1836
1837         ret = regexec(&reg[1], str, 2, pmatch, 0);
1838         if (0 == ret) {
1839                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
1840
1841                 if (0 > len) {
1842                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1843                         return VC_ERROR_OPERATION_FAILED;
1844                 }
1845                 tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1846
1847                 if (NULL == tempstr) {
1848                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1849                         return VC_ERROR_OUT_OF_MEMORY;
1850                 }
1851
1852                 hour = atoi(tempstr);
1853
1854                 if (0 <= flag) {
1855                         hour = hour + 12 * flag;
1856
1857                         if (12 == hour) hour = 0;
1858                         else if (24 == hour) hour = 12;
1859                 }
1860
1861                 if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) {
1862                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1863                         return VC_ERROR_NONE;
1864                 }
1865
1866                 free(tempstr);
1867                 tempstr = NULL;
1868
1869                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1870
1871                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1872                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1873         } else if (0 < flag) {
1874                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1875                 return VC_ERROR_NONE;
1876         }
1877
1878         ret = regexec(&reg[2], str, 2, pmatch, 0);
1879         if (0 == ret) {
1880                 idx = 1;
1881                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1882                 if (0 < len) {
1883                         tempstr = strndup(str + pmatch[idx].rm_so, (size_t)len);
1884
1885                         if (NULL == tempstr) {
1886                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1887                                 return VC_ERROR_OUT_OF_MEMORY;
1888                         }
1889
1890                         min = atoi(tempstr);
1891
1892                         if (0 > min || 60 <= min) {
1893                                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1894                                 return VC_ERROR_NONE;
1895                         }
1896
1897                         td->tm_sec = 0;
1898
1899                         free(tempstr);
1900                         tempstr = NULL;
1901                 } else {
1902                         idx = 0;
1903                         min = 30;
1904                 }
1905
1906                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so);
1907                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1908                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1909         }
1910
1911         if (0 > hour && 0 > min) {
1912                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1913                 return VC_ERROR_NONE;
1914         }
1915
1916         if (0 <= min && 0 <= hour) {
1917                 if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1);
1918
1919                 td->tm_hour = hour;
1920                 td->tm_min = min;
1921         } else if (0 <= min) {
1922                 char *lang = NULL;
1923                 vc_config_mgr_get_default_language(&lang);
1924                 if (NULL == lang) {
1925                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1926                         return VC_ERROR_OPERATION_FAILED;
1927                 }
1928
1929                 if (!strcmp("en_US", lang)) {
1930                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
1931                         free(lang);
1932                         lang = NULL;
1933                         return VC_ERROR_NONE;
1934                 }
1935                 if (min <= td->tm_min) __vc_cmd_add_hour(td, 1);
1936
1937                 td->tm_min = min;
1938
1939                 free(lang);
1940                 lang = NULL;
1941         } else {
1942                 if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1);
1943
1944                 td->tm_hour = hour;
1945                 td->tm_min = 0;
1946         }
1947
1948         td->tm_sec = 0;
1949
1950         __update_data_sidx(sidx);
1951         __update_data_eidx(eidx);
1952
1953         *exist = 1;
1954         return VC_ERROR_NONE;
1955 }
1956
1957 static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist)
1958 {
1959         regmatch_t pmatch[10];
1960         int ret;
1961         int len;
1962         int idx;
1963
1964         *exist = 0;
1965         ret = regexec(&reg[10], str, 5, pmatch, 0);
1966         if (0 == ret) {
1967                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1968
1969                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1970
1971                 td->tm_year = td_now.tm_year;
1972                 td->tm_mon = td_now.tm_mon;
1973                 td->tm_mday = td_now.tm_mday;
1974
1975                 __vc_cmd_add_mday(td, idx - 1);
1976
1977                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1978
1979                 __update_data_sidx(pmatch[0].rm_so);
1980                 __update_data_eidx(pmatch[0].rm_eo);
1981
1982                 *exist = 1;
1983                 return VC_ERROR_NONE;
1984         }
1985
1986         ret = regexec(&reg[11], str, 10, pmatch, 0);
1987         if (0 == ret) {
1988                 for (idx = 1; 10 > idx; idx++) {
1989                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1990
1991                         if (0 < len) break;
1992                 }
1993
1994                 td->tm_year = td_now.tm_year;
1995                 td->tm_mon = td_now.tm_mon;
1996                 td->tm_mday = td_now.tm_mday;
1997
1998                 __vc_cmd_add_mday(td, idx + 1);
1999
2000                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2001
2002                 __update_data_sidx(pmatch[0].rm_so);
2003                 __update_data_eidx(pmatch[0].rm_eo);
2004
2005                 *exist = 1;
2006                 return VC_ERROR_NONE;
2007         }
2008
2009         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
2010         return VC_ERROR_NONE;
2011 }
2012
2013 static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist)
2014 {
2015         regmatch_t pmatch[13];
2016         int ret;
2017         int len;
2018         int idx;
2019         int sidx = -1;
2020         int eidx = -1;
2021         int y_flag = 0;
2022         int m_flag = 0;
2023         int year = 0;
2024         int mon = 0;
2025         int day = 0;
2026         char *tempstr = NULL;
2027
2028         *exist = 0;
2029         ret = regexec(&reg[9], str, 2, pmatch, 0);
2030         if (0 == ret) {
2031                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
2032
2033                 if (0 > len) {
2034                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2035                         return VC_ERROR_OPERATION_FAILED;
2036                 }
2037                 tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
2038
2039                 if (NULL == tempstr) {
2040                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2041                         return VC_ERROR_OUT_OF_MEMORY;
2042                 }
2043
2044                 day = atoi(tempstr);
2045
2046                 free(tempstr);
2047                 tempstr = NULL;
2048
2049                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2050
2051                 sidx = pmatch[0].rm_so;
2052                 eidx = pmatch[0].rm_eo;
2053         } else {
2054                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2055                 return VC_ERROR_NONE;
2056         }
2057
2058         ret = regexec(&reg[8], str, 13, pmatch, 0);
2059         if (0 == ret) {
2060                 for (idx = 1; 13 > idx; idx++) {
2061                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2062
2063                         if (0 < len) {
2064                                 mon = idx - 1;
2065                                 break;
2066                         }
2067                 }
2068
2069                 m_flag = 1;
2070
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                 char *lang = NULL;
2077                 vc_config_mgr_get_default_language(&lang);
2078                 if (NULL == lang) {
2079                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
2080                         return VC_ERROR_OPERATION_FAILED;
2081                 }
2082
2083                 if (!strcmp("en_US", lang)) {
2084                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2085                         free(lang);
2086                         lang = NULL;
2087                         return VC_ERROR_NONE;
2088                 }
2089
2090                 free(lang);
2091                 lang = NULL;
2092
2093                 mon = td->tm_mon;
2094         }
2095
2096         ret = regexec(&reg[7], str, 3, pmatch, 0);
2097         if (0 == ret) {
2098                 if (!m_flag) return -1;
2099
2100                 len = pmatch[2].rm_eo - pmatch[2].rm_so;
2101
2102                 if (0 > len) {
2103                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2104                         return VC_ERROR_OPERATION_FAILED;
2105                 }
2106                 tempstr = strndup(str + pmatch[2].rm_so, (size_t)len);
2107
2108                 if (NULL == tempstr) {
2109                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2110                         return VC_ERROR_OUT_OF_MEMORY;
2111                 }
2112
2113                 year = atoi(tempstr);
2114                 year = 1900 < year ? year - 1900 : year + 100;
2115
2116                 free(tempstr);
2117                 tempstr = NULL;
2118
2119                 y_flag = 1;
2120                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2121
2122                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2123                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2124         } else {
2125                 year = td->tm_year;
2126         }
2127
2128         if (0 > g_time_flag) {
2129                 td->tm_hour = 0;
2130                 td->tm_min = 0;
2131                 td->tm_sec = 0;
2132         } else if (2 == g_time_flag) {
2133                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2134                 return VC_ERROR_NONE;
2135         }
2136
2137         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
2138         if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29;
2139
2140         if (max_day[mon] < day || 1 > day) {
2141                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird");
2142                 return VC_ERROR_NONE;
2143         }
2144
2145         td->tm_year = year;
2146         td->tm_mon = mon;
2147         td->tm_mday = day;
2148
2149         if (!y_flag) {
2150                 if (!m_flag) {
2151                         if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1);
2152                 } else {
2153                         if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1);
2154                         else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1);
2155                 }
2156         }
2157
2158         __update_data_sidx(sidx);
2159         __update_data_eidx(eidx);
2160
2161         *exist = 1;
2162         return VC_ERROR_NONE;
2163 }
2164
2165 static int __vc_cmd_time_check(const char *str, struct tm *td)
2166 {
2167         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check time value in string \"%s\"", str);
2168
2169         vc_error_e ret;
2170         int exist = 0;
2171
2172         ret = __vc_cmd_tphrase_check(str, td, &exist);
2173         if (1 == exist) {
2174                 g_time_flag = 1;
2175
2176                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2177                 return ret;
2178         } else if (VC_ERROR_NONE != ret) {
2179                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2180                 return ret;
2181         }
2182
2183         ret = __vc_cmd_trelative_check(str, td, &exist);
2184         if (1 == exist) {
2185                 g_time_flag = 2;
2186
2187                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2188                 return ret;
2189         } else if (VC_ERROR_NONE != ret) {
2190                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2191                 return ret;
2192         }
2193
2194         ret = __vc_cmd_tabsolute_check(str, td, &exist);
2195         if (1 == exist) {
2196                 g_time_flag = 3;
2197
2198                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist");
2199                 return ret;
2200         } else if (VC_ERROR_NONE != ret) {
2201                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2202                 return ret;
2203         }
2204
2205         SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no time value");
2206         return VC_ERROR_NONE;
2207 }
2208
2209 static int __vc_cmd_date_check(const char *str, struct tm *td)
2210 {
2211         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check date value in string \"%s\"", str);
2212
2213         vc_error_e ret;
2214         int exist = 0;
2215
2216         ret = __vc_cmd_dphrase_check(str, td, &exist);
2217         if (1 == exist) {
2218                 g_date_flag = 1;
2219
2220                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist");
2221                 return ret;
2222         } else if (VC_ERROR_NONE != ret) {
2223                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2224                 return ret;
2225         }
2226
2227         ret = __vc_cmd_dabsolute_check(str, td, &exist);
2228         if (1 == exist) {
2229                 g_date_flag = 1;
2230
2231                 SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist");
2232                 return ret;
2233         } else if (VC_ERROR_NONE != ret) {
2234                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret);
2235                 return ret;
2236         }
2237
2238         SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no date value");
2239         return VC_ERROR_NONE;
2240 }
2241
2242 int vc_cmd_get_datetime(const char *text, time_t *result, char **remain)
2243 {
2244         SLOG(LOG_DEBUG, TAG_VCCMD, "==== Get timestamp data");
2245
2246         struct tm td;
2247         const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
2248         vc_error_e ret;
2249
2250         if (NULL == text || NULL == result || NULL == remain) {
2251                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter");
2252                 return VC_ERROR_INVALID_PARAMETER;
2253         }
2254
2255         *result = -1;
2256         ret = __vc_cmd_regex_init();
2257         if (VC_ERROR_NONE != ret) {
2258                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed");
2259                 return ret;
2260         }
2261
2262         g_data_sidx = g_data_eidx = -1;
2263
2264         t_now = time(NULL);
2265         localtime_r(&t_now, &td_now);
2266         SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now);
2267
2268         __copy_struct_tm(&td, &td_now);
2269         SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2270                 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);
2271
2272         g_time_flag = g_date_flag = -1;
2273
2274         ret = __vc_cmd_time_check(text, &td);
2275         if (VC_ERROR_NONE != ret) {
2276                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret);
2277                 return ret;
2278         }
2279
2280         ret = __vc_cmd_date_check(text, &td);
2281         if (VC_ERROR_NONE != ret) {
2282                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret);
2283                 return ret;
2284         }
2285
2286         __vc_cmd_regex_deinit(12);
2287
2288         if (g_time_flag > 0 || g_date_flag > 0) {
2289                 *result = mktime(&td);
2290
2291                 SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %d", *result);
2292                 SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2293                         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);
2294
2295                 *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx));
2296
2297                 if (NULL == *remain) {
2298                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error");
2299                         return VC_ERROR_OUT_OF_MEMORY;
2300                 }
2301
2302                 strncpy(*remain, text, g_data_sidx);
2303                 strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx);
2304         } else {
2305                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text");
2306         }
2307
2308         SLOG(LOG_DEBUG, TAG_VCCMD, "====");
2309         SLOG(LOG_DEBUG, TAG_VCCMD, "");
2310
2311         return VC_ERROR_NONE;
2312 }