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