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