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