e6b5767e71e6a849fa4328049d4e1e0ba9cb1764
[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         *exist = 0;
1767         ret = regexec(&reg[3], str, 1, pmatch, 0);
1768         if (0 == ret) {
1769                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so);
1770                 hour = min = -1;
1771
1772                 sidx = pmatch[0].rm_so;
1773                 eidx = pmatch[0].rm_eo;
1774
1775                 ret = regexec(&reg[4], str, 2, pmatch, 0);
1776                 if (0 == ret) {
1777                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1778
1779                         if (0 > len) {
1780                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1781                                 return VC_ERROR_OPERATION_FAILED;
1782                         }
1783                         char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1784
1785                         if (NULL == tempstr) {
1786                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1787                                 return VC_ERROR_OUT_OF_MEMORY;
1788                         }
1789
1790                         hour = atoi(tempstr);
1791
1792                         free(tempstr);
1793                         tempstr = NULL;
1794
1795                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1796
1797                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1798                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1799                 }
1800
1801                 ret = regexec(&reg[5], str, 2, pmatch, 0);
1802                 if (0 == ret) {
1803                         len = pmatch[1].rm_eo - pmatch[1].rm_so;
1804
1805                         if (0 > len) {
1806                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1807                                 return VC_ERROR_OPERATION_FAILED;
1808                         }
1809                         char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1810
1811                         if (NULL == tempstr) {
1812                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1813                                 return VC_ERROR_OUT_OF_MEMORY;
1814                         }
1815
1816                         min = atoi(tempstr);
1817
1818                         free(tempstr);
1819                         tempstr = NULL;
1820
1821                         SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1822
1823                         if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1824                         if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1825                 }
1826
1827                 if (hour < 0 && min < 0) {
1828                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1829                         return VC_ERROR_NONE;
1830                 }
1831
1832                 hour = 0 > hour ? 0 : hour;
1833                 min = 0 > min ? 0 : min;
1834
1835                 min = min + (hour * 60);
1836
1837                 __vc_cmd_add_min(td, min);
1838                 td->tm_sec = 0;
1839
1840                 __update_data_sidx(sidx);
1841                 __update_data_eidx(eidx);
1842
1843                 *exist = 1;
1844                 return VC_ERROR_NONE;
1845         }
1846
1847         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1848         return VC_ERROR_NONE;
1849 }
1850
1851 static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist)
1852 {
1853         regmatch_t pmatch[5];
1854         int ret;
1855         int len;
1856         int idx;
1857         int flag = -1;
1858         int hour = -1;
1859         int min = -1;
1860         int sidx = -1;
1861         int eidx = -1;
1862
1863         *exist = 0;
1864         ret = regexec(&reg[0], str, 5, pmatch, 0);
1865         if (0 == ret) {
1866                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
1867
1868                 flag = idx & 1;
1869
1870                 sidx = pmatch[0].rm_so;
1871                 eidx = pmatch[0].rm_eo;
1872         }
1873
1874         ret = regexec(&reg[1], str, 2, pmatch, 0);
1875         if (0 == ret) {
1876                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
1877
1878                 if (0 > len) {
1879                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
1880                         return VC_ERROR_OPERATION_FAILED;
1881                 }
1882                 char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
1883
1884                 if (NULL == tempstr) {
1885                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1886                         return VC_ERROR_OUT_OF_MEMORY;
1887                 }
1888
1889                 hour = atoi(tempstr);
1890
1891                 if (0 <= flag) {
1892                         hour = hour + 12 * flag;
1893
1894                         if (12 == hour) hour = 0;
1895                         else if (24 == hour) hour = 12;
1896                 }
1897
1898                 if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) {
1899                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1900                         free(tempstr);
1901                         tempstr = NULL;
1902                         return VC_ERROR_NONE;
1903                 }
1904
1905                 free(tempstr);
1906                 tempstr = NULL;
1907
1908                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
1909
1910                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1911                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1912         } else if (0 < flag) {
1913                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1914                 return VC_ERROR_NONE;
1915         }
1916
1917         ret = regexec(&reg[2], str, 2, pmatch, 0);
1918         if (0 == ret) {
1919                 idx = 1;
1920                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
1921                 if (0 < len) {
1922                         char *tempstr = strndup(str + pmatch[idx].rm_so, (size_t)len);
1923
1924                         if (NULL == tempstr) {
1925                                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
1926                                 return VC_ERROR_OUT_OF_MEMORY;
1927                         }
1928
1929                         min = atoi(tempstr);
1930
1931                         if (0 > min || 60 <= min) {
1932                                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1933                                 free(tempstr);
1934                                 tempstr = NULL;
1935                                 return VC_ERROR_NONE;
1936                         }
1937
1938                         td->tm_sec = 0;
1939
1940                         free(tempstr);
1941                         tempstr = NULL;
1942                 } else {
1943                         idx = 0;
1944                         min = 30;
1945                 }
1946
1947                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so);
1948                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
1949                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
1950         }
1951
1952         if (0 > hour && 0 > min) {
1953                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
1954                 return VC_ERROR_NONE;
1955         }
1956
1957         if (0 <= min && 0 <= hour) {
1958                 if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1);
1959
1960                 td->tm_hour = hour;
1961                 td->tm_min = min;
1962         } else if (0 <= min) {
1963                 char *lang = NULL;
1964                 vc_config_mgr_get_default_language(&lang);
1965                 if (NULL == lang) {
1966                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
1967                         return VC_ERROR_OPERATION_FAILED;
1968                 }
1969
1970                 if (!strcmp("en_US", lang)) {
1971                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
1972                         free(lang);
1973                         lang = NULL;
1974                         return VC_ERROR_NONE;
1975                 }
1976                 if (min <= td->tm_min) __vc_cmd_add_hour(td, 1);
1977
1978                 td->tm_min = min;
1979
1980                 free(lang);
1981                 lang = NULL;
1982         } else {
1983                 if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1);
1984
1985                 td->tm_hour = hour;
1986                 td->tm_min = 0;
1987         }
1988
1989         td->tm_sec = 0;
1990
1991         __update_data_sidx(sidx);
1992         __update_data_eidx(eidx);
1993
1994         *exist = 1;
1995         return VC_ERROR_NONE;
1996 }
1997
1998 static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist)
1999 {
2000         regmatch_t pmatch[10];
2001         int ret;
2002         int len;
2003         int idx;
2004
2005         *exist = 0;
2006         ret = regexec(&reg[10], str, 5, pmatch, 0);
2007         if (0 == ret) {
2008                 for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
2009
2010                 len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2011
2012                 td->tm_year = td_now.tm_year;
2013                 td->tm_mon = td_now.tm_mon;
2014                 td->tm_mday = td_now.tm_mday;
2015
2016                 __vc_cmd_add_mday(td, idx - 1);
2017
2018                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2019
2020                 __update_data_sidx(pmatch[0].rm_so);
2021                 __update_data_eidx(pmatch[0].rm_eo);
2022
2023                 *exist = 1;
2024                 return VC_ERROR_NONE;
2025         }
2026
2027         ret = regexec(&reg[11], str, 10, pmatch, 0);
2028         if (0 == ret) {
2029                 for (idx = 1; 10 > idx; idx++) {
2030                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2031
2032                         if (0 < len) break;
2033                 }
2034
2035                 td->tm_year = td_now.tm_year;
2036                 td->tm_mon = td_now.tm_mon;
2037                 td->tm_mday = td_now.tm_mday;
2038
2039                 __vc_cmd_add_mday(td, idx + 1);
2040
2041                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2042
2043                 __update_data_sidx(pmatch[0].rm_so);
2044                 __update_data_eidx(pmatch[0].rm_eo);
2045
2046                 *exist = 1;
2047                 return VC_ERROR_NONE;
2048         }
2049
2050         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
2051         return VC_ERROR_NONE;
2052 }
2053
2054 static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist)
2055 {
2056         regmatch_t pmatch[13];
2057         int ret;
2058         int len;
2059         int idx;
2060         int sidx = -1;
2061         int eidx = -1;
2062         int y_flag = 0;
2063         int m_flag = 0;
2064         int year = 0;
2065         int mon = 0;
2066         int day = 0;
2067         char *tempstr = NULL;
2068
2069         *exist = 0;
2070         ret = regexec(&reg[9], str, 2, pmatch, 0);
2071         if (0 == ret) {
2072                 len = pmatch[1].rm_eo - pmatch[1].rm_so;
2073
2074                 if (0 > len) {
2075                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2076                         return VC_ERROR_OPERATION_FAILED;
2077                 }
2078                 tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
2079
2080                 if (NULL == tempstr) {
2081                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2082                         return VC_ERROR_OUT_OF_MEMORY;
2083                 }
2084
2085                 day = atoi(tempstr);
2086
2087                 free(tempstr);
2088                 tempstr = NULL;
2089
2090                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2091
2092                 sidx = pmatch[0].rm_so;
2093                 eidx = pmatch[0].rm_eo;
2094         } else {
2095                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2096                 return VC_ERROR_NONE;
2097         }
2098
2099         ret = regexec(&reg[8], str, 13, pmatch, 0);
2100         if (0 == ret) {
2101                 for (idx = 1; 13 > idx; idx++) {
2102                         len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
2103
2104                         if (0 < len) {
2105                                 mon = idx - 1;
2106                                 break;
2107                         }
2108                 }
2109
2110                 m_flag = 1;
2111
2112                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2113
2114                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2115                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2116         } else {
2117                 char *lang = NULL;
2118                 vc_config_mgr_get_default_language(&lang);
2119                 if (NULL == lang) {
2120                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
2121                         return VC_ERROR_OPERATION_FAILED;
2122                 }
2123
2124                 if (!strcmp("en_US", lang)) {
2125                         SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2126                         free(lang);
2127                         lang = NULL;
2128                         return VC_ERROR_NONE;
2129                 }
2130
2131                 free(lang);
2132                 lang = NULL;
2133
2134                 mon = td->tm_mon;
2135         }
2136
2137         ret = regexec(&reg[7], str, 3, pmatch, 0);
2138         if (0 == ret) {
2139                 if (!m_flag) return -1;
2140
2141                 len = pmatch[2].rm_eo - pmatch[2].rm_so;
2142
2143                 if (0 > len) {
2144                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
2145                         return VC_ERROR_OPERATION_FAILED;
2146                 }
2147                 tempstr = strndup(str + pmatch[2].rm_so, (size_t)len);
2148
2149                 if (NULL == tempstr) {
2150                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
2151                         return VC_ERROR_OUT_OF_MEMORY;
2152                 }
2153
2154                 year = atoi(tempstr);
2155                 year = 1900 < year ? year - 1900 : year + 100;
2156
2157                 free(tempstr);
2158                 tempstr = NULL;
2159
2160                 y_flag = 1;
2161                 SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
2162
2163                 if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
2164                 if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
2165         } else {
2166                 year = td->tm_year;
2167         }
2168
2169         if (0 > g_time_flag) {
2170                 td->tm_hour = 0;
2171                 td->tm_min = 0;
2172                 td->tm_sec = 0;
2173         } else if (2 == g_time_flag) {
2174                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2175                 return VC_ERROR_NONE;
2176         }
2177
2178         int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
2179         if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29;
2180
2181         if (max_day[mon] < day || 1 > day) {
2182                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
2183                 return VC_ERROR_NONE;
2184         }
2185
2186         td->tm_year = year;
2187         td->tm_mon = mon;
2188         td->tm_mday = day;
2189
2190         if (!y_flag) {
2191                 if (!m_flag) {
2192                         if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1);
2193                 } else {
2194                         if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1);
2195                         else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1);
2196                 }
2197         }
2198
2199         __update_data_sidx(sidx);
2200         __update_data_eidx(eidx);
2201
2202         *exist = 1;
2203         return VC_ERROR_NONE;
2204 }
2205
2206 static int __vc_cmd_time_check(const char *str, struct tm *td)
2207 {
2208         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check time value in string \"%s\"", str);
2209
2210         vc_error_e ret;
2211         int exist = 0;
2212
2213         ret = __vc_cmd_tphrase_check(str, td, &exist);
2214         if (1 == exist) {
2215                 g_time_flag = 1;
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         ret = __vc_cmd_trelative_check(str, td, &exist);
2225         if (1 == exist) {
2226                 g_time_flag = 2;
2227
2228                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
2229                 return ret;
2230         } else if (VC_ERROR_NONE != ret) {
2231                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2232                 return ret;
2233         }
2234
2235         ret = __vc_cmd_tabsolute_check(str, td, &exist);
2236         if (1 == exist) {
2237                 g_time_flag = 3;
2238
2239                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
2240                 return ret;
2241         } else if (VC_ERROR_NONE != ret) {
2242                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2243                 return ret;
2244         }
2245
2246         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no time value");
2247         return VC_ERROR_NONE;
2248 }
2249
2250 static int __vc_cmd_date_check(const char *str, struct tm *td)
2251 {
2252         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check date value in string \"%s\"", str);
2253
2254         vc_error_e ret;
2255         int exist = 0;
2256
2257         ret = __vc_cmd_dphrase_check(str, td, &exist);
2258         if (1 == exist) {
2259                 g_date_flag = 1;
2260
2261                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
2262                 return ret;
2263         } else if (VC_ERROR_NONE != ret) {
2264                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2265                 return ret;
2266         }
2267
2268         ret = __vc_cmd_dabsolute_check(str, td, &exist);
2269         if (1 == exist) {
2270                 g_date_flag = 1;
2271
2272                 SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
2273                 return ret;
2274         } else if (VC_ERROR_NONE != ret) {
2275                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
2276                 return ret;
2277         }
2278
2279         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no date value");
2280         return VC_ERROR_NONE;
2281 }
2282
2283 int vc_cmd_get_datetime(const char *text, time_t *result, char **remain)
2284 {
2285         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Get timestamp data");
2286
2287         struct tm td;
2288         const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
2289         vc_error_e ret;
2290
2291         if (NULL == text || NULL == result || NULL == remain) {
2292                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter");
2293                 return VC_ERROR_INVALID_PARAMETER;
2294         }
2295
2296         *result = -1;
2297         ret = __vc_cmd_regex_init();
2298         if (VC_ERROR_NONE != ret) {
2299                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed");
2300                 return ret;
2301         }
2302
2303         g_data_sidx = g_data_eidx = -1;
2304
2305         t_now = time(NULL);
2306         localtime_r(&t_now, &td_now);
2307         SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now);
2308
2309         __copy_struct_tm(&td, &td_now);
2310         SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2311                 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);
2312
2313         g_time_flag = g_date_flag = -1;
2314
2315         ret = __vc_cmd_time_check(text, &td);
2316         if (VC_ERROR_NONE != ret) {
2317                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
2318                 return ret;
2319         }
2320
2321         ret = __vc_cmd_date_check(text, &td);
2322         if (VC_ERROR_NONE != ret) {
2323                 SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
2324                 return ret;
2325         }
2326
2327         __vc_cmd_regex_deinit(12);
2328
2329         if (g_time_flag > 0 || g_date_flag > 0) {
2330                 *result = mktime(&td);
2331
2332                 SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %ld", *result);
2333                 SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
2334                         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);
2335
2336                 *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx));
2337
2338                 if (NULL == *remain) {
2339                         SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error");
2340                         return VC_ERROR_OUT_OF_MEMORY;
2341                 }
2342
2343                 strncpy(*remain, text, g_data_sidx);
2344                 strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx);
2345         } else {
2346                 SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text");
2347         }
2348
2349         SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
2350
2351         return VC_ERROR_NONE;
2352 }
2353 //LCOV_EXCL_STOP