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