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