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