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