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