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