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