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