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