Rearrange the scope of each temporary variables
[platform/core/uifw/voice-control.git] / common / vc_command.c
index c06d828..e6b5767 100644 (file)
 * limitations under the License.
 */
 
+#define _GNU_SOURCE
 
+#include <cynara-client.h>
+#include <cynara-error.h>
+#include <cynara-session.h>
 #include <libintl.h>
 #include <stdlib.h>
+#include <system_info.h>
 
 #include "vc_command.h"
+#include "vc_info_parser.h"
 #include "vc_main.h"
+#include "vc_regex_rule.h"
+#include "vc_config_mgr.h"
 #include "voice_control_command.h"
 #include "voice_control_command_expand.h"
 #include "voice_control_common.h"
 #include "voice_control_key_defines.h"
 
+static pthread_mutex_t g_cmd_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t g_cmd_list_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define CMD_MUTEX_LOCK()       pthread_mutex_lock(&g_cmd_mutex)
+#define CMD_MUTEX_UNLOCK()     pthread_mutex_unlock(&g_cmd_mutex)
+#define CMD_LIST_MUTEX_LOCK()  pthread_mutex_lock(&g_cmd_list_mutex)
+#define CMD_LIST_MUTEX_UNLOCK()        pthread_mutex_unlock(&g_cmd_list_mutex)
+
+static int g_feature_enabled = -1;
+static bool g_privilege_allowed = false;
+
+static pthread_mutex_t g_cynara_mutex = PTHREAD_MUTEX_INITIALIZER;
+static cynara *p_cynara = NULL;
+static GList *g_cmd_list = NULL;
+static GList *g_cmdlist_list = NULL;
+
+
+// For getting timestamp using regular expression
+static regex_t reg[MAX_NUM_REGEX];
+static time_t t_now;           //time_t is based on UTC
+static struct tm td_now;       //if use localtime function, the value follows the local time zone, otherwise it follows the UTC.
+
+static int g_time_flag;
+static int g_date_flag;
+
+static int g_data_sidx;
+static int g_data_eidx;
+
+static int __vc_cmd_get_feature_enabled()
+{
+       if (0 == g_feature_enabled) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Voice control feature NOT supported");
+               return VC_ERROR_NOT_SUPPORTED;
+       } else if (-1 == g_feature_enabled) {
+               bool vc_supported = false;
+               bool mic_supported = false;
+               if (0 == system_info_get_platform_bool(VC_FEATURE_PATH, &vc_supported)) {
+                       if (0 == system_info_get_platform_bool(VC_MIC_FEATURE_PATH, &mic_supported)) {
+                               if (false == vc_supported || false == mic_supported) {
+                                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Voice control feature NOT supported");
+                                       g_feature_enabled = 0;
+                                       return VC_ERROR_NOT_SUPPORTED;
+                               }
+
+                               g_feature_enabled = 1;
+                       } else {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get feature value");
+                               return VC_ERROR_NOT_SUPPORTED;
+                       }
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get feature value");
+                       return VC_ERROR_NOT_SUPPORTED;
+               }
+       }
+
+       return VC_ERROR_NONE;
+}
+
+static int __check_privilege_initialize()
+{
+       int ret = cynara_initialize(&p_cynara, NULL);
+       if (CYNARA_API_SUCCESS != ret)
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to initialize");
+
+       return ret == CYNARA_API_SUCCESS;
+}
+
+static int __check_privilege(const char* uid, const char * privilege)
+{
+       FILE *fp = NULL;
+       char label_path[1024] = "/proc/self/attr/current";
+       char smack_label[1024] = {'\0',};
+
+       if (!p_cynara) {
+               return false;
+       }
+
+       fp = fopen(label_path, "r");
+       if (fp != NULL) {
+               if (0 >= fread(smack_label, 1, sizeof(smack_label), fp))
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread");
+
+               fclose(fp);
+       }
+
+       pid_t pid = getpid();
+       char *session = cynara_session_from_pid(pid);
+       int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
+       if (session)
+               free(session);
+
+       if (ret != CYNARA_API_ACCESS_ALLOWED)
+               return false;
+       return true;
+}
+
+static void __check_privilege_deinitialize()
+{
+       if (p_cynara)
+       {
+               int ret = cynara_finish(p_cynara);
+               if (ret != CYNARA_API_SUCCESS)
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] cynara finish %d", ret);
+       }
+       p_cynara = NULL;
+}
+
+static int __vc_cmd_check_privilege()
+{
+       if (true == g_privilege_allowed)
+               return VC_ERROR_NONE;
+
+       pthread_mutex_lock(&g_cynara_mutex);
+
+       if (false == g_privilege_allowed) {
+               bool ret = true;
+               ret = __check_privilege_initialize();
+               if (false == ret) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] privilege initialize is failed");
+                       g_privilege_allowed = false;
+                       pthread_mutex_unlock(&g_cynara_mutex);
+                       return VC_ERROR_PERMISSION_DENIED;
+               }
+
+               char uid[32];
+               snprintf(uid, 32, "%d", getuid());
+               ret = true;
+               ret = __check_privilege(uid, VC_PRIVILEGE_RECORDER);
+               if (false == ret) {
+                       //LCOV_EXCL_START
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Permission is denied(%s)(%s)", VC_PRIVILEGE_RECORDER, uid);
+                       __check_privilege_deinitialize();
+                       g_privilege_allowed = false;
+                       pthread_mutex_unlock(&g_cynara_mutex);
+                       return VC_ERROR_PERMISSION_DENIED;
+                       //LCOV_EXCL_STOP
+               }
+
+               __check_privilege_deinitialize();
+       }
+
+       g_privilege_allowed = true;
+       pthread_mutex_unlock(&g_cynara_mutex);
+       return VC_ERROR_NONE;
+}
 
 int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       CMD_LIST_MUTEX_LOCK();
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               CMD_LIST_MUTEX_UNLOCK();
                return VC_ERROR_INVALID_PARAMETER;
        }
 
@@ -37,6 +200,7 @@ int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list)
 
        if (NULL == list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
+               CMD_LIST_MUTEX_UNLOCK();
                return VC_ERROR_OUT_OF_MEMORY;
        }
 
@@ -45,35 +209,66 @@ int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list)
 
        *vc_cmd_list = (vc_cmd_list_h)list;
 
+       g_cmdlist_list = g_list_append(g_cmdlist_list, list);
+
        SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p)", *vc_cmd_list);
 
+       CMD_LIST_MUTEX_UNLOCK();
        return VC_ERROR_NONE;
 }
 
 int vc_cmd_list_destroy(vc_cmd_list_h vc_cmd_list, bool release_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       CMD_LIST_MUTEX_LOCK();
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               CMD_LIST_MUTEX_UNLOCK();
                return VC_ERROR_INVALID_PARAMETER;
        }
 
-       vc_cmd_list_remove_all(vc_cmd_list, release_command);
 
        vc_cmd_list_s* list = NULL;
        list = (vc_cmd_list_s*)vc_cmd_list;
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p)", list);
 
-       if (NULL != list) {
-               free(list);
-               list = NULL;
+       GList *iter = NULL;
+       iter = g_list_find(g_cmdlist_list, list);
+       if (NULL == iter) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "Fail to destroy client : handle is not valid");
+               CMD_LIST_MUTEX_UNLOCK();
+               return VC_ERROR_INVALID_PARAMETER;
        }
 
+       g_cmdlist_list = g_list_delete_link(g_cmdlist_list, iter);
+
+       vc_cmd_list_remove_all((vc_cmd_list_h)list, release_command);
+       free(list);
+       list = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Client destroy");
+
+       CMD_LIST_MUTEX_UNLOCK();
        return VC_ERROR_NONE;
 }
 
 int vc_cmd_list_get_count(vc_cmd_list_h vc_cmd_list, int* count)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list || NULL == count) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Get command count : Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -91,6 +286,13 @@ int vc_cmd_list_get_count(vc_cmd_list_h vc_cmd_list, int* count)
 
 int vc_cmd_list_add(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list || NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -115,6 +317,13 @@ int vc_cmd_list_add(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
 
 int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list || NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -128,122 +337,202 @@ int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), command(%p)", list, cmd);
 
-       vc_cmd_s* temp_cmd = NULL;
        GSList *iter = NULL;
-
-       iter = g_slist_nth(list->list, 0);
-
-       while (NULL != iter) {
-               temp_cmd = iter->data;
-
-               if (NULL != temp_cmd && cmd == temp_cmd) {
-                       list->list = g_slist_remove(list->list, temp_cmd);
-                       /*
-                       if (true == release_command) {
-                               SLOG(LOG_DEBUG, TAG_VCCMD, "Release command data");
-                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
-                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
-                               free(temp_cmd);
-                               temp_cmd = NULL;
-                       }
-                       */
-               }
-
-               iter = g_slist_next(iter);
+       iter = g_slist_find(list->list, cmd);
+       if (NULL == iter) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "Fail to destroy command : handle is not valid");
+               return VC_ERROR_INVALID_PARAMETER;
        }
 
-       int count = g_slist_length(list->list);
+       list->list = g_slist_remove_link(list->list, iter);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "destroy command");
 
-       if (0 == count) {
+       int len = g_slist_length(list->list);
+       if (0 == len)
                list->index = -1;
-       } else if (list->index == count) {
-               list->index = count - 1;
-       }
+       else if (list->index == len)
+               list->index = len - 1;
 
        return VC_ERROR_NONE;
 }
 
+static void __vc_cmd_list_remove_all_foreach(gpointer data)
+{
+       vc_cmd_s *temp = (vc_cmd_s *)data;
+       if (temp) {
+               SECURE_SLOG(LOG_DEBUG, TAG_VCCMD, "Free command(%p)", temp);
+               vc_cmd_destroy((vc_cmd_h)temp);
+       }
+}
+
 int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool release_command)
 {
-       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Destroy all command");
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Destroy all command");
 
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
-       vc_cmd_list_s* list = NULL;
-       list = (vc_cmd_list_s*)vc_cmd_list;
+       vc_cmd_list_s* cmd_list = (vc_cmd_list_s*)vc_cmd_list;
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), release command (%s)"
-                , list, release_command ? "true" : "false");
+                , cmd_list, release_command ? "true" : "false");
 
-       int count = g_slist_length(list->list);
+       if (NULL == cmd_list->list) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ List is already empty.");
+               return VC_ERROR_NONE;
+       }
 
-       int i ;
-       vc_cmd_s *temp_cmd;
+       if (true == release_command) {
+               g_slist_free_full(cmd_list->list, __vc_cmd_list_remove_all_foreach);
+       } else {
+               g_slist_free(cmd_list->list);
+       }
 
-       for (i = 0; i < count ; i++) {
-               temp_cmd = g_slist_nth_data(list->list, 0);
+       cmd_list->list = NULL;
+       cmd_list->index = -1;
 
-               if (NULL != temp_cmd) {
-                       list->list = g_slist_remove(list->list, temp_cmd);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
 
-                       if (true == release_command) {
-                               SLOG(LOG_DEBUG, TAG_VCCMD, "Free command(%p)", temp_cmd);
-                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
-                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
-                               free(temp_cmd);
-                               temp_cmd = NULL;
-                       }
-               }
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
        }
 
-       list->index = -1;
+       if (NULL == vc_cmd_list || NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_list_s* list = NULL;
+       list = (vc_cmd_list_s*)vc_cmd_list;
+
+       GSList *iter = NULL;
+       iter = g_slist_nth(list->list, 0);
+       while (NULL != iter) {
+               vc_cmd_s *temp_cmd = NULL;
+               temp_cmd = iter->data;
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+               if (false == callback((vc_cmd_h)temp_cmd, user_data))
+                       break;
+
+               iter = g_slist_next(iter);
+       }
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
-       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Foreach commands Done");
 
        return VC_ERROR_NONE;
 }
 
-int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data)
+int vc_cmd_list_filter_by_type(vc_cmd_list_h original, int type, vc_cmd_list_h* filtered)
 {
-       if (NULL == vc_cmd_list) {
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Filter by type");
+
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       if (NULL == original || NULL == filtered) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
+       if (VC_COMMAND_TYPE_NONE >= type || VC_COMMAND_TYPE_EXCLUSIVE < type) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid type");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
        vc_cmd_list_s* list = NULL;
-       list = (vc_cmd_list_s*)vc_cmd_list;
+       list = (vc_cmd_list_s*)original;
 
-       int count = g_slist_length(list->list);
-       int i ;
+       vc_cmd_list_h temp_list;
+       if (0 != vc_cmd_list_create(&temp_list)) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to list create");
+               return VC_ERROR_OPERATION_FAILED;
+       }
 
        GSList *iter = NULL;
-       vc_cmd_s *temp_cmd;
-
        iter = g_slist_nth(list->list, 0);
+       while (NULL != iter) {
+               vc_cmd_s *iter_cmd = NULL;
+               iter_cmd = iter->data;
+               if (NULL == iter_cmd) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
 
-       for (i = 0; i < count; i++) {
-               temp_cmd = iter->data;
+               int iter_type = 0;
+               if (0 != vc_cmd_get_type((vc_cmd_h)iter_cmd, &iter_type)) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command type");
+                       continue;
+               }
 
-               if (NULL != temp_cmd) {
-                       if (false == callback((vc_cmd_h)temp_cmd, user_data)) {
-                               break;
+               if (iter_type == type) {
+                       vc_cmd_h temp_cmd;
+                       if (0 != vc_cmd_create(&temp_cmd)) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to create cmd");
+                               continue;
                        }
 
+                       memcpy(temp_cmd, iter_cmd, sizeof(vc_cmd_s));
+                       if (NULL != iter_cmd->command)
+                               ((vc_cmd_s *)temp_cmd)->command = strdup(iter_cmd->command);
+                       if (NULL != iter_cmd->parameter)
+                               ((vc_cmd_s *)temp_cmd)->parameter = strdup(iter_cmd->parameter);
+
+                       if (0 != vc_cmd_list_add(temp_list, temp_cmd)) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to cmd list add");
+                               vc_cmd_destroy(temp_cmd);
+                               continue;
+                       }
                }
                iter = g_slist_next(iter);
        }
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Foreach commands Done");
+       int count = 0;
+       if (0 != vc_cmd_list_get_count(temp_list, &count)) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get count");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Filtering result : (%d) command", count);
+       }
+
+       *filtered = temp_list;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
 
        return VC_ERROR_NONE;
 }
 
 int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -264,6 +553,13 @@ int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list)
 
 int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -287,6 +583,13 @@ int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list)
 
 int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -296,6 +599,10 @@ int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
        list = (vc_cmd_list_s*)vc_cmd_list;
 
        int count = g_slist_length(list->list);
+       if (0 == count) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
+               return VC_ERROR_EMPTY;
+       }
 
        if (list->index < count - 1) {
                list->index = list->index + 1;
@@ -310,6 +617,13 @@ int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
 
 int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -318,6 +632,11 @@ int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
        vc_cmd_list_s* list = NULL;
        list = (vc_cmd_list_s*)vc_cmd_list;
 
+       if (0 == g_slist_length(list->list)) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
+               return VC_ERROR_EMPTY;
+       }
+
        if (list->index > 0) {
                list->index = list->index - 1;
                SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
@@ -331,6 +650,13 @@ int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
 
 int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_cmd_list || NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
                return VC_ERROR_INVALID_PARAMETER;
@@ -360,8 +686,18 @@ int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command)
 
 int vc_cmd_create(vc_cmd_h* vc_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       CMD_MUTEX_LOCK();
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               CMD_MUTEX_UNLOCK();
                return VC_ERROR_INVALID_PARAMETER;
        }
 
@@ -369,6 +705,7 @@ int vc_cmd_create(vc_cmd_h* vc_command)
 
        if (NULL == command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
+               CMD_MUTEX_UNLOCK();
                return VC_ERROR_OUT_OF_MEMORY;
        }
 
@@ -380,20 +717,38 @@ int vc_cmd_create(vc_cmd_h* vc_command)
        command->command = NULL;
        command->parameter = NULL;
        command->domain = 0;
+       command->priority = 0;
        command->key = VC_KEY_NONE;
        command->modifier = VC_MODIFIER_NONE;
+       command->invocation_name = NULL;
+       command->appid = NULL;
+       command->fixed = NULL;
+       command->coordinates = NULL;
 
        *vc_command = (vc_cmd_h)command;
 
+       g_cmd_list = g_list_append(g_cmd_list, command);
+
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Create command][%p]", *vc_command);
 
+       CMD_MUTEX_UNLOCK();
        return VC_ERROR_NONE;
 }
 
 int vc_cmd_destroy(vc_cmd_h vc_command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       CMD_MUTEX_LOCK();
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               CMD_MUTEX_UNLOCK();
                return VC_ERROR_INVALID_PARAMETER;
        }
 
@@ -402,18 +757,50 @@ int vc_cmd_destroy(vc_cmd_h vc_command)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Destroy command][%p]", command);
 
-       if (NULL != command) {
-               if (NULL != command->command)   free(command->command);
-               if (NULL != command->parameter) free(command->parameter);
-               free(command);
-               command = NULL;
+       GList *iter = NULL;
+       iter = g_list_find(g_cmd_list, command);
+       if (NULL == iter) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "Fail to command destroy : handle is not valid");
+               CMD_MUTEX_UNLOCK();
+               return VC_ERROR_INVALID_PARAMETER;
        }
 
+       g_cmd_list = g_list_delete_link(g_cmd_list, iter);
+
+       if (command->command)
+               free(command->command);
+       command->command = NULL;
+       if (command->parameter)
+               free(command->parameter);
+       command->parameter = NULL;
+       if (command->invocation_name)
+               free(command->invocation_name);
+       command->invocation_name = NULL;
+       if (command->appid)
+               free(command->appid);
+       command->appid = NULL;
+       if (command->fixed)
+               free(command->fixed);
+       command->fixed = NULL;
+       if (command->coordinates)
+               free(command->coordinates);
+       command->coordinates = NULL;
+       free(command);
+       command = NULL;
+
+       CMD_MUTEX_UNLOCK();
        return VC_ERROR_NONE;
 }
 
 int vc_cmd_set_id(vc_cmd_h vc_command, int id)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -422,16 +809,22 @@ int vc_cmd_set_id(vc_cmd_h vc_command, int id)
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd) {
-               cmd->id = id;
-               SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
-       }
+       cmd->id = id;
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
+//LCOV_EXCL_START
 int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command || NULL == id) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -440,41 +833,101 @@ int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd) {
-               *id = cmd->id;
-               SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
-       }
+       *id = cmd->id;
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
+//LCOV_EXCL_STOP
 
-int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
+int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
        if (NULL == vc_command) {
-               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == appid) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, appid is NULL");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd->command) {
-               free(cmd->command);
+       if (cmd->appid)
+               free(cmd->appid);
+       cmd->appid = NULL;
+       cmd->appid = strdup(appid);
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set appid][%p] appid(%s)", vc_command, cmd->appid);
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
        }
 
-       cmd->command = NULL;
+       if (NULL == vc_command || NULL == appid) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       if (cmd->appid)
+               *appid = strdup(gettext(cmd->appid));
+       else
+               *appid = NULL;
 
-       if (NULL != command) {
-               cmd->command = strdup(command);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get appid][%p] appid(%s)", vc_command, *appid);
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       if (NULL == vc_command || NULL == command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
        }
 
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       if (cmd->command)
+               free(cmd->command);
+       cmd->command = NULL;
+       cmd->command = strdup(command);
+
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Set command][%p] Command(%s)", vc_command, cmd->command);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command || NULL == command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -483,18 +936,26 @@ int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd->command) {
+       if (cmd->command)
                *command = strdup(gettext(cmd->command));
-       }
+       else
+               *command = NULL;
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Get command][%p] Command(%s)", vc_command, *command);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
 {
-       if (NULL == vc_command) {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       if (NULL == vc_command || NULL == command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
        }
@@ -502,22 +963,21 @@ int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd->parameter) {
+       if (cmd->parameter)
                free(cmd->parameter);
-       }
-
        cmd->parameter = NULL;
+       cmd->parameter = strdup(command);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set unfixed command][%p] unfixed command(%s)", vc_command, cmd->parameter);
 
-       if (NULL != command) {
-               cmd->parameter = strdup(command);
-               SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] parameter(%s)", vc_command, cmd->parameter);
-       }
-
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
        if (NULL == vc_command || NULL == command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -526,33 +986,161 @@ int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       if (NULL != cmd->parameter) {
+       if (cmd->parameter)
                *command = strdup(gettext(cmd->parameter));
-               SLOG(LOG_DEBUG, TAG_VCCMD, "[Get nonfixed command][%p] nonfixed command(%s)", vc_command, *command);
-       }
+       else
+               *command = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get unfixed command][%p] unfixed command(%s)", vc_command, *command);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
-int vc_cmd_set_type(vc_cmd_h vc_command, int type)
+//LCOV_EXCL_START
+int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
+       if (NULL == fixed) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, fixed is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
-       cmd->type = type;
-
-       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
+       if (cmd->fixed)
+               free(cmd->fixed);
+       cmd->fixed = NULL;
+       cmd->fixed = strdup(fixed);
 
-       return 0;
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] fixed command(%s)", vc_command, cmd->fixed);
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
+       if (NULL == vc_command || NULL == fixed) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       if (cmd->fixed)
+               *fixed = strdup(gettext(cmd->fixed));
+       else
+               *fixed = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get fixed command][%p] fixed command(%s)", vc_command, *fixed);
+
+       return VC_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
+int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation_name)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
+       if (NULL == vc_command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == invocation_name) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, invocation_name is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       if (cmd->invocation_name)
+               free(cmd->invocation_name);
+       cmd->invocation_name = NULL;
+       cmd->invocation_name = strdup(invocation_name);
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set invocation name][%p] invocation_name(%s)", vc_command, cmd->invocation_name);
+       return VC_ERROR_NONE;
+}
+
+//LCOV_EXCL_START
+int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation_name)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
+       if (NULL == vc_command || NULL == invocation_name) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       if (cmd->invocation_name)
+               *invocation_name = strdup(gettext(cmd->invocation_name));
+       else
+               *invocation_name = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get invocation name][%p] invocation_name(%s)", vc_command, *invocation_name);
+       return VC_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
+int vc_cmd_set_type(vc_cmd_h vc_command, int type)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
+       if (NULL == vc_command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (VC_COMMAND_TYPE_NONE >= type || VC_COMMAND_TYPE_EXCLUSIVE < type) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid type(%d)", type);
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       cmd->type = type;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
+
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command || NULL == type) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -565,16 +1153,25 @@ int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Get type][%p] type(%d)", vc_command, *type);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
-int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format)
+int vc_cmd_set_format(vc_cmd_h vc_command, int format)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
+       if (VC_COMMAND_FORMAT_FIXED > format || VC_COMMAND_FORMAT_NONFIXED_AND_FIXED < format) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid format(%d)", format);
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
@@ -582,11 +1179,15 @@ int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Set format][%p] format(%d)", vc_command, format);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
-int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format)
+int vc_cmd_get_format(vc_cmd_h vc_command, int* format)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
        if (NULL == vc_command || NULL == format) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -599,16 +1200,28 @@ int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Get format][%p] format(%d)", vc_command, *format);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_set_pid(vc_cmd_h vc_command, int pid)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
        }
 
+       if (0 > pid) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid pid (%d)", pid);
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
        vc_cmd_s* cmd = NULL;
        cmd = (vc_cmd_s*)vc_command;
 
@@ -616,11 +1229,18 @@ int vc_cmd_set_pid(vc_cmd_h vc_command, int pid)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Set pid][%p] pid(%d)", vc_command, cmd->pid);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command || NULL == pid) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -633,11 +1253,18 @@ int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Get pid][%p] pid(%d)", vc_command, *pid);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_set_domain(vc_cmd_h vc_command, int domain)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -650,11 +1277,18 @@ int vc_cmd_set_domain(vc_cmd_h vc_command, int domain)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Set domain] domain : %d", domain);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
 {
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+       if (0 != __vc_cmd_check_privilege()) {
+               return VC_ERROR_PERMISSION_DENIED;
+       }
+
        if (NULL == vc_command || NULL == domain) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
                return VC_ERROR_INVALID_PARAMETER;
@@ -667,9 +1301,10 @@ int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
 
        SLOG(LOG_DEBUG, TAG_VCCMD, "[Get domain] domain : %d", *domain);
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
+//LCOV_EXCL_START
 /**
 * @brief Sets key value of command.
 *
@@ -685,7 +1320,7 @@ int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
 */
 int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
 {
-       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Set result key");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Set result key");
 
        if (NULL == vc_command) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
@@ -700,10 +1335,9 @@ int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
        cmd->key = key;
        cmd->modifier = modifier;
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
-       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 /**
@@ -721,7 +1355,7 @@ int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
 */
 int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
 {
-       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Get result key");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Get result key");
 
        if (NULL == vc_command || NULL == key || NULL == modifier) {
                SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
@@ -734,10 +1368,9 @@ int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
        *key = cmd->key;
        *modifier = cmd->modifier;
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
-       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
 
-       return 0;
+       return VC_ERROR_NONE;
 }
 
 int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
@@ -749,25 +1382,972 @@ int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
        vc_cmd_list_s* list = NULL;
        list = (vc_cmd_list_s*)vc_cmd_list;
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "=== Command List ===");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@ Command List @");
        SLOG(LOG_DEBUG, TAG_VCCMD, "[List][%p]", list);
 
-       int count = g_slist_length(list->list);
+       int i = 0;
+       GSList *iter = NULL;
+       iter = g_slist_nth(list->list, 0);
+       while (NULL != iter) {
+               vc_cmd_s *cmd = NULL;
+               cmd = iter->data;
+               if (NULL == cmd) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] No command in list");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+               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)",
+                        i++, cmd, cmd->pid, cmd->index, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed);
+
+               iter = g_slist_next(iter);
+       }
 
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json)
+{
+       if (0 != __vc_cmd_get_feature_enabled()) {
+               return VC_ERROR_NOT_SUPPORTED;
+       }
+
+       if (NULL == vc_cmd || NULL == json) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] NULL parameter");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_cmd;
+
+       if (VC_CMD_FORMAT_ACTION != cmd->format) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not Action format");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (0 != vc_info_parser_get_nlu_result(json)) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get nlu result");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_cmd_regex_deinit(int num_regex)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Start Deinitialize regex @@@");
        int i;
-       vc_cmd_s *temp_cmd = NULL;
 
-       for (i = 0; i < count ; i++) {
-               temp_cmd = g_slist_nth_data(list->list, i);
+       for (i = 0; num_regex > i; i++) {
+               regfree(&reg[i]);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
+}
+
+static int __vc_cmd_regex_init()
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Initialize regular expression @@@");
+
+       int cflags = REG_EXTENDED | REG_ICASE;
+       int ret;
+       char errStr[128];
+       char *lang = NULL;
+       int lang_type = 1;
+
+       vc_config_mgr_get_default_language(&lang);
+       if (NULL == lang) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (!strcmp("en_US", lang)) {
+               lang_type = 1;
+       } else if (!strcmp("ko_KR", lang)) {
+               lang_type = 0;
+       } else {
+               free(lang);
+               lang = NULL;
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not supported language type");
+               return VC_ERROR_INVALID_LANGUAGE;
+       }
+
+       free(lang);
+       lang = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ lang type > %d @@@", lang_type);
+
+       re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s" , TIME_ABS1_REGEX[lang_type]);
+       ret = regcomp(&reg[0], TIME_ABS1_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[0], errStr, sizeof(errStr));
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS2_REGEX[lang_type]);
+       ret = regcomp(&reg[1], TIME_ABS2_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[1], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(1);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS3_REGEX[lang_type]);
+       ret = regcomp(&reg[2], TIME_ABS3_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[2], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(2);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL1_REGEX[lang_type]);
+       ret = regcomp(&reg[3], TIME_REL1_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[3], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(3);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL2_REGEX[lang_type]);
+       ret = regcomp(&reg[4], TIME_REL2_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[4], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(4);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL3_REGEX[lang_type]);
+       ret = regcomp(&reg[5], TIME_REL3_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[5], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(5);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_PHR_REGEX[lang_type]);
+       ret = regcomp(&reg[6], TIME_PHR_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[6], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(6);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS1_REGEX[lang_type]);
+       ret = regcomp(&reg[7], DATE_ABS1_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[7], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(7);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS2_REGEX[lang_type]);
+       ret = regcomp(&reg[8], DATE_ABS2_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[8], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(8);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS3_REGEX[lang_type]);
+       ret = regcomp(&reg[9], DATE_ABS3_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[9], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(9);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR1_REGEX[lang_type]);
+       ret = regcomp(&reg[10], DATE_PHR1_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[10], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(10);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR2_REGEX[lang_type]);
+       ret = regcomp(&reg[11], DATE_PHR2_REGEX[lang_type], cflags);
+       if (0 != ret) {
+               regerror(ret, &reg[11], errStr, sizeof(errStr));
+               __vc_cmd_regex_deinit(11);
+
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_cmd_add_year(struct tm *td, int year)
+{
+       td->tm_year += year;
+}
+
+static void __vc_cmd_add_mon(struct tm *td, int mon)
+{
+       int year = 0;
+
+       mon = td->tm_mon + mon;
+       year = mon / 12;
+
+       if (0 < year) {
+               __vc_cmd_add_year(td, year);
+       }
+
+       td->tm_mon = mon % 12;
+}
+
+static void __vc_cmd_add_mday(struct tm *td, int mday)
+{
+       int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
+       int year = td->tm_year + 1900;
+
+       int mon = 0;
+
+       if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) max_day[1] = 29;
+
+       mday = td->tm_mday + mday;
+
+       for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) {
+               mday -= max_day[mon % 12];
+
+               if (11 == mon % 12) {
+                       year++;
+
+                       if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) {
+                               max_day[1] = 29;
+                       } else {
+                               max_day[1] = 28;
+                       }
+               }
+       }
+
+       mon = mon - td->tm_mon;
+
+       if (0 < mon) {
+               __vc_cmd_add_mon(td, mon);
+       }
+
+       td->tm_mday = mday;
+}
+
+static void __vc_cmd_add_hour(struct tm *td, int hour)
+{
+       int day = 0;
+
+       hour = td->tm_hour + hour;
+       day = hour / 24;
+
+       if (0 < day) {
+               __vc_cmd_add_mday(td, day);
+       }
+
+       td->tm_hour = hour % 24;
+}
+
+static void __vc_cmd_add_min(struct tm *td, int min)
+{
+       int hour = 0;
+
+       min = td->tm_min + min;
+       hour = min / 60;
+
+       if (0 < hour) {
+               __vc_cmd_add_hour(td, hour);
+       }
+
+       td->tm_min = min % 60;
+}
+
+static void __copy_struct_tm(struct tm *des, struct tm *src)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Start to copy struct tm @@@");
+
+       des->tm_sec     = src->tm_sec;
+       des->tm_min     = src->tm_min;
+       des->tm_hour    = src->tm_hour;
+       des->tm_mday    = src->tm_mday;
+       des->tm_mon     = src->tm_mon;
+       des->tm_year    = src->tm_year;
+       des->tm_wday    = src->tm_wday;
+       des->tm_yday    = src->tm_yday;
+       des->tm_isdst   = src->tm_isdst;
+
+       des->tm_gmtoff  = src->tm_gmtoff;
+       des->tm_zone    = src->tm_zone;
+}
+
+static void __update_data_sidx(int idx)
+{
+       if (0 > g_data_sidx || idx < g_data_sidx) g_data_sidx = idx;
+}
+
+static void __update_data_eidx(int idx)
+{
+       if (0 > g_data_eidx || idx > g_data_eidx) g_data_eidx = idx;
+}
+
+static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist)
+{
+       regmatch_t pmatch[3];
+       int ret;
+       int len;
+       int idx;
+
+       *exist = 0;
+       ret = regexec(&reg[6], str, 3, pmatch, 0);
+       if (0 == ret) {
+               idx = 1;
+               len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
+               if (0 < len) {
+                       if (12 < td->tm_hour) {
+                               __vc_cmd_add_mday(td, 1);
+                       }
+
+                       td->tm_hour = 12;
+               } else {
+                       idx = 2;
+                       len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
+
+                       __vc_cmd_add_mday(td, 1);
+               }
+
+               td->tm_min = 0;
+               td->tm_sec = 0;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               __update_data_sidx(pmatch[0].rm_so);
+               __update_data_eidx(pmatch[0].rm_eo);
+
+               *exist = 1;
+               return VC_ERROR_NONE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist)
+{
+       regmatch_t pmatch[2];
+       int ret;
+       int len;
+       int sidx = -1;
+       int eidx = -1;
+       int hour = -1;
+       int min = -1;
+
+       *exist = 0;
+       ret = regexec(&reg[3], str, 1, pmatch, 0);
+       if (0 == ret) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so);
+               hour = min = -1;
+
+               sidx = pmatch[0].rm_so;
+               eidx = pmatch[0].rm_eo;
+
+               ret = regexec(&reg[4], str, 2, pmatch, 0);
+               if (0 == ret) {
+                       len = pmatch[1].rm_eo - pmatch[1].rm_so;
+
+                       if (0 > len) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
+                               return VC_ERROR_OPERATION_FAILED;
+                       }
+                       char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
+
+                       if (NULL == tempstr) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                               return VC_ERROR_OUT_OF_MEMORY;
+                       }
+
+                       hour = atoi(tempstr);
+
+                       free(tempstr);
+                       tempstr = NULL;
+
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+                       if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+                       if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+               }
+
+               ret = regexec(&reg[5], str, 2, pmatch, 0);
+               if (0 == ret) {
+                       len = pmatch[1].rm_eo - pmatch[1].rm_so;
+
+                       if (0 > len) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
+                               return VC_ERROR_OPERATION_FAILED;
+                       }
+                       char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
+
+                       if (NULL == tempstr) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                               return VC_ERROR_OUT_OF_MEMORY;
+                       }
+
+                       min = atoi(tempstr);
+
+                       free(tempstr);
+                       tempstr = NULL;
+
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+                       if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+                       if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+               }
+
+               if (hour < 0 && min < 0) {
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
+                       return VC_ERROR_NONE;
+               }
+
+               hour = 0 > hour ? 0 : hour;
+               min = 0 > min ? 0 : min;
+
+               min = min + (hour * 60);
+
+               __vc_cmd_add_min(td, min);
+               td->tm_sec = 0;
+
+               __update_data_sidx(sidx);
+               __update_data_eidx(eidx);
+
+               *exist = 1;
+               return VC_ERROR_NONE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist)
+{
+       regmatch_t pmatch[5];
+       int ret;
+       int len;
+       int idx;
+       int flag = -1;
+       int hour = -1;
+       int min = -1;
+       int sidx = -1;
+       int eidx = -1;
+
+       *exist = 0;
+       ret = regexec(&reg[0], str, 5, pmatch, 0);
+       if (0 == ret) {
+               for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
+
+               flag = idx & 1;
+
+               sidx = pmatch[0].rm_so;
+               eidx = pmatch[0].rm_eo;
+       }
+
+       ret = regexec(&reg[1], str, 2, pmatch, 0);
+       if (0 == ret) {
+               len = pmatch[1].rm_eo - pmatch[1].rm_so;
+
+               if (0 > len) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+               char *tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
+
+               if (NULL == tempstr) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                       return VC_ERROR_OUT_OF_MEMORY;
+               }
+
+               hour = atoi(tempstr);
+
+               if (0 <= flag) {
+                       hour = hour + 12 * flag;
+
+                       if (12 == hour) hour = 0;
+                       else if (24 == hour) hour = 12;
+               }
+
+               if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) {
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+                       free(tempstr);
+                       tempstr = NULL;
+                       return VC_ERROR_NONE;
+               }
+
+               free(tempstr);
+               tempstr = NULL;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+               if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+       } else if (0 < flag) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+               return VC_ERROR_NONE;
+       }
+
+       ret = regexec(&reg[2], str, 2, pmatch, 0);
+       if (0 == ret) {
+               idx = 1;
+               len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
+               if (0 < len) {
+                       char *tempstr = strndup(str + pmatch[idx].rm_so, (size_t)len);
+
+                       if (NULL == tempstr) {
+                               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                               return VC_ERROR_OUT_OF_MEMORY;
+                       }
+
+                       min = atoi(tempstr);
+
+                       if (0 > min || 60 <= min) {
+                               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+                               free(tempstr);
+                               tempstr = NULL;
+                               return VC_ERROR_NONE;
+                       }
+
+                       td->tm_sec = 0;
+
+                       free(tempstr);
+                       tempstr = NULL;
+               } else {
+                       idx = 0;
+                       min = 30;
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so);
+               if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+               if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+       }
+
+       if (0 > hour && 0 > min) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
+               return VC_ERROR_NONE;
+       }
+
+       if (0 <= min && 0 <= hour) {
+               if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1);
+
+               td->tm_hour = hour;
+               td->tm_min = min;
+       } else if (0 <= min) {
+               char *lang = NULL;
+               vc_config_mgr_get_default_language(&lang);
+               if (NULL == lang) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+
+               if (!strcmp("en_US", lang)) {
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+                       free(lang);
+                       lang = NULL;
+                       return VC_ERROR_NONE;
+               }
+               if (min <= td->tm_min) __vc_cmd_add_hour(td, 1);
+
+               td->tm_min = min;
+
+               free(lang);
+               lang = NULL;
+       } else {
+               if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1);
+
+               td->tm_hour = hour;
+               td->tm_min = 0;
+       }
+
+       td->tm_sec = 0;
+
+       __update_data_sidx(sidx);
+       __update_data_eidx(eidx);
+
+       *exist = 1;
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist)
+{
+       regmatch_t pmatch[10];
+       int ret;
+       int len;
+       int idx;
+
+       *exist = 0;
+       ret = regexec(&reg[10], str, 5, pmatch, 0);
+       if (0 == ret) {
+               for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++);
+
+               len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
+
+               td->tm_year = td_now.tm_year;
+               td->tm_mon = td_now.tm_mon;
+               td->tm_mday = td_now.tm_mday;
+
+               __vc_cmd_add_mday(td, idx - 1);
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               __update_data_sidx(pmatch[0].rm_so);
+               __update_data_eidx(pmatch[0].rm_eo);
+
+               *exist = 1;
+               return VC_ERROR_NONE;
+       }
+
+       ret = regexec(&reg[11], str, 10, pmatch, 0);
+       if (0 == ret) {
+               for (idx = 1; 10 > idx; idx++) {
+                       len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
 
-               if (NULL != temp_cmd) {
-                       SLOG(LOG_DEBUG, TAG_VCCMD, "  [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Domain(%d) Command(%s) Param(%s)",
-                                i, temp_cmd, temp_cmd->pid, temp_cmd->index, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter);
+                       if (0 < len) break;
                }
+
+               td->tm_year = td_now.tm_year;
+               td->tm_mon = td_now.tm_mon;
+               td->tm_mday = td_now.tm_mday;
+
+               __vc_cmd_add_mday(td, idx + 1);
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               __update_data_sidx(pmatch[0].rm_so);
+               __update_data_eidx(pmatch[0].rm_eo);
+
+               *exist = 1;
+               return VC_ERROR_NONE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string");
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist)
+{
+       regmatch_t pmatch[13];
+       int ret;
+       int len;
+       int idx;
+       int sidx = -1;
+       int eidx = -1;
+       int y_flag = 0;
+       int m_flag = 0;
+       int year = 0;
+       int mon = 0;
+       int day = 0;
+       char *tempstr = NULL;
+
+       *exist = 0;
+       ret = regexec(&reg[9], str, 2, pmatch, 0);
+       if (0 == ret) {
+               len = pmatch[1].rm_eo - pmatch[1].rm_so;
+
+               if (0 > len) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+               tempstr = strndup(str + pmatch[1].rm_so, (size_t)len);
+
+               if (NULL == tempstr) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                       return VC_ERROR_OUT_OF_MEMORY;
+               }
+
+               day = atoi(tempstr);
+
+               free(tempstr);
+               tempstr = NULL;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               sidx = pmatch[0].rm_so;
+               eidx = pmatch[0].rm_eo;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+               return VC_ERROR_NONE;
+       }
+
+       ret = regexec(&reg[8], str, 13, pmatch, 0);
+       if (0 == ret) {
+               for (idx = 1; 13 > idx; idx++) {
+                       len = pmatch[idx].rm_eo - pmatch[idx].rm_so;
+
+                       if (0 < len) {
+                               mon = idx - 1;
+                               break;
+                       }
+               }
+
+               m_flag = 1;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+               if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+       } else {
+               char *lang = NULL;
+               vc_config_mgr_get_default_language(&lang);
+               if (NULL == lang) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+
+               if (!strcmp("en_US", lang)) {
+                       SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+                       free(lang);
+                       lang = NULL;
+                       return VC_ERROR_NONE;
+               }
+
+               free(lang);
+               lang = NULL;
+
+               mon = td->tm_mon;
+       }
+
+       ret = regexec(&reg[7], str, 3, pmatch, 0);
+       if (0 == ret) {
+               if (!m_flag) return -1;
+
+               len = pmatch[2].rm_eo - pmatch[2].rm_so;
+
+               if (0 > len) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid string length");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+               tempstr = strndup(str + pmatch[2].rm_so, (size_t)len);
+
+               if (NULL == tempstr) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed");
+                       return VC_ERROR_OUT_OF_MEMORY;
+               }
+
+               year = atoi(tempstr);
+               year = 1900 < year ? year - 1900 : year + 100;
+
+               free(tempstr);
+               tempstr = NULL;
+
+               y_flag = 1;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so);
+
+               if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so;
+               if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo;
+       } else {
+               year = td->tm_year;
+       }
+
+       if (0 > g_time_flag) {
+               td->tm_hour = 0;
+               td->tm_min = 0;
+               td->tm_sec = 0;
+       } else if (2 == g_time_flag) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+               return VC_ERROR_NONE;
+       }
+
+       int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31};
+       if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29;
+
+       if (max_day[mon] < day || 1 > day) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incoming sentence is weird");
+               return VC_ERROR_NONE;
+       }
+
+       td->tm_year = year;
+       td->tm_mon = mon;
+       td->tm_mday = day;
+
+       if (!y_flag) {
+               if (!m_flag) {
+                       if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1);
+               } else {
+                       if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1);
+                       else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1);
+               }
+       }
+
+       __update_data_sidx(sidx);
+       __update_data_eidx(eidx);
+
+       *exist = 1;
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_time_check(const char *str, struct tm *td)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check time value in string \"%s\"", str);
+
+       vc_error_e ret;
+       int exist = 0;
+
+       ret = __vc_cmd_tphrase_check(str, td, &exist);
+       if (1 == exist) {
+               g_time_flag = 1;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
+               return ret;
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
+               return ret;
+       }
+
+       ret = __vc_cmd_trelative_check(str, td, &exist);
+       if (1 == exist) {
+               g_time_flag = 2;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
+               return ret;
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
+               return ret;
+       }
+
+       ret = __vc_cmd_tabsolute_check(str, td, &exist);
+       if (1 == exist) {
+               g_time_flag = 3;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Time value is exist");
+               return ret;
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
+               return ret;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no time value");
+       return VC_ERROR_NONE;
+}
+
+static int __vc_cmd_date_check(const char *str, struct tm *td)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Check date value in string \"%s\"", str);
+
+       vc_error_e ret;
+       int exist = 0;
+
+       ret = __vc_cmd_dphrase_check(str, td, &exist);
+       if (1 == exist) {
+               g_date_flag = 1;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
+               return ret;
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
+               return ret;
+       }
+
+       ret = __vc_cmd_dabsolute_check(str, td, &exist);
+       if (1 == exist) {
+               g_date_flag = 1;
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Date value is exist");
+               return ret;
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred > (%d)", ret);
+               return ret;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ There is no date value");
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_get_datetime(const char *text, time_t *result, char **remain)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@ Get timestamp data");
+
+       struct tm td;
+       const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+       vc_error_e ret;
+
+       if (NULL == text || NULL == result || NULL == remain) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       *result = -1;
+       ret = __vc_cmd_regex_init();
+       if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed");
+               return ret;
+       }
+
+       g_data_sidx = g_data_eidx = -1;
+
+       t_now = time(NULL);
+       localtime_r(&t_now, &td_now);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now);
+
+       __copy_struct_tm(&td, &td_now);
+       SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
+               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);
+
+       g_time_flag = g_date_flag = -1;
+
+       ret = __vc_cmd_time_check(text, &td);
+       if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
+               return ret;
+       }
+
+       ret = __vc_cmd_date_check(text, &td);
+       if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occurred in the check > (%d)", ret);
+               return ret;
+       }
+
+       __vc_cmd_regex_deinit(12);
+
+       if (g_time_flag > 0 || g_date_flag > 0) {
+               *result = mktime(&td);
+
+               SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %ld", *result);
+               SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s),  %d:%d:%d",
+                       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);
+
+               *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx));
+
+               if (NULL == *remain) {
+                       SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error");
+                       return VC_ERROR_OUT_OF_MEMORY;
+               }
+
+               strncpy(*remain, text, g_data_sidx);
+               strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text");
        }
 
-       SLOG(LOG_DEBUG, TAG_VCCMD, "==================");
-       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+       SLOG(LOG_DEBUG, TAG_VCCMD, "@@@");
 
-       return 0;
+       return VC_ERROR_NONE;
 }
+//LCOV_EXCL_STOP